From d6181b5810c43306f4897237162410fa1c2ada02 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 05 2019 19:04:06 +0000 Subject: import sssd-2.2.0-19.el8 --- diff --git a/.gitignore b/.gitignore index b147e6a..bffaf09 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/sssd-2.0.0.tar.gz +SOURCES/sssd-2.2.0.tar.gz diff --git a/.sssd.metadata b/.sssd.metadata index 7f62e35..637397e 100644 --- a/.sssd.metadata +++ b/.sssd.metadata @@ -1 +1 @@ -700ff5391bea73c19ddcdf99b25615fd4d284d7b SOURCES/sssd-2.0.0.tar.gz +6c4ba24eb19a821c69e19675e76f01c94cbd5aa0 SOURCES/sssd-2.2.0.tar.gz diff --git a/SOURCES/0001-KCM-Don-t-error-out-if-creating-a-new-ID-as-the-firs.patch b/SOURCES/0001-KCM-Don-t-error-out-if-creating-a-new-ID-as-the-firs.patch deleted file mode 100644 index c6c7fa1..0000000 --- a/SOURCES/0001-KCM-Don-t-error-out-if-creating-a-new-ID-as-the-firs.patch +++ /dev/null @@ -1,41 +0,0 @@ -From a53590ef89d78d3e065e0f1eb28b641c391b5a18 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 28 Aug 2018 14:47:44 +0200 -Subject: [PATCH] KCM: Don't error out if creating a new ID as the first step -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We need to handle the case where the nextID operation is ran, but the -secdb is totally empty, otherwise logins with sssd's krb5_child would -fail. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3815 - -Reviewed-by: Michal Židek - -DOWNSTREAM: Resolves: rhbz#1622026 - sssd 2.0 regression: Kerberos authentication fails with the KCM ccache ---- - src/responder/kcm/kcmsrv_ccache_secdb.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c -index 0f1c037caf8c3bda6f3dca7136ed9236862ccdd7..a61d7b15be433e8308acc3dfa35d730247e2e615 100644 ---- a/src/responder/kcm/kcmsrv_ccache_secdb.c -+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c -@@ -595,7 +595,10 @@ static struct tevent_req *ccdb_secdb_nextid_send(TALLOC_CTX *mem_ctx, - } - - ret = sss_sec_list(state, sreq, &keys, &nkeys); -- if (ret != EOK) { -+ if (ret == ENOENT) { -+ keys = NULL; -+ nkeys = 0; -+ } else if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Cannot list keys [%d]: %s\n", - ret, sss_strerror(ret)); --- -2.14.4 - diff --git a/SOURCES/0001-MAN-ldap_user_home_directory-default-missing.patch b/SOURCES/0001-MAN-ldap_user_home_directory-default-missing.patch new file mode 100644 index 0000000..e0de1f3 --- /dev/null +++ b/SOURCES/0001-MAN-ldap_user_home_directory-default-missing.patch @@ -0,0 +1,36 @@ +From 52cdf289ff9b40a203d7f823b8dad85501c7404c Mon Sep 17 00:00:00 2001 +From: Tomas Halman +Date: Wed, 19 Jun 2019 10:15:30 +0200 +Subject: [PATCH 1/2] MAN: ldap_user_home_directory default missing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The default value of "ldap_user_home_directory" is "homeDirectory" +but for AD provider it is "unixHomeDirectory" + +Resolves: +https://bugzilla.redhat.com/show_bug.cgi?id=1673443 + +Reviewed-by: Michal Židek +(cherry picked from commit 01ea70fa8cc91f05a726d1dea3c64bd776dc3517) +--- + src/man/sssd-ldap.5.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml +index b6496b50f..f0bc82db5 100644 +--- a/src/man/sssd-ldap.5.xml ++++ b/src/man/sssd-ldap.5.xml +@@ -373,7 +373,7 @@ + home directory. + + +- Default: homeDirectory ++ Default: homeDirectory (LDAP and IPA), unixHomeDirectory (AD) + + + +-- +2.20.1 + diff --git a/SOURCES/0002-PROXY-Return-data-in-output-parameter-if-everything-.patch b/SOURCES/0002-PROXY-Return-data-in-output-parameter-if-everything-.patch new file mode 100644 index 0000000..0879227 --- /dev/null +++ b/SOURCES/0002-PROXY-Return-data-in-output-parameter-if-everything-.patch @@ -0,0 +1,135 @@ +From 59c0d659fc71b47278c2faadaa844e8516454626 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Fri, 28 Jun 2019 16:27:21 +0200 +Subject: [PATCH 2/2] PROXY: Return data in output parameter if everything is + OK + +The function remove_duplicate_group_members might return EOK also in the middle +of function but return parameter was not set with right data. +Processing continued in the function save_group but there was a +dereference of NULL pointer. + +Introduced in: https://pagure.io/SSSD/sssd/issue/3931 + +Crash: + (gdb) bt + #0 0x00007fb4ce4a9ac5 in save_group (sysdb=sysdb@entry=0x55c9a0efb230, dom=dom@entry=0x55c9a0efb420, grp=grp@entry=0x55c9a0f370f0, real_name=0x55c9a0f47340 "nobody@ldap", + alias=alias@entry=0x0) at src/providers/proxy/proxy_id.c:748 + #1 0x00007fb4ce4aa600 in get_gr_gid (mem_ctx=mem_ctx@entry=0x55c9a0f38be0, sysdb=sysdb@entry=0x55c9a0efb230, dom=dom@entry=0x55c9a0efb420, gid=99, now=, + ctx=) at src/providers/proxy/proxy_id.c:1160 + #2 0x00007fb4ce4ac9e5 in get_initgr_groups_process (pwd=0x55c9a0f384a0, pwd=0x55c9a0f384a0, dom=0x55c9a0efb420, sysdb=0x55c9a0efb230, ctx=0x55c9a0f048e0, memctx=0x55c9a0f38be0) + at src/providers/proxy/proxy_id.c:1553 + #3 get_initgr (i_name=, dom=0x55c9a0efb420, sysdb=, ctx=0x55c9a0f048e0, mem_ctx=0x55c9a0f38b70) at src/providers/proxy/proxy_id.c:1461 + #4 proxy_account_info (domain=0x55c9a0efb420, be_ctx=, data=, ctx=0x55c9a0f048e0, mem_ctx=0x55c9a0f38b70) at src/providers/proxy/proxy_id.c:1659 + #5 proxy_account_info_handler_send (mem_ctx=, id_ctx=0x55c9a0f048e0, data=, params=0x55c9a0f39790) at src/providers/proxy/proxy_id.c:1758 + #6 0x000055c99fc67677 in file_dp_request (_dp_req=, req=0x55c9a0f39470, request_data=, dp_flags=1, method=DPM_ACCOUNT_HANDLER, target=DPT_ID, + name=, domainname=0x55c9a0f39190 "LDAP", provider=0x55c9a0efe0e0, mem_ctx=) at src/providers/data_provider/dp_request.c:250 + #7 dp_req_send (mem_ctx=0x55c9a0f37b60, provider=provider@entry=0x55c9a0efe0e0, domain=domain@entry=0x55c9a0f39190 "LDAP", name=, target=target@entry=DPT_ID, + method=method@entry=DPM_ACCOUNT_HANDLER, dp_flags=dp_flags@entry=1, request_data=0x55c9a0f37c00, _request_name=0x55c9a0f37b60) at src/providers/data_provider/dp_request.c:295 + #8 0x000055c99fc6a132 in dp_get_account_info_send (mem_ctx=, ev=0x55c9a0eddbc0, sbus_req=, provider=0x55c9a0efe0e0, dp_flags=1, + entry_type=, filter=0x55c9a0f358d0 "name=nobody@ldap", domain=0x55c9a0f39190 "LDAP", extra=0x55c9a0f354a0 "") at src/providers/data_provider/dp_target_id.c:528 + #9 0x00007fb4da35265b in _sbus_sss_invoke_in_uusss_out_qus_step (ev=0x55c9a0eddbc0, te=, tv=..., private_data=) at src/sss_iface/sbus_sss_invokers.c:2847 + #10 0x00007fb4d9cfb1cf in tevent_common_invoke_timer_handler () from /lib64/libtevent.so.0 + #11 0x00007fb4d9cfb339 in tevent_common_loop_timer_delay () from /lib64/libtevent.so.0 + #12 0x00007fb4d9cfc2f9 in epoll_event_loop_once () from /lib64/libtevent.so.0 + #13 0x00007fb4d9cfa7b7 in std_event_loop_once () from /lib64/libtevent.so.0 + #14 0x00007fb4d9cf5b5d in _tevent_loop_once () from /lib64/libtevent.so.0 + #15 0x00007fb4d9cf5d8b in tevent_common_loop_wait () from /lib64/libtevent.so.0 + #16 0x00007fb4d9cfa757 in std_event_loop_wait () from /lib64/libtevent.so.0 + #17 0x00007fb4dd955ac3 in server_loop (main_ctx=0x55c9a0edf090) at src/util/server.c:724 + #18 0x000055c99fc59760 in main (argc=8, argv=) at src/providers/data_provider_be.c:747 + (gdb) l + (gdb) bt + #0 0x00007fb4ce4a9ac5 in save_group (sysdb=sysdb@entry=0x55c9a0efb230, dom=dom@entry=0x55c9a0efb420, grp=grp@entry=0x55c9a0f370f0, real_name=0x55c9a0f47340 "nobody@ldap", + alias=alias@entry=0x0) at src/providers/proxy/proxy_id.c:748 + #1 0x00007fb4ce4aa600 in get_gr_gid (mem_ctx=mem_ctx@entry=0x55c9a0f38be0, sysdb=sysdb@entry=0x55c9a0efb230, dom=dom@entry=0x55c9a0efb420, gid=99, now=, + ctx=) at src/providers/proxy/proxy_id.c:1160 + #2 0x00007fb4ce4ac9e5 in get_initgr_groups_process (pwd=0x55c9a0f384a0, pwd=0x55c9a0f384a0, dom=0x55c9a0efb420, sysdb=0x55c9a0efb230, ctx=0x55c9a0f048e0, memctx=0x55c9a0f38be0) + at src/providers/proxy/proxy_id.c:1553 + #3 get_initgr (i_name=, dom=0x55c9a0efb420, sysdb=, ctx=0x55c9a0f048e0, mem_ctx=0x55c9a0f38b70) at src/providers/proxy/proxy_id.c:1461 + #4 proxy_account_info (domain=0x55c9a0efb420, be_ctx=, data=, ctx=0x55c9a0f048e0, mem_ctx=0x55c9a0f38b70) at src/providers/proxy/proxy_id.c:1659 + #5 proxy_account_info_handler_send (mem_ctx=, id_ctx=0x55c9a0f048e0, data=, params=0x55c9a0f39790) at src/providers/proxy/proxy_id.c:1758 + #6 0x000055c99fc67677 in file_dp_request (_dp_req=, req=0x55c9a0f39470, request_data=, dp_flags=1, method=DPM_ACCOUNT_HANDLER, target=DPT_ID, + name=, domainname=0x55c9a0f39190 "LDAP", provider=0x55c9a0efe0e0, mem_ctx=) at src/providers/data_provider/dp_request.c:250 + #7 dp_req_send (mem_ctx=0x55c9a0f37b60, provider=provider@entry=0x55c9a0efe0e0, domain=domain@entry=0x55c9a0f39190 "LDAP", name=, target=target@entry=DPT_ID, + method=method@entry=DPM_ACCOUNT_HANDLER, dp_flags=dp_flags@entry=1, request_data=0x55c9a0f37c00, _request_name=0x55c9a0f37b60) at src/providers/data_provider/dp_request.c:295 + #8 0x000055c99fc6a132 in dp_get_account_info_send (mem_ctx=, ev=0x55c9a0eddbc0, sbus_req=, provider=0x55c9a0efe0e0, dp_flags=1, + entry_type=, filter=0x55c9a0f358d0 "name=nobody@ldap", domain=0x55c9a0f39190 "LDAP", extra=0x55c9a0f354a0 "") at src/providers/data_provider/dp_target_id.c:528 + #9 0x00007fb4da35265b in _sbus_sss_invoke_in_uusss_out_qus_step (ev=0x55c9a0eddbc0, te=, tv=..., private_data=) at src/sss_iface/sbus_sss_invokers.c:2847 + #10 0x00007fb4d9cfb1cf in tevent_common_invoke_timer_handler () from /lib64/libtevent.so.0 + #11 0x00007fb4d9cfb339 in tevent_common_loop_timer_delay () from /lib64/libtevent.so.0 + #12 0x00007fb4d9cfc2f9 in epoll_event_loop_once () from /lib64/libtevent.so.0 + #13 0x00007fb4d9cfa7b7 in std_event_loop_once () from /lib64/libtevent.so.0 + #14 0x00007fb4d9cf5b5d in _tevent_loop_once () from /lib64/libtevent.so.0 + #15 0x00007fb4d9cf5d8b in tevent_common_loop_wait () from /lib64/libtevent.so.0 + #16 0x00007fb4d9cfa757 in std_event_loop_wait () from /lib64/libtevent.so.0 + #17 0x00007fb4dd955ac3 in server_loop (main_ctx=0x55c9a0edf090) at src/util/server.c:724 + #18 0x000055c99fc59760 in main (argc=8, argv=) at src/providers/data_provider_be.c:747 + (gdb) l + 733 ret = remove_duplicate_group_members(tmp_ctx, grp, &ngroup); + 734 if (ret != EOK) { + 735 DEBUG(SSSDBG_CRIT_FAILURE, "Failed to remove duplicate group member s\n"); + 736 goto done; + 737 } + 738 + 739 DEBUG_GR_MEM(SSSDBG_TRACE_LIBS, ngroup); + 740 + 741 ret = sysdb_transaction_start(sysdb); + 742 if (ret != EOK) { + 743 DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); + 744 goto done; + 745 } + 746 in_transaction = true; + 747 + 748 if (ngroup->gr_mem && ngroup->gr_mem[0]) { + 749 attrs = sysdb_new_attrs(tmp_ctx); + 750 if (!attrs) { + 751 DEBUG(SSSDBG_CRIT_FAILURE, "Allocation error?!\n"); + 752 ret = ENOMEM; + (gdb) p ngroup + $1 = (struct group *) 0x0 + 743 DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n"); + 744 goto done; + 745 } + 746 in_transaction = true; + 747 + 748 if (ngroup->gr_mem && ngroup->gr_mem[0]) { + 749 attrs = sysdb_new_attrs(tmp_ctx); + 750 if (!attrs) { + 751 DEBUG(SSSDBG_CRIT_FAILURE, "Allocation error?!\n"); + 752 ret = ENOMEM; + (gdb) p ngroup + $1 = (struct group *) 0x0 + +Merges: https://pagure.io/SSSD/sssd/pull-request/4036 + +Resolves: +https://pagure.io/SSSD/sssd/issue/4037 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit e1b678c0cce73494d986610920b03956c1dbb62a) +--- + src/providers/proxy/proxy_id.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c +index e1be29076..91105ce5a 100644 +--- a/src/providers/proxy/proxy_id.c ++++ b/src/providers/proxy/proxy_id.c +@@ -698,10 +698,12 @@ static errno_t remove_duplicate_group_members(TALLOC_CTX *mem_ctx, + } + grp->gr_mem[i] = NULL; + +- *_grp = talloc_steal(mem_ctx, grp); + ret = EOK; + + done: ++ if (ret == EOK) { ++ *_grp = talloc_steal(mem_ctx, grp); ++ } + talloc_zfree(tmp_ctx); + + return ret; +-- +2.20.1 + diff --git a/SOURCES/0002-sbus-register-filter-on-new-connection.patch b/SOURCES/0002-sbus-register-filter-on-new-connection.patch deleted file mode 100644 index 69e00c2..0000000 --- a/SOURCES/0002-sbus-register-filter-on-new-connection.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 929a2b84cbb63312c2d797ab7048003c6f5e0c71 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Wed, 5 Sep 2018 15:08:52 +0200 -Subject: [PATCH] sbus: register filter on new connection - -The filter is not again registered on new connection when the old connection -was lost. This caused a segfault when the router is destroyed during shutdown. - -It also would not allow to recieve and process any messages as the filter -function is needed for that. However, this was not very visible with -current sssd architecture. - -Steps to reproduce: -1. Run SSSD -2. pkill sssd_be -3. Wait for responders to reconnect to backend -4. Shutdown SSSD -5. It will crash without this patch - -Resolves: -https://pagure.io/SSSD/sssd/issue/3821 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 55d5b43543b5ef62322fe635fe8108410cb4ea77) ---- - src/sbus/router/sbus_router.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/sbus/router/sbus_router.c b/src/sbus/router/sbus_router.c -index 24c2c76475c130343eb4319a76dfa91f40d2958d..d31cef1b4c253b927b1b8e1c3d7daef14eb26dd6 100644 ---- a/src/sbus/router/sbus_router.c -+++ b/src/sbus/router/sbus_router.c -@@ -364,6 +364,13 @@ errno_t - sbus_router_reset(struct sbus_connection *conn) - { - errno_t ret; -+ bool bret; -+ -+ bret = sbus_router_filter_add(conn->router); -+ if (!bret) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to register message filter!\n"); -+ return EFAULT; -+ } - - ret = sbus_router_reset_listeners(conn); - if (ret != EOK) { --- -2.14.4 diff --git a/SOURCES/0003-LDAP-failover-does-not-work-on-non-responsive-ldaps.patch b/SOURCES/0003-LDAP-failover-does-not-work-on-non-responsive-ldaps.patch new file mode 100644 index 0000000..1053167 --- /dev/null +++ b/SOURCES/0003-LDAP-failover-does-not-work-on-non-responsive-ldaps.patch @@ -0,0 +1,80 @@ +From 5afd3f6030a78d1c3631c645955c0804b7e7abce Mon Sep 17 00:00:00 2001 +From: Tomas Halman +Date: Mon, 24 Jun 2019 15:58:09 +0200 +Subject: [PATCH 3/4] LDAP: failover does not work on non-responsive ldaps + +In case ldaps:// is used, then establishing the secure socket is +a sychronous operation. If there's nothing on the other end, then +the process would be stuck waiting in for the crypto library +to finish. + +Here we set socket read/write timeout so the operation can finish +in reasonable time with an error. The ldap_network_timeout +option is used for this timeout. + +Resolves: +https://pagure.io/SSSD/sssd/issue/2878 + +Reviewed-by: Alexey Tikhonov +Reviewed-by: Jakub Hrozek +--- + src/util/sss_sockets.c | 26 ++++++++++++++++++++++++-- + 1 file changed, 24 insertions(+), 2 deletions(-) + +diff --git a/src/util/sss_sockets.c b/src/util/sss_sockets.c +index 5e9be9ebd..0e4d8df8a 100644 +--- a/src/util/sss_sockets.c ++++ b/src/util/sss_sockets.c +@@ -74,10 +74,11 @@ static errno_t set_fcntl_flags(int fd, int fd_flags, int fl_flags) + return EOK; + } + +-static errno_t set_fd_common_opts(int fd) ++static errno_t set_fd_common_opts(int fd, int timeout) + { + int dummy = 1; + int ret; ++ struct timeval tv; + + /* SO_KEEPALIVE and TCP_NODELAY are set by OpenLDAP client libraries but + * failures are ignored.*/ +@@ -97,6 +98,27 @@ static errno_t set_fd_common_opts(int fd) + strerror(ret)); + } + ++ if (timeout > 0) { ++ /* Set socket read & write timeout */ ++ tv = tevent_timeval_set(timeout, 0); ++ ++ ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); ++ if (ret != 0) { ++ ret = errno; ++ DEBUG(SSSDBG_FUNC_DATA, ++ "setsockopt SO_RCVTIMEO failed.[%d][%s].\n", ret, ++ strerror(ret)); ++ } ++ ++ ret = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); ++ if (ret != 0) { ++ ret = errno; ++ DEBUG(SSSDBG_FUNC_DATA, ++ "setsockopt SO_SNDTIMEO failed.[%d][%s].\n", ret, ++ strerror(ret)); ++ } ++ } ++ + return EOK; + } + +@@ -264,7 +286,7 @@ struct tevent_req *sssd_async_socket_init_send(TALLOC_CTX *mem_ctx, + goto fail; + } + +- ret = set_fd_common_opts(state->sd); ++ ret = set_fd_common_opts(state->sd, timeout); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "set_fd_common_opts failed.\n"); + goto fail; +-- +2.20.1 + diff --git a/SOURCES/0003-sysdb-extract-sysdb_ldb_msg_attr_to_certmap_info-cal.patch b/SOURCES/0003-sysdb-extract-sysdb_ldb_msg_attr_to_certmap_info-cal.patch deleted file mode 100644 index 4ed5198..0000000 --- a/SOURCES/0003-sysdb-extract-sysdb_ldb_msg_attr_to_certmap_info-cal.patch +++ /dev/null @@ -1,260 +0,0 @@ -From d5b15619809b169dca96af648c24f927e85d0e4b Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 29 Jun 2018 17:49:50 +0200 -Subject: [PATCH 03/19] sysdb: extract sysdb_ldb_msg_attr_to_certmap_info() - call - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 7c619ae08f05a7595d15cf11b64461a7d19cfaa7) ---- - src/db/sysdb.h | 4 ++ - src/db/sysdb_certmap.c | 191 ++++++++++++++++++++++++++++--------------------- - 2 files changed, 112 insertions(+), 83 deletions(-) - -diff --git a/src/db/sysdb.h b/src/db/sysdb.h -index d72af5a05009d80af0226c52736fbba6641d30fd..cb04e1b60546bd5de968eaf67ea5d2fc2b5e24ba 100644 ---- a/src/db/sysdb.h -+++ b/src/db/sysdb.h -@@ -702,6 +702,10 @@ errno_t sysdb_update_certmap(struct sysdb_ctx *sysdb, - struct certmap_info **certmaps, - bool user_name_hint); - -+errno_t sysdb_ldb_msg_attr_to_certmap_info(TALLOC_CTX *mem_ctx, -+ struct ldb_message *msg, -+ struct certmap_info **certmap); -+ - errno_t sysdb_get_certmap(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, - struct certmap_info ***certmaps, - bool *user_name_hint); -diff --git a/src/db/sysdb_certmap.c b/src/db/sysdb_certmap.c -index 6d83ba0884fbacfd068a5b24bd9c7627b70680f5..e61cc05cc0c056a78965ff5989bd46aac2a44b3d 100644 ---- a/src/db/sysdb_certmap.c -+++ b/src/db/sysdb_certmap.c -@@ -262,19 +262,119 @@ done: - return ret; - } - -+errno_t sysdb_ldb_msg_attr_to_certmap_info(TALLOC_CTX *mem_ctx, -+ struct ldb_message *msg, -+ struct certmap_info **certmap) -+{ -+ int ret; -+ size_t d; -+ size_t num_values; -+ struct certmap_info *map = NULL; -+ const char *tmp_str; -+ uint64_t tmp_uint; -+ struct ldb_message_element *tmp_el; -+ -+ -+ map = talloc_zero(mem_ctx, struct certmap_info); -+ if (map == NULL) { -+ return ENOMEM; -+ } -+ -+ tmp_str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); -+ if (tmp_str == NULL) { -+ DEBUG(SSSDBG_MINOR_FAILURE, "The object [%s] doesn't have a name.\n", -+ ldb_dn_get_linearized(msg->dn)); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ map->name = talloc_strdup(map, tmp_str); -+ if (map->name == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ tmp_str = ldb_msg_find_attr_as_string(msg, SYSDB_CERTMAP_MAPPING_RULE, -+ NULL); -+ if (tmp_str != NULL) { -+ map->map_rule = talloc_strdup(map, tmp_str); -+ if (map->map_rule == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ } -+ -+ tmp_str = ldb_msg_find_attr_as_string(msg, SYSDB_CERTMAP_MATCHING_RULE, -+ NULL); -+ if (tmp_str != NULL) { -+ map->match_rule = talloc_strdup(map, tmp_str); -+ if (map->match_rule == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ } -+ -+ tmp_uint = ldb_msg_find_attr_as_uint64(msg, SYSDB_CERTMAP_PRIORITY, -+ (uint64_t) -1); -+ if (tmp_uint != (uint64_t) -1) { -+ if (tmp_uint > UINT32_MAX) { -+ DEBUG(SSSDBG_OP_FAILURE, "Priority value [%lu] too large.\n", -+ (unsigned long) tmp_uint); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ map->priority = (uint32_t) tmp_uint; -+ } -+ -+ tmp_el = ldb_msg_find_element(msg, SYSDB_CERTMAP_DOMAINS); -+ if (tmp_el != NULL) { -+ num_values = tmp_el->num_values; -+ } else { -+ num_values = 0; -+ } -+ -+ map->domains = talloc_zero_array(map, const char *, num_values + 1); -+ if (map->domains == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ for (d = 0; d < num_values; d++) { -+ map->domains[d] = talloc_strndup(map->domains, -+ (char *) tmp_el->values[d].data, -+ tmp_el->values[d].length); -+ if (map->domains[d] == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ } -+ -+ *certmap = map; -+ -+ ret = EOK; -+ -+done: -+ if (ret != EOK) { -+ talloc_free(map); -+ } -+ -+ return ret; -+} -+ - errno_t sysdb_get_certmap(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, - struct certmap_info ***certmaps, bool *user_name_hint) - { - size_t c; -- size_t d; - struct ldb_dn *container_dn = NULL; - int ret; - struct certmap_info **maps = NULL; - TALLOC_CTX *tmp_ctx = NULL; - struct ldb_result *res; -- const char *tmp_str; -- uint64_t tmp_uint; -- struct ldb_message_element *tmp_el; - const char *attrs[] = {SYSDB_NAME, - SYSDB_CERTMAP_PRIORITY, - SYSDB_CERTMAP_MATCHING_RULE, -@@ -283,7 +383,6 @@ errno_t sysdb_get_certmap(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, - NULL}; - const char *config_attrs[] = {SYSDB_CERTMAP_USER_NAME_HINT, - NULL}; -- size_t num_values; - bool hint = false; - - tmp_ctx = talloc_new(NULL); -@@ -332,86 +431,12 @@ errno_t sysdb_get_certmap(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, - } - - for (c = 0; c < res->count; c++) { -- maps[c] = talloc_zero(maps, struct certmap_info); -- if (maps[c] == NULL) { -- ret = ENOMEM; -+ ret = sysdb_ldb_msg_attr_to_certmap_info(maps, res->msgs[c], &maps[c]); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sysdb_ldb_msg_attr_to_certmap_info failed.\n"); - goto done; - } -- tmp_str = ldb_msg_find_attr_as_string(res->msgs[c], SYSDB_NAME, NULL); -- if (tmp_str == NULL) { -- DEBUG(SSSDBG_MINOR_FAILURE, "The object [%s] doesn't have a name.\n", -- ldb_dn_get_linearized(res->msgs[c]->dn)); -- ret = EINVAL; -- goto done; -- } -- -- maps[c]->name = talloc_strdup(maps, tmp_str); -- if (maps[c]->name == NULL) { -- ret = ENOMEM; -- goto done; -- } -- -- tmp_str = ldb_msg_find_attr_as_string(res->msgs[c], -- SYSDB_CERTMAP_MAPPING_RULE, NULL); -- if (tmp_str != NULL) { -- maps[c]->map_rule = talloc_strdup(maps, tmp_str); -- if (maps[c]->map_rule == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); -- ret = ENOMEM; -- goto done; -- } -- } -- -- tmp_str = ldb_msg_find_attr_as_string(res->msgs[c], -- SYSDB_CERTMAP_MATCHING_RULE, NULL); -- if (tmp_str != NULL) { -- maps[c]->match_rule = talloc_strdup(maps, tmp_str); -- if (maps[c]->match_rule == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); -- ret = ENOMEM; -- goto done; -- } -- } -- -- tmp_uint = ldb_msg_find_attr_as_uint64(res->msgs[c], -- SYSDB_CERTMAP_PRIORITY, -- (uint64_t) -1); -- if (tmp_uint != (uint64_t) -1) { -- if (tmp_uint > UINT32_MAX) { -- DEBUG(SSSDBG_OP_FAILURE, "Priority value [%lu] too large.\n", -- (unsigned long) tmp_uint); -- ret = EINVAL; -- goto done; -- } -- -- maps[c]->priority = (uint32_t) tmp_uint; -- } -- -- tmp_el = ldb_msg_find_element(res->msgs[c], SYSDB_CERTMAP_DOMAINS); -- if (tmp_el != NULL) { -- num_values = tmp_el->num_values; -- } else { -- num_values = 0; -- } -- -- maps[c]->domains = talloc_zero_array(maps[c], const char *, -- num_values + 1); -- if (maps[c]->domains == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array failed.\n"); -- ret = ENOMEM; -- goto done; -- } -- -- for (d = 0; d < num_values; d++) { -- maps[c]->domains[d] = talloc_strndup(maps[c]->domains, -- (char *) tmp_el->values[d].data, -- tmp_el->values[d].length); -- if (maps[c]->domains[d] == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); -- ret = ENOMEM; -- goto done; -- } -- } - } - - ret = EOK; --- -2.14.4 - diff --git a/SOURCES/0004-sudo-use-proper-datetime-for-default-modifyTimestamp.patch b/SOURCES/0004-sudo-use-proper-datetime-for-default-modifyTimestamp.patch new file mode 100644 index 0000000..0fb3dab --- /dev/null +++ b/SOURCES/0004-sudo-use-proper-datetime-for-default-modifyTimestamp.patch @@ -0,0 +1,69 @@ +From d15c205bed16f5d138ce5c9335ed9f4aa7d4c25c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Wed, 17 Jul 2019 11:57:23 +0200 +Subject: [PATCH 4/4] sudo: use proper datetime for default modifyTimestamp + value + +The current default was simply "1", however OpenLDAP server was unable +to compare modifyTimestamp attribute to simple number. A proper datetime +is required by OpenLDAP. + +It worked correctly on 389-ds. + +Steps to reproduce: +1. install openldap server +2. run sssd +3. there are no sudo rules on the server and there are no cached objects +4. you'll see in the logs that sudo smart refresh uses `(&(&(objectclass=sudoRole)(modifyTimestamp>=1))...` filter (`1` instead of proper datetime value) + +The minimum accepted value by OpenLDAP is 00000101000000Z, as both month and day can not be zero. + +Resolves: +https://pagure.io/SSSD/sssd/issue/4046 +--- + src/providers/ldap/sdap_sudo_shared.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c +index d2f24ed6e..93a977626 100644 +--- a/src/providers/ldap/sdap_sudo_shared.c ++++ b/src/providers/ldap/sdap_sudo_shared.c +@@ -123,11 +123,24 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx, + static char * + sdap_sudo_new_usn(TALLOC_CTX *mem_ctx, + unsigned long usn, +- const char *leftover) ++ const char *leftover, ++ bool supports_usn) + { + const char *str = leftover == NULL ? "" : leftover; + char *newusn; + ++ /* This is a fresh start and server uses modifyTimestamp. We need to ++ * provide proper datetime value. */ ++ if (!supports_usn && usn == 0) { ++ newusn = talloc_strdup(mem_ctx, "00000101000000Z"); ++ if (newusn == NULL) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to change USN value (OOM)!\n"); ++ return NULL; ++ } ++ ++ return newusn; ++ } ++ + /* We increment USN number so that we can later use simplify filter + * (just usn >= last+1 instead of usn >= last && usn != last). + */ +@@ -178,7 +191,8 @@ sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, + srv_opts->last_usn = usn_number; + } + +- newusn = sdap_sudo_new_usn(srv_opts, srv_opts->last_usn, endptr); ++ newusn = sdap_sudo_new_usn(srv_opts, srv_opts->last_usn, endptr, ++ srv_opts->supports_usn); + if (newusn == NULL) { + return; + } +-- +2.20.1 + diff --git a/SOURCES/0004-sysdb_ldb_msg_attr_to_certmap_info-set-SSS_CERTMAP_M.patch b/SOURCES/0004-sysdb_ldb_msg_attr_to_certmap_info-set-SSS_CERTMAP_M.patch deleted file mode 100644 index 38fc538..0000000 --- a/SOURCES/0004-sysdb_ldb_msg_attr_to_certmap_info-set-SSS_CERTMAP_M.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 2c5808cfe71b221f66ccdb993abe76161d543d5b Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 3 Jul 2018 11:30:07 +0200 -Subject: [PATCH 04/19] sysdb_ldb_msg_attr_to_certmap_info: set - SSS_CERTMAP_MIN_PRIO - -Make sure that priority is always set. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit d1dd7f7703b4f40d2fbb830e28969b31b8a1673e) ---- - src/db/sysdb_certmap.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/db/sysdb_certmap.c b/src/db/sysdb_certmap.c -index e61cc05cc0c056a78965ff5989bd46aac2a44b3d..0bb7ebcade649631ef50e4d62f4ba85fb32c7aa4 100644 ---- a/src/db/sysdb_certmap.c -+++ b/src/db/sysdb_certmap.c -@@ -22,6 +22,7 @@ - - #include "util/util.h" - #include "db/sysdb_private.h" -+#include "lib/certmap/sss_certmap.h" - - static errno_t sysdb_create_certmap_container(struct sysdb_ctx *sysdb, - bool user_name_hint) -@@ -327,6 +328,8 @@ errno_t sysdb_ldb_msg_attr_to_certmap_info(TALLOC_CTX *mem_ctx, - } - - map->priority = (uint32_t) tmp_uint; -+ } else { -+ map->priority = SSS_CERTMAP_MIN_PRIO; - } - - tmp_el = ldb_msg_find_element(msg, SYSDB_CERTMAP_DOMAINS); --- -2.14.4 - diff --git a/SOURCES/0005-negcache-add-fq-usernames-of-know-domains-to-all-UPN.patch b/SOURCES/0005-negcache-add-fq-usernames-of-know-domains-to-all-UPN.patch new file mode 100644 index 0000000..9d2aad4 --- /dev/null +++ b/SOURCES/0005-negcache-add-fq-usernames-of-know-domains-to-all-UPN.patch @@ -0,0 +1,126 @@ +From e7e212b49bbd357129aab410cbbd5c7b1b0965a2 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Mon, 24 Jun 2019 14:01:02 +0200 +Subject: [PATCH] negcache: add fq-usernames of know domains to all UPN + neg-caches + +The previous patch for this issue did not handle user with +fully-qualified names from known domains correctly. Here the user was +only added to the negative cache of the known domain but not to the +negative UPN caches for all domains. This patch fixes this. + +Related to https://pagure.io/SSSD/sssd/issue/3978 + +Reviewed-by: Jakub Hrozek +--- + src/responder/common/negcache.c | 54 ++++++++++++++++---------------- + src/tests/cmocka/test_negcache.c | 17 +++++++++- + 2 files changed, 43 insertions(+), 28 deletions(-) + +diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c +index d6f72d816..d9bf1417e 100644 +--- a/src/responder/common/negcache.c ++++ b/src/responder/common/negcache.c +@@ -1070,37 +1070,37 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache, + continue; + } + if (domainname) { +- dom = responder_get_domain(rctx, domainname); +- if (!dom) { +- DEBUG(SSSDBG_CRIT_FAILURE, +- "Unknown domain name [%s], assuming [%s] is UPN\n", +- domainname, filter_list[i]); +- for (dom = domain_list; +- dom != NULL; +- dom = get_next_domain(dom, SSS_GND_ALL_DOMAINS)) { +- ret = sss_ncache_set_upn(ncache, true, dom, filter_list[i]); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, +- "sss_ncache_set_upn failed (%d [%s]), ignored\n", +- ret, sss_strerror(ret)); +- } ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Adding [%s] to UPN negative cache of all domains.\n", ++ filter_list[i]); ++ for (dom = domain_list; ++ dom != NULL; ++ dom = get_next_domain(dom, SSS_GND_ALL_DOMAINS)) { ++ ret = sss_ncache_set_upn(ncache, true, dom, filter_list[i]); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "sss_ncache_set_upn failed (%d [%s]), ignored\n", ++ ret, sss_strerror(ret)); + } +- continue; + } + +- fqname = sss_create_internal_fqname(tmpctx, name, dom->name); +- if (fqname == NULL) { +- continue; +- } ++ /* Add name to domain specific cache for known domain names */ ++ dom = responder_get_domain(rctx, domainname); ++ if (dom != NULL) { ++ fqname = sss_create_internal_fqname(tmpctx, name, dom->name); ++ if (fqname == NULL) { ++ continue; ++ } + +- ret = sss_ncache_set_user(ncache, true, dom, fqname); +- talloc_zfree(fqname); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, +- "Failed to store permanent user filter for [%s]" +- " (%d [%s])\n", filter_list[i], +- ret, strerror(ret)); +- continue; ++ ret = sss_ncache_set_user(ncache, true, dom, fqname); ++ talloc_zfree(fqname); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "Failed to store permanent user filter for [%s]" ++ " (%d [%s])\n", filter_list[i], ++ ret, strerror(ret)); ++ continue; ++ } + } + } else { + for (dom = domain_list; +diff --git a/src/tests/cmocka/test_negcache.c b/src/tests/cmocka/test_negcache.c +index 7ab8a0981..9d4bdde14 100644 +--- a/src/tests/cmocka/test_negcache.c ++++ b/src/tests/cmocka/test_negcache.c +@@ -637,7 +637,7 @@ static void test_sss_ncache_prepopulate(void **state) + struct sss_domain_info *subdomain; + + struct sss_test_conf_param nss_params[] = { +- { "filter_users", "testuser_nss@UPN.REALM, testuser_nss_short" }, ++ { "filter_users", "testuser_nss@UPN.REALM, testuser_nss_short, all_dom_upn@"TEST_DOM_NAME }, + { NULL, NULL }, + }; + struct sss_test_conf_param dom_params[] = { +@@ -752,6 +752,21 @@ static void test_sss_ncache_prepopulate(void **state) + + ret = sss_ncache_check_upn(ncache, tc->dom, "testuser3@somedomain"); + assert_int_equal(ret, EEXIST); ++ ++ /* Fully qualified names with a known domain part should be added to all ++ * negative UPN caches and to the negative cache of the know domain. */ ++ ret = sss_ncache_check_upn(ncache, tc->dom, "all_dom_upn@"TEST_DOM_NAME); ++ assert_int_equal(ret, EEXIST); ++ ++ ret = sss_ncache_check_upn(ncache, tc->dom->subdomains, ++ "all_dom_upn@"TEST_DOM_NAME); ++ assert_int_equal(ret, EEXIST); ++ ++ ret = check_user_in_ncache(ncache, tc->dom, "all_dom_upn"); ++ assert_int_equal(ret, EEXIST); ++ ++ ret = check_user_in_ncache(ncache, tc->dom->subdomains, "all_dom_upn"); ++ assert_int_equal(ret, ENOENT); + } + + static void test_sss_ncache_default_domain_suffix(void **state) +-- +2.20.1 + diff --git a/SOURCES/0005-sysdb-add-attr_map-attribute-to-sysdb_ldb_msg_attr_t.patch b/SOURCES/0005-sysdb-add-attr_map-attribute-to-sysdb_ldb_msg_attr_t.patch deleted file mode 100644 index c67b895..0000000 --- a/SOURCES/0005-sysdb-add-attr_map-attribute-to-sysdb_ldb_msg_attr_t.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 11878ac29dd0abaad1daad2772e32f1db6f84e3d Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 29 Jun 2018 18:13:59 +0200 -Subject: [PATCH 05/19] sysdb: add attr_map attribute to - sysdb_ldb_msg_attr_to_certmap_info() - -Allow more flexible attribute mapping in -sysdb_ldb_msg_attr_to_certmap_info() - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 0bf709ad348ca115443bd21e4e369abd5d7698c4) ---- - src/db/sysdb.h | 1 + - src/db/sysdb_certmap.c | 39 +++++++++++++++++++++++++++++++-------- - 2 files changed, 32 insertions(+), 8 deletions(-) - -diff --git a/src/db/sysdb.h b/src/db/sysdb.h -index cb04e1b60546bd5de968eaf67ea5d2fc2b5e24ba..2187947dcd74df0511b33ac5823df38a05713e4a 100644 ---- a/src/db/sysdb.h -+++ b/src/db/sysdb.h -@@ -704,6 +704,7 @@ errno_t sysdb_update_certmap(struct sysdb_ctx *sysdb, - - errno_t sysdb_ldb_msg_attr_to_certmap_info(TALLOC_CTX *mem_ctx, - struct ldb_message *msg, -+ const char **attr_map, - struct certmap_info **certmap); - - errno_t sysdb_get_certmap(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, -diff --git a/src/db/sysdb_certmap.c b/src/db/sysdb_certmap.c -index 0bb7ebcade649631ef50e4d62f4ba85fb32c7aa4..e37f1ba830f297137991c7757af9c7c4e17b2813 100644 ---- a/src/db/sysdb_certmap.c -+++ b/src/db/sysdb_certmap.c -@@ -263,8 +263,19 @@ done: - return ret; - } - -+enum certmap_info_member { -+ SSS_CMIM_NAME = 0, -+ SSS_CMIM_MAPPING_RULE, -+ SSS_CMIM_MATCHING_RULE, -+ SSS_CMIM_PRIORITY, -+ SSS_CMIM_DOMAINS, -+ -+ SSS_CMIM_SENTINEL -+}; -+ - errno_t sysdb_ldb_msg_attr_to_certmap_info(TALLOC_CTX *mem_ctx, - struct ldb_message *msg, -+ const char **attr_map, - struct certmap_info **certmap) - { - int ret; -@@ -275,13 +286,24 @@ errno_t sysdb_ldb_msg_attr_to_certmap_info(TALLOC_CTX *mem_ctx, - uint64_t tmp_uint; - struct ldb_message_element *tmp_el; - -+ if (msg == NULL || attr_map == NULL || certmap == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid input.\n"); -+ return EINVAL; -+ } -+ -+ for (d = 0; d < SSS_CMIM_SENTINEL; d++) { -+ if (attr_map[d] == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid attribute map"); -+ return EINVAL; -+ } -+ } - - map = talloc_zero(mem_ctx, struct certmap_info); - if (map == NULL) { - return ENOMEM; - } - -- tmp_str = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); -+ tmp_str = ldb_msg_find_attr_as_string(msg, attr_map[SSS_CMIM_NAME], NULL); - if (tmp_str == NULL) { - DEBUG(SSSDBG_MINOR_FAILURE, "The object [%s] doesn't have a name.\n", - ldb_dn_get_linearized(msg->dn)); -@@ -295,7 +317,7 @@ errno_t sysdb_ldb_msg_attr_to_certmap_info(TALLOC_CTX *mem_ctx, - goto done; - } - -- tmp_str = ldb_msg_find_attr_as_string(msg, SYSDB_CERTMAP_MAPPING_RULE, -+ tmp_str = ldb_msg_find_attr_as_string(msg, attr_map[SSS_CMIM_MAPPING_RULE], - NULL); - if (tmp_str != NULL) { - map->map_rule = talloc_strdup(map, tmp_str); -@@ -306,7 +328,7 @@ errno_t sysdb_ldb_msg_attr_to_certmap_info(TALLOC_CTX *mem_ctx, - } - } - -- tmp_str = ldb_msg_find_attr_as_string(msg, SYSDB_CERTMAP_MATCHING_RULE, -+ tmp_str = ldb_msg_find_attr_as_string(msg, attr_map[SSS_CMIM_MATCHING_RULE], - NULL); - if (tmp_str != NULL) { - map->match_rule = talloc_strdup(map, tmp_str); -@@ -317,7 +339,7 @@ errno_t sysdb_ldb_msg_attr_to_certmap_info(TALLOC_CTX *mem_ctx, - } - } - -- tmp_uint = ldb_msg_find_attr_as_uint64(msg, SYSDB_CERTMAP_PRIORITY, -+ tmp_uint = ldb_msg_find_attr_as_uint64(msg, attr_map[SSS_CMIM_PRIORITY], - (uint64_t) -1); - if (tmp_uint != (uint64_t) -1) { - if (tmp_uint > UINT32_MAX) { -@@ -332,7 +354,7 @@ errno_t sysdb_ldb_msg_attr_to_certmap_info(TALLOC_CTX *mem_ctx, - map->priority = SSS_CERTMAP_MIN_PRIO; - } - -- tmp_el = ldb_msg_find_element(msg, SYSDB_CERTMAP_DOMAINS); -+ tmp_el = ldb_msg_find_element(msg, attr_map[SSS_CMIM_DOMAINS]); - if (tmp_el != NULL) { - num_values = tmp_el->num_values; - } else { -@@ -379,9 +401,9 @@ errno_t sysdb_get_certmap(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, - TALLOC_CTX *tmp_ctx = NULL; - struct ldb_result *res; - const char *attrs[] = {SYSDB_NAME, -- SYSDB_CERTMAP_PRIORITY, -- SYSDB_CERTMAP_MATCHING_RULE, - SYSDB_CERTMAP_MAPPING_RULE, -+ SYSDB_CERTMAP_MATCHING_RULE, -+ SYSDB_CERTMAP_PRIORITY, - SYSDB_CERTMAP_DOMAINS, - NULL}; - const char *config_attrs[] = {SYSDB_CERTMAP_USER_NAME_HINT, -@@ -434,7 +456,8 @@ errno_t sysdb_get_certmap(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, - } - - for (c = 0; c < res->count; c++) { -- ret = sysdb_ldb_msg_attr_to_certmap_info(maps, res->msgs[c], &maps[c]); -+ ret = sysdb_ldb_msg_attr_to_certmap_info(maps, res->msgs[c], attrs, -+ &maps[c]); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "sysdb_ldb_msg_attr_to_certmap_info failed.\n"); --- -2.14.4 - diff --git a/SOURCES/0006-confdb-add-confdb_certmap_to_sysdb.patch b/SOURCES/0006-confdb-add-confdb_certmap_to_sysdb.patch deleted file mode 100644 index 210f90d..0000000 --- a/SOURCES/0006-confdb-add-confdb_certmap_to_sysdb.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 861302754636745a9b60aa3946a749b779d4ef06 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 2 Jul 2018 10:38:54 +0200 -Subject: [PATCH 06/19] confdb: add confdb_certmap_to_sysdb() - -Add a function to write certificate mapping and matching rules from the -config database to the cache of a domain. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit d9cc38008a51a8a5189904f175e4d10cbde4a974) ---- - src/confdb/confdb.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/confdb/confdb.h | 23 +++++++++++++ - 2 files changed, 122 insertions(+) - -diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c -index 22068cacccc90d83047b148513b58618f176dd9a..7de0fb3cc7031767d748bd4fb739a3376fd364e3 100644 ---- a/src/confdb/confdb.c -+++ b/src/confdb/confdb.c -@@ -2196,3 +2196,102 @@ done: - talloc_free(tmp_ctx); - return ret; - } -+ -+static errno_t confdb_get_all_certmaps(TALLOC_CTX *mem_ctx, -+ struct confdb_ctx *cdb, -+ struct sss_domain_info *dom, -+ struct certmap_info ***_certmap_list) -+{ -+ TALLOC_CTX *tmp_ctx = NULL; -+ struct ldb_dn *dn = NULL; -+ struct ldb_result *res = NULL; -+ /* The attributte order is important, because it is used in -+ * sysdb_ldb_msg_attr_to_certmap_info and must match -+ * enum certmap_info_member. */ -+ static const char *attrs[] = { CONFDB_CERTMAP_NAME, -+ CONFDB_CERTMAP_MAPRULE, -+ CONFDB_CERTMAP_MATCHRULE, -+ CONFDB_CERTMAP_PRIORITY, -+ CONFDB_CERTMAP_DOMAINS, -+ NULL}; -+ struct certmap_info **certmap_list = NULL; -+ size_t c; -+ int ret; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ return ENOMEM; -+ } -+ -+ dn = ldb_dn_new_fmt(tmp_ctx, cdb->ldb, "cn=%s,%s", dom->name, -+ CONFDB_CERTMAP_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; -+ } -+ -+ certmap_list = talloc_zero_array(tmp_ctx, struct certmap_info *, -+ res->count + 1); -+ if (certmap_list == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ for (c = 0; c < res->count; c++) { -+ ret = sysdb_ldb_msg_attr_to_certmap_info(certmap_list, res->msgs[c], -+ attrs, &certmap_list[c]); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sysdb_ldb_msg_attr_to_certmap_info failed.\n"); -+ goto done; -+ } -+ } -+ -+ *_certmap_list = talloc_steal(mem_ctx, certmap_list); -+ -+ ret = EOK; -+ -+done: -+ talloc_free(tmp_ctx); -+ return ret; -+} -+ -+int confdb_certmap_to_sysdb(struct confdb_ctx *cdb, -+ struct sss_domain_info *dom) -+{ -+ int ret; -+ TALLOC_CTX *tmp_ctx; -+ struct certmap_info **certmap_list; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); -+ return ENOMEM; -+ } -+ -+ ret = confdb_get_all_certmaps(tmp_ctx, cdb, dom, &certmap_list); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "confdb_get_all_certmaps failed.\n"); -+ goto done; -+ } -+ -+ ret = sysdb_update_certmap(dom->sysdb, certmap_list, false /* TODO */); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_update_certmap failed.\n"); -+ goto done; -+ } -+ -+ ret = EOK; -+ -+done: -+ talloc_free(tmp_ctx); -+ -+ return ret; -+} -diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h -index 22665013aba1f768b7ecd38df9261b84807f70b8..2aae93a278eb62e9b8a18885f06d66b20f269f60 100644 ---- a/src/confdb/confdb.h -+++ b/src/confdb/confdb.h -@@ -265,6 +265,15 @@ - #define CONFDB_KCM_SOCKET "socket_path" - #define CONFDB_KCM_DB "ccache_storage" /* Undocumented on purpose */ - -+/* Certificate mapping rules */ -+#define CONFDB_CERTMAP_BASEDN "cn=certmap,cn=config" -+#define CONFDB_CERTMAP_NAME "cn" -+#define CONFDB_CERTMAP_MAPRULE "maprule" -+#define CONFDB_CERTMAP_MATCHRULE "matchrule" -+#define CONFDB_CERTMAP_DOMAINS "domains" -+#define CONFDB_CERTMAP_PRIORITY "priority" -+ -+ - struct confdb_ctx; - struct config_file_ctx; - -@@ -662,6 +671,20 @@ int confdb_get_sub_sections(TALLOC_CTX *mem_ctx, - const char *section, - char ***sections, - int *num_sections); -+ -+/** -+ * @brief Convenience function to write the certificate mapping and matching -+ * rules from the configuration database to the cache of a domain -+ * -+ * @param[in] cdb The connection object to the confdb -+ * @param[in] dom Target domain where to rules should be written to -+ * -+ * @return 0 - Successfully retrieved the entry (or used the default) -+ * @return ENOMEM - There was insufficient memory to complete the operation -+ * @return EINVAL - Typically internal processing error -+ */ -+int confdb_certmap_to_sysdb(struct confdb_ctx *cdb, -+ struct sss_domain_info *dom); - /** - * @} - */ --- -2.14.4 - diff --git a/SOURCES/0006-p11_child-prefer-better-digest-function-if-card-supp.patch b/SOURCES/0006-p11_child-prefer-better-digest-function-if-card-supp.patch new file mode 100644 index 0000000..b46cf3d --- /dev/null +++ b/SOURCES/0006-p11_child-prefer-better-digest-function-if-card-supp.patch @@ -0,0 +1,147 @@ +From 7f0a8f5060b28dc35e152d7290b583de99361d80 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 2 Jul 2019 17:11:50 +0200 +Subject: [PATCH 6/7] p11_child: prefer better digest function if card supports + it + +To improve FIPS compliance and security in general p11_child now checks +which message digest functions (hashes) are support for RSA keys and +tries to use the highest bit length supported. + +For EC keys sha512 is used unconditionally. + +Related to https://pagure.io/SSSD/sssd/issue/4039 + +Reviewed-by: Alexey Tikhonov +--- + src/p11_child/p11_child_openssl.c | 87 +++++++++++++++++++++++++++++-- + 1 file changed, 82 insertions(+), 5 deletions(-) + +diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c +index 007f58c52..7233f39fd 100644 +--- a/src/p11_child/p11_child_openssl.c ++++ b/src/p11_child/p11_child_openssl.c +@@ -1097,7 +1097,75 @@ static int rs_to_seq(TALLOC_CTX *mem_ctx, CK_BYTE *rs_sig, CK_ULONG rs_sig_len, + return EOK; + } + ++static CK_RV get_preferred_rsa_mechanism(TALLOC_CTX *mem_ctx, ++ CK_FUNCTION_LIST *module, ++ CK_SLOT_ID slot_id, ++ CK_MECHANISM_TYPE *preferred_mechanism, ++ const EVP_MD **preferred_evp_md) ++{ ++ CK_ULONG count; ++ CK_MECHANISM_TYPE *mechanism_list = NULL; ++ CK_RV rv; ++ size_t c; ++ size_t m; ++ struct prefs { ++ CK_MECHANISM_TYPE mech; ++ const char *mech_name; ++ const EVP_MD *evp_md; ++ const char *md_name; ++ } prefs[] = { ++ { CKM_SHA512_RSA_PKCS, "CKM_SHA512_RSA_PKCS", EVP_sha512(), "sha512" }, ++ { CKM_SHA384_RSA_PKCS, "CKM_SHA384_RSA_PKCS", EVP_sha384(), "sha384" }, ++ { CKM_SHA256_RSA_PKCS, "CKM_SHA256_RSA_PKCS", EVP_sha256(), "sha256" }, ++ { CKM_SHA224_RSA_PKCS, "CKM_SHA224_RSA_PKCS", EVP_sha224(), "sha224" }, ++ { CKM_SHA1_RSA_PKCS, "CKM_SHA1_RSA_PKCS", EVP_sha1(), "sha1" }, ++ { 0, NULL } ++ }; ++ ++ *preferred_mechanism = CKM_SHA1_RSA_PKCS; ++ *preferred_evp_md = EVP_sha1(); ++ ++ rv = module->C_GetMechanismList(slot_id, NULL, &count); ++ if (rv == CKR_OK && count > 0) { ++ mechanism_list = talloc_size(mem_ctx, ++ count * sizeof(CK_MECHANISM_TYPE)); ++ if (mechanism_list != NULL) { ++ rv = module->C_GetMechanismList(slot_id, mechanism_list, &count); ++ if (rv == CKR_OK) { ++ if (DEBUG_IS_SET(SSSDBG_TRACE_ALL)) { ++ for (m = 0; m < count; m++) { ++ DEBUG(SSSDBG_TRACE_ALL, "Found mechanism [%lu].\n", ++ mechanism_list[m]); ++ } ++ } ++ for (c = 0; prefs[c].mech != 0; c++) { ++ for (m = 0; m < count; m++) { ++ if (prefs[c].mech == mechanism_list[m]) { ++ *preferred_mechanism = prefs[c].mech; ++ *preferred_evp_md = prefs[c].evp_md; ++ DEBUG(SSSDBG_FUNC_DATA, ++ "Using PKCS#11 mechanism [%lu][%s] and " ++ "local message digest [%s].\n", ++ *preferred_mechanism, prefs[c].mech_name, ++ prefs[c].md_name); ++ break; ++ } ++ } ++ if (m != count) { ++ break; ++ } ++ } ++ } ++ } ++ } ++ ++ talloc_free(mechanism_list); ++ ++ return rv; ++} ++ + static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, ++ CK_SLOT_ID slot_id, + struct cert_list *cert) + { + CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY; +@@ -1108,6 +1176,7 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, + {CKA_ID, NULL, 0} + }; + CK_MECHANISM mechanism = { CK_UNAVAILABLE_INFORMATION, NULL, 0 }; ++ CK_MECHANISM_TYPE preferred_mechanism; + CK_OBJECT_HANDLE priv_key_object; + CK_ULONG object_count; + CK_BYTE random_value[128]; +@@ -1157,15 +1226,23 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, + + switch (get_key_type(module, session, priv_key_object)) { + case CKK_RSA: +- DEBUG(SSSDBG_TRACE_ALL, "Found RSA key using CKM_SHA1_RSA_PKCS.\n"); +- mechanism.mechanism = CKM_SHA1_RSA_PKCS; +- evp_md = EVP_sha1(); ++ rv = get_preferred_rsa_mechanism(cert, module, slot_id, ++ &preferred_mechanism, &evp_md); ++ if (rv != CKR_OK) { ++ DEBUG(SSSDBG_OP_FAILURE, "get_preferred_rsa_mechanism failed, " ++ "using default CKM_SHA1_RSA_PKCS.\n"); ++ preferred_mechanism = CKM_SHA1_RSA_PKCS; ++ evp_md = EVP_sha1(); ++ } ++ DEBUG(SSSDBG_TRACE_ALL, "Found RSA key using mechanism [%lu].\n", ++ preferred_mechanism); ++ mechanism.mechanism = preferred_mechanism; + card_does_hash = true; + break; + case CKK_EC: + DEBUG(SSSDBG_TRACE_ALL, "Found ECC key using CKM_ECDSA.\n"); + mechanism.mechanism = CKM_ECDSA; +- evp_md = EVP_sha1(); ++ evp_md = EVP_sha512(); + card_does_hash = false; + break; + case CK_UNAVAILABLE_INFORMATION: +@@ -1662,7 +1739,7 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, + goto done; + } + +- ret = sign_data(module, session, cert_list); ++ ret = sign_data(module, session, slot_id, cert_list); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sign_data failed.\n"); + ret = EACCES; +-- +2.20.1 + diff --git a/SOURCES/0007-AD-LDAP-read-certificate-mapping-rules-from-config-f.patch b/SOURCES/0007-AD-LDAP-read-certificate-mapping-rules-from-config-f.patch deleted file mode 100644 index a838fe7..0000000 --- a/SOURCES/0007-AD-LDAP-read-certificate-mapping-rules-from-config-f.patch +++ /dev/null @@ -1,72 +0,0 @@ -From cfdabe874c62267bccd3a7b26d16118f9c183c3a Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 2 Jul 2018 12:20:53 +0200 -Subject: [PATCH 07/19] AD/LDAP: read certificate mapping rules from config - file - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 15301db1dc1e5e2aafc1805a30e3b28756218c9b) ---- - src/providers/ad/ad_init.c | 16 ++++++++++++++++ - src/providers/ldap/ldap_init.c | 16 ++++++++++++++++ - 2 files changed, 32 insertions(+) - -diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c -index 637efb761c1cf87b0a2c2b1c19b00ea0bbbe161f..a9085717c5334c2c7dbc48c856cee336ab63d7b0 100644 ---- a/src/providers/ad/ad_init.c -+++ b/src/providers/ad/ad_init.c -@@ -419,6 +419,22 @@ static errno_t ad_init_misc(struct be_ctx *be_ctx, - return ret; - } - -+ ret = confdb_certmap_to_sysdb(be_ctx->cdb, be_ctx->domain); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to initialize certificate mapping rules. " -+ "Authentication with certificates/Smartcards might not work " -+ "as expected.\n"); -+ /* not fatal, ignored */ -+ } -+ -+ ret = sdap_init_certmap(sdap_id_ctx, sdap_id_ctx); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to initialized certificate mapping.\n"); -+ return ret; -+ } -+ - return EOK; - } - -diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c -index 44b3e9ab3dec828b5350ac9e52e56e125084cbac..95e65612369e3e4840f5ffedfe2812d17149c6da 100644 ---- a/src/providers/ldap/ldap_init.c -+++ b/src/providers/ldap/ldap_init.c -@@ -438,6 +438,22 @@ static errno_t ldap_init_misc(struct be_ctx *be_ctx, - "[%d]: %s\n", ret, sss_strerror(ret)); - } - -+ ret = confdb_certmap_to_sysdb(be_ctx->cdb, be_ctx->domain); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to initialize certificate mapping rules. " -+ "Authentication with certificates/Smartcards might not work " -+ "as expected.\n"); -+ /* not fatal, ignored */ -+ } -+ -+ ret = sdap_init_certmap(id_ctx, id_ctx); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to initialized certificate mapping.\n"); -+ return ret; -+ } -+ - return EOK; - } - --- -2.14.4 - diff --git a/SOURCES/0007-p11_child-fix-a-memory-leak-and-other-memory-mangeme.patch b/SOURCES/0007-p11_child-fix-a-memory-leak-and-other-memory-mangeme.patch new file mode 100644 index 0000000..6abe806 --- /dev/null +++ b/SOURCES/0007-p11_child-fix-a-memory-leak-and-other-memory-mangeme.patch @@ -0,0 +1,49 @@ +From 60748f69d9e21cf4cfd0655a0d7b81a715e9ae04 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 2 Jul 2019 21:58:15 +0200 +Subject: [PATCH 7/7] p11_child: fix a memory leak and other memory mangement + issues + +EVP_MD_CTX_create() was called without matching EVP_MD_CTX_destroy(). + +Reviewed-by: Alexey Tikhonov +--- + src/p11_child/p11_child_openssl.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c +index 7233f39fd..64d2d759c 100644 +--- a/src/p11_child/p11_child_openssl.c ++++ b/src/p11_child/p11_child_openssl.c +@@ -986,9 +986,9 @@ static int do_hash(TALLOC_CTX *mem_ctx, const EVP_MD *evp_md, + + done: + ++ EVP_MD_CTX_free(md_ctx); + if (ret != EOK) { + free(out); +- EVP_MD_CTX_free(md_ctx); + } + + return ret; +@@ -1187,7 +1187,7 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, + CK_RV rv; + CK_RV rv_f; + EVP_PKEY *cert_pub_key = NULL; +- EVP_MD_CTX *md_ctx; ++ EVP_MD_CTX *md_ctx = NULL; + int ret; + const EVP_MD *evp_md = NULL; + CK_BYTE *hash_val = NULL; +@@ -1358,6 +1358,8 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, + ret = EOK; + + done: ++ EVP_MD_CTX_destroy(md_ctx); ++ talloc_free(hash_val); + talloc_free(signature); + EVP_PKEY_free(cert_pub_key); + +-- +2.20.1 + diff --git a/SOURCES/0008-man-fix-description-of-dns_resolver_op_timeout.patch b/SOURCES/0008-man-fix-description-of-dns_resolver_op_timeout.patch new file mode 100644 index 0000000..e8624ce --- /dev/null +++ b/SOURCES/0008-man-fix-description-of-dns_resolver_op_timeout.patch @@ -0,0 +1,36 @@ +From 7b4635c8428917ced63954f2c3c70491b45d7870 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Tue, 11 Jun 2019 13:49:13 +0200 +Subject: [PATCH 08/12] man: fix description of dns_resolver_op_timeout + +Resolves: +https://pagure.io/SSSD/sssd/issue/3217 + +Reviewed-by: Jakub Hrozek +Reviewed-by: Sumit Bose +--- + src/man/include/failover.xml | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/src/man/include/failover.xml b/src/man/include/failover.xml +index cd6fd4d79..11ff86a38 100644 +--- a/src/man/include/failover.xml ++++ b/src/man/include/failover.xml +@@ -77,7 +77,13 @@ + + + +- How long would SSSD talk to a single DNS server. ++ Time in seconds to tell how long would SSSD try ++ to resolve single DNS query (e.g. resolution of a ++ hostname or an SRV record) before trying the next ++ hostname or discovery domain. ++ ++ ++ Default: 6 + + + +-- +2.20.1 + diff --git a/SOURCES/0008-sysdb-sysdb_certmap_add-handle-domains-more-flexible.patch b/SOURCES/0008-sysdb-sysdb_certmap_add-handle-domains-more-flexible.patch deleted file mode 100644 index 0ca43a2..0000000 --- a/SOURCES/0008-sysdb-sysdb_certmap_add-handle-domains-more-flexible.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 357323d3312d4f2c6a2bbbea03f2296e3368e45a Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 3 Jul 2018 11:31:12 +0200 -Subject: [PATCH 08/19] sysdb: sysdb_certmap_add() handle domains more flexible - -sysdb_ldb_msg_attr_to_certmap_info() creates an empty list if there are -no domains defined, sysdb_certmap_add() should be able to handle both a -missing or an empty domains list. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 06f7005d38d164879b727708feff80004b422f91) ---- - src/db/sysdb_certmap.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/db/sysdb_certmap.c b/src/db/sysdb_certmap.c -index e37f1ba830f297137991c7757af9c7c4e17b2813..0bcc54c4d1eb0ede7de088e3e945a48f1549c88c 100644 ---- a/src/db/sysdb_certmap.c -+++ b/src/db/sysdb_certmap.c -@@ -131,7 +131,7 @@ static errno_t sysdb_certmap_add(struct sysdb_ctx *sysdb, - } - } - -- if (certmap->domains != NULL) { -+ if (certmap->domains != NULL && certmap->domains[0] != NULL) { - for (c = 0; certmap->domains[c] != NULL; c++); - el = talloc_zero(tmp_ctx, struct ldb_message_element); - if (el == NULL) { --- -2.14.4 - diff --git a/SOURCES/0009-confdb-add-special-handling-for-rules-for-the-files-.patch b/SOURCES/0009-confdb-add-special-handling-for-rules-for-the-files-.patch deleted file mode 100644 index ad0e621..0000000 --- a/SOURCES/0009-confdb-add-special-handling-for-rules-for-the-files-.patch +++ /dev/null @@ -1,132 +0,0 @@ -From db2ca398ef66d73bf04d4cf45a327a8472ce834e Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 6 Jul 2018 15:17:10 +0200 -Subject: [PATCH 09/19] confdb: add special handling for rules for the files - provider - -To make the configuration more simple there are some special assumption -for local users, i.e. user managed by the files provider. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 9386ef605ffbc03abe2bc273efddbc099441fe3b) ---- - src/confdb/confdb.c | 59 ++++++++++++++++++++++++++++++++++++++++ - src/confdb/confdb.h | 1 + - src/providers/files/files_init.c | 10 +++++++ - 3 files changed, 70 insertions(+) - -diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c -index 7de0fb3cc7031767d748bd4fb739a3376fd364e3..6370a0411d98b6611dd384e9ab0de1d580be9c2d 100644 ---- a/src/confdb/confdb.c -+++ b/src/confdb/confdb.c -@@ -2197,6 +2197,56 @@ done: - return ret; - } - -+static errno_t certmap_local_check(struct ldb_message *msg) -+{ -+ const char *rule_name; -+ const char *tmp_str; -+ int ret; -+ -+ rule_name = ldb_msg_find_attr_as_string(msg, CONFDB_CERTMAP_NAME, NULL); -+ if (rule_name == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Certficate mapping rule [%s] has no name.", -+ ldb_dn_get_linearized(msg->dn)); -+ return EINVAL; -+ } -+ -+ tmp_str = ldb_msg_find_attr_as_string(msg, CONFDB_CERTMAP_DOMAINS, NULL); -+ if (tmp_str != NULL) { -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "Option [%s] is ignored for local certmap rules.\n", -+ CONFDB_CERTMAP_DOMAINS); -+ } -+ -+ tmp_str = ldb_msg_find_attr_as_string(msg, CONFDB_CERTMAP_MAPRULE, NULL); -+ if (tmp_str != NULL) { -+ if (tmp_str[0] != '(' || tmp_str[strlen(tmp_str) - 1] != ')') { -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "Mapping rule must be in braces (...).\n"); -+ return EINVAL; -+ } -+ DEBUG(SSSDBG_TRACE_ALL, "Using [%s] mapping rule of [%s].\n", -+ tmp_str, ldb_dn_get_linearized(msg->dn)); -+ return EOK; -+ } -+ -+ tmp_str = talloc_asprintf(msg, "(%s)", rule_name); -+ if (tmp_str == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); -+ return ENOMEM; -+ } -+ ret = ldb_msg_add_string(msg, CONFDB_CERTMAP_MAPRULE, tmp_str); -+ if (ret != LDB_SUCCESS) { -+ talloc_free(discard_const(tmp_str)); -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed.\n"); -+ return EIO; -+ } -+ -+ DEBUG(SSSDBG_TRACE_ALL, "Using [%s] as mapping rule for [%s].\n", -+ tmp_str, ldb_dn_get_linearized(msg->dn)); -+ -+ return EOK; -+} -+ - static errno_t confdb_get_all_certmaps(TALLOC_CTX *mem_ctx, - struct confdb_ctx *cdb, - struct sss_domain_info *dom, -@@ -2245,6 +2295,15 @@ static errno_t confdb_get_all_certmaps(TALLOC_CTX *mem_ctx, - } - - for (c = 0; c < res->count; c++) { -+ if (is_files_provider(dom)) { -+ ret = certmap_local_check(res->msgs[c]); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "Invalid certificate mapping [%s] for local user, " -+ "ignored.\n", ldb_dn_get_linearized(res->msgs[c]->dn)); -+ continue; -+ } -+ } - ret = sysdb_ldb_msg_attr_to_certmap_info(certmap_list, res->msgs[c], - attrs, &certmap_list[c]); - if (ret != EOK) { -diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h -index 2aae93a278eb62e9b8a18885f06d66b20f269f60..625d156267ebf5f59e3974663256acfbb5f3b027 100644 ---- a/src/confdb/confdb.h -+++ b/src/confdb/confdb.h -@@ -685,6 +685,7 @@ int confdb_get_sub_sections(TALLOC_CTX *mem_ctx, - */ - int confdb_certmap_to_sysdb(struct confdb_ctx *cdb, - struct sss_domain_info *dom); -+ - /** - * @} - */ -diff --git a/src/providers/files/files_init.c b/src/providers/files/files_init.c -index 746c04af1d766b4da623196d3ff6ebc99ca6efef..c793bed9cc99db958b50ed9f6d69a2f8f337b409 100644 ---- a/src/providers/files/files_init.c -+++ b/src/providers/files/files_init.c -@@ -189,6 +189,16 @@ int sssm_files_init(TALLOC_CTX *mem_ctx, - goto done; - } - -+ ret = confdb_certmap_to_sysdb(be_ctx->cdb, be_ctx->domain); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to initialize certificate mapping rules. " -+ "Authentication with certificates/Smartcards might not work " -+ "as expected.\n"); -+ /* not fatal, ignored */ -+ } -+ -+ - *_module_data = ctx; - ret = EOK; - done: --- -2.14.4 - diff --git a/SOURCES/0009-man-fix-description-of-dns_resolver_timeout.patch b/SOURCES/0009-man-fix-description-of-dns_resolver_timeout.patch new file mode 100644 index 0000000..4f486f4 --- /dev/null +++ b/SOURCES/0009-man-fix-description-of-dns_resolver_timeout.patch @@ -0,0 +1,31 @@ +From 3807de1d97fc87cf7c25af264a8b1bbabdef54e2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Tue, 11 Jun 2019 13:49:33 +0200 +Subject: [PATCH 09/12] man: fix description of dns_resolver_timeout + +Resolves: +https://pagure.io/SSSD/sssd/issue/3217 + +Reviewed-by: Jakub Hrozek +Reviewed-by: Sumit Bose +--- + src/man/include/failover.xml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/man/include/failover.xml b/src/man/include/failover.xml +index 11ff86a38..7b451d831 100644 +--- a/src/man/include/failover.xml ++++ b/src/man/include/failover.xml +@@ -98,6 +98,9 @@ + include several steps, such as resolving DNS SRV + queries or locating the site. + ++ ++ Default: 6 ++ + + + +-- +2.20.1 + diff --git a/SOURCES/0010-failover-add-dns_resolver_server_timeout-option.patch b/SOURCES/0010-failover-add-dns_resolver_server_timeout-option.patch new file mode 100644 index 0000000..2abfcaf --- /dev/null +++ b/SOURCES/0010-failover-add-dns_resolver_server_timeout-option.patch @@ -0,0 +1,276 @@ +From 99e2a107f01c625cb59cb88589db87294176d6c6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Tue, 11 Jun 2019 13:37:23 +0200 +Subject: [PATCH 10/12] failover: add dns_resolver_server_timeout option + +Resolves: +https://pagure.io/SSSD/sssd/issue/3217 + +Reviewed-by: Jakub Hrozek +Reviewed-by: Sumit Bose +--- + src/config/SSSDConfig/__init__.py.in | 1 + + src/config/SSSDConfigTest.py | 2 ++ + src/config/cfg_rules.ini | 1 + + src/config/etc/sssd.api.conf | 1 + + src/man/include/failover.xml | 17 ++++++++++++++++- + src/providers/data_provider.h | 1 + + src/providers/data_provider_fo.c | 3 +++ + src/resolv/async_resolv.c | 10 ++++++---- + src/resolv/async_resolv.h | 2 +- + src/tests/cmocka/test_fo_srv.c | 4 ++-- + src/tests/cmocka/test_resolv_fake.c | 2 +- + src/tests/fail_over-tests.c | 2 +- + src/tests/resolv-tests.c | 2 +- + 13 files changed, 37 insertions(+), 11 deletions(-) + +diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in +index 9642fe6ba..2d1214e16 100644 +--- a/src/config/SSSDConfig/__init__.py.in ++++ b/src/config/SSSDConfig/__init__.py.in +@@ -171,6 +171,7 @@ option_strings = { + 'entry_cache_timeout' : _('Entry cache timeout length (seconds)'), + 'lookup_family_order' : _('Restrict or prefer a specific address family when performing DNS lookups'), + 'account_cache_expiration' : _('How long to keep cached entries after last successful login (days)'), ++ 'dns_resolver_server_timeout' : _('How long should SSSD talk to single DNS server before trying next server (miliseconds)'), + 'dns_resolver_timeout' : _('How long to wait for replies from DNS when resolving servers (seconds)'), + 'dns_discovery_domain' : _('The domain part of service discovery DNS query'), + 'override_gid' : _('Override GID value from the identity provider with this value'), +diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py +index 727df71ab..82b1a9700 100755 +--- a/src/config/SSSDConfigTest.py ++++ b/src/config/SSSDConfigTest.py +@@ -606,6 +606,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): + 'refresh_expired_interval', + 'lookup_family_order', + 'account_cache_expiration', ++ 'dns_resolver_server_timeout', + 'dns_resolver_timeout', + 'dns_discovery_domain', + 'dyndns_update', +@@ -976,6 +977,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): + 'refresh_expired_interval', + 'account_cache_expiration', + 'lookup_family_order', ++ 'dns_resolver_server_timeout', + 'dns_resolver_timeout', + 'dns_discovery_domain', + 'dyndns_update', +diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini +index 929e6149a..a2efb3a67 100644 +--- a/src/config/cfg_rules.ini ++++ b/src/config/cfg_rules.ini +@@ -367,6 +367,7 @@ option = account_cache_expiration + option = pwd_expiration_warning + option = filter_users + option = filter_groups ++option = dns_resolver_server_timeout + option = dns_resolver_timeout + option = dns_discovery_domain + option = override_gid +diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf +index c6d6690fb..288b1cfe7 100644 +--- a/src/config/etc/sssd.api.conf ++++ b/src/config/etc/sssd.api.conf +@@ -170,6 +170,7 @@ account_cache_expiration = int, None, false + pwd_expiration_warning = int, None, false + filter_users = list, str, false + filter_groups = list, str, false ++dns_resolver_server_timeout = int, None, false + dns_resolver_timeout = int, None, false + dns_discovery_domain = str, None, false + override_gid = int, None, false +diff --git a/src/man/include/failover.xml b/src/man/include/failover.xml +index 7b451d831..f2a01b933 100644 +--- a/src/man/include/failover.xml ++++ b/src/man/include/failover.xml +@@ -71,6 +71,20 @@ + , + manual page. + ++ ++ ++ dns_resolver_server_timeout ++ ++ ++ ++ Time in milliseconds that sets how long would SSSD ++ talk to a single DNS server before trying next one. ++ ++ ++ Default: 2000 ++ ++ ++ + + + dns_resolver_op_timeout +@@ -111,7 +125,8 @@ + ldap_opt_timeout> timeout should be set to + a larger value than dns_resolver_timeout + which in turn should be set to a larger value than +- dns_resolver_op_timeout. ++ dns_resolver_op_timeout which should be larger ++ than dns_resolver_server_timeout. + + + +diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h +index a0a21cc12..2d10dbb5b 100644 +--- a/src/providers/data_provider.h ++++ b/src/providers/data_provider.h +@@ -265,6 +265,7 @@ enum dp_res_opts { + DP_RES_OPT_FAMILY_ORDER, + DP_RES_OPT_RESOLVER_TIMEOUT, + DP_RES_OPT_RESOLVER_OP_TIMEOUT, ++ DP_RES_OPT_RESOLVER_SERVER_TIMEOUT, + DP_RES_OPT_DNS_DOMAIN, + + DP_RES_OPTS /* attrs counter */ +diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c +index 473b667e5..a7af3e2a5 100644 +--- a/src/providers/data_provider_fo.c ++++ b/src/providers/data_provider_fo.c +@@ -833,6 +833,7 @@ static struct dp_option dp_res_default_opts[] = { + { "lookup_family_order", DP_OPT_STRING, { "ipv4_first" }, NULL_STRING }, + { "dns_resolver_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, + { "dns_resolver_op_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, ++ { "dns_resolver_server_timeout", DP_OPT_NUMBER, { .number = 2000 }, NULL_NUMBER }, + { "dns_discovery_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + DP_OPTION_TERMINATOR + }; +@@ -894,6 +895,8 @@ errno_t be_res_init(struct be_ctx *ctx) + ret = resolv_init(ctx, ctx->ev, + dp_opt_get_int(ctx->be_res->opts, + DP_RES_OPT_RESOLVER_OP_TIMEOUT), ++ dp_opt_get_int(ctx->be_res->opts, ++ DP_RES_OPT_RESOLVER_SERVER_TIMEOUT), + &ctx->be_res->resolv); + if (ret != EOK) { + talloc_zfree(ctx->be_res); +diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c +index 01d835ec9..00b9531d4 100644 +--- a/src/resolv/async_resolv.c ++++ b/src/resolv/async_resolv.c +@@ -60,8 +60,6 @@ + #define DNS_RR_LEN(r) DNS__16BIT((r) + 8) + #define DNS_RR_TTL(r) DNS__32BIT((r) + 4) + +-#define RESOLV_TIMEOUTMS 2000 +- + enum host_database default_host_dbs[] = { DB_FILES, DB_DNS, DB_SENTINEL }; + + struct fd_watch { +@@ -83,6 +81,9 @@ struct resolv_ctx { + /* Time in milliseconds before canceling a DNS request */ + int timeout; + ++ /* Time in milliseconds for communication with single DNS server. */ ++ int ares_timeout; ++ + /* The timeout watcher periodically calls ares_process_fd() to check + * if our pending requests didn't timeout. */ + int pending_requests; +@@ -423,7 +424,7 @@ recreate_ares_channel(struct resolv_ctx *ctx) + */ + options.sock_state_cb = fd_event; + options.sock_state_cb_data = ctx; +- options.timeout = RESOLV_TIMEOUTMS; ++ options.timeout = ctx->ares_timeout; + /* Only affects ares_gethostbyname */ + options.lookups = discard_const("f"); + options.tries = 1; +@@ -450,7 +451,7 @@ recreate_ares_channel(struct resolv_ctx *ctx) + + int + resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, +- int timeout, struct resolv_ctx **ctxp) ++ int timeout, int ares_timeout, struct resolv_ctx **ctxp) + { + int ret; + struct resolv_ctx *ctx; +@@ -467,6 +468,7 @@ resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, + + ctx->ev_ctx = ev_ctx; + ctx->timeout = timeout; ++ ctx->ares_timeout = ares_timeout; + + ret = recreate_ares_channel(ctx); + if (ret != EOK) { +diff --git a/src/resolv/async_resolv.h b/src/resolv/async_resolv.h +index 90ed03707..d83a7be44 100644 +--- a/src/resolv/async_resolv.h ++++ b/src/resolv/async_resolv.h +@@ -52,7 +52,7 @@ + struct resolv_ctx; + + int resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, +- int timeout, struct resolv_ctx **ctxp); ++ int timeout, int ares_timeout, struct resolv_ctx **ctxp); + + void resolv_reread_configuration(struct resolv_ctx *ctx); + +diff --git a/src/tests/cmocka/test_fo_srv.c b/src/tests/cmocka/test_fo_srv.c +index a11ebbb54..c13cf3a69 100644 +--- a/src/tests/cmocka/test_fo_srv.c ++++ b/src/tests/cmocka/test_fo_srv.c +@@ -49,7 +49,7 @@ struct resolv_ctx { + + /* mock resolver interface. The resolver test is separate */ + int resolv_init(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, +- int timeout, struct resolv_ctx **ctxp) ++ int timeout, int ares_timeout, struct resolv_ctx **ctxp) + { + *ctxp = talloc(mem_ctx, struct resolv_ctx); + return EOK; +@@ -230,7 +230,7 @@ static int test_fo_setup(void **state) + assert_non_null(test_ctx->ctx); + + ret = resolv_init(test_ctx, test_ctx->ctx->ev, +- TEST_RESOLV_TIMEOUT, &test_ctx->resolv); ++ TEST_RESOLV_TIMEOUT, 2000, &test_ctx->resolv); + assert_non_null(test_ctx->resolv); + + memset(&fopts, 0, sizeof(fopts)); +diff --git a/src/tests/cmocka/test_resolv_fake.c b/src/tests/cmocka/test_resolv_fake.c +index 4cb3d4027..0f4011a39 100644 +--- a/src/tests/cmocka/test_resolv_fake.c ++++ b/src/tests/cmocka/test_resolv_fake.c +@@ -240,7 +240,7 @@ static int test_resolv_fake_setup(void **state) + assert_non_null(test_ctx->ctx); + + ret = resolv_init(test_ctx, test_ctx->ctx->ev, +- TEST_DEFAULT_TIMEOUT, &test_ctx->resolv); ++ TEST_DEFAULT_TIMEOUT, 2000, &test_ctx->resolv); + assert_int_equal(ret, EOK); + + *state = test_ctx; +diff --git a/src/tests/fail_over-tests.c b/src/tests/fail_over-tests.c +index 5312b2772..b2269ef3b 100644 +--- a/src/tests/fail_over-tests.c ++++ b/src/tests/fail_over-tests.c +@@ -73,7 +73,7 @@ setup_test(void) + fail("Could not init tevent context"); + } + +- ret = resolv_init(ctx, ctx->ev, 5, &ctx->resolv); ++ ret = resolv_init(ctx, ctx->ev, 5, 2000, &ctx->resolv); + if (ret != EOK) { + talloc_free(ctx); + fail("Could not init resolv context"); +diff --git a/src/tests/resolv-tests.c b/src/tests/resolv-tests.c +index 4a2b3b904..bc4cd7cc1 100644 +--- a/src/tests/resolv-tests.c ++++ b/src/tests/resolv-tests.c +@@ -76,7 +76,7 @@ static int setup_resolv_test(int timeout, struct resolv_test_ctx **ctx) + return EFAULT; + } + +- ret = resolv_init(test_ctx, test_ctx->ev, timeout, &test_ctx->resolv); ++ ret = resolv_init(test_ctx, test_ctx->ev, timeout, 2000, &test_ctx->resolv); + if (ret != EOK) { + fail("Could not init resolv context"); + talloc_free(test_ctx); +-- +2.20.1 + diff --git a/SOURCES/0010-files-add-support-for-Smartcard-authentication.patch b/SOURCES/0010-files-add-support-for-Smartcard-authentication.patch deleted file mode 100644 index 41d3d62..0000000 --- a/SOURCES/0010-files-add-support-for-Smartcard-authentication.patch +++ /dev/null @@ -1,415 +0,0 @@ -From f92bac7b528d5caf797162ecb4d21f1f7652a49a Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 9 Jul 2018 18:37:46 +0200 -Subject: [PATCH 10/19] files: add support for Smartcard authentication - -To support certificate based authentication the files provider must be -able to map a certificate to a user during a BE_REQ_BY_CERT request. - -Additionally the authentication request should be handled by the PAM -responder code which is responsible for the local Smartcard -authentication. To be consistent with the other backend an authentication -handler is added to the files provider which unconditionally returns the -offline error code telling the PAM responder to handle the -authentication if it has access to the needed credentials. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 275eeed24adc31f3df51cf278f509a4be76a3a3c) ---- - Makefile.am | 2 + - src/providers/files/files_auth.c | 69 +++++++++++++ - src/providers/files/files_certmap.c | 186 ++++++++++++++++++++++++++++++++++++ - src/providers/files/files_id.c | 20 ++++ - src/providers/files/files_init.c | 21 +++- - src/providers/files/files_private.h | 17 ++++ - 6 files changed, 314 insertions(+), 1 deletion(-) - create mode 100644 src/providers/files/files_auth.c - create mode 100644 src/providers/files/files_certmap.c - -diff --git a/Makefile.am b/Makefile.am -index d313957722a1d6be90ee2f91bf2613a39657a6a1..85952818c9a8efd957ce99f4595b251265cc5417 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -4270,6 +4270,8 @@ libsss_proxy_la_LDFLAGS = \ - libsss_files_la_SOURCES = \ - src/providers/files/files_init.c \ - src/providers/files/files_id.c \ -+ src/providers/files/files_auth.c \ -+ src/providers/files/files_certmap.c \ - src/providers/files/files_ops.c \ - src/util/inotify.c \ - $(NULL) -diff --git a/src/providers/files/files_auth.c b/src/providers/files/files_auth.c -new file mode 100644 -index 0000000000000000000000000000000000000000..b71de6971f89a94af0a457f77206c5a7fb3af4ea ---- /dev/null -+++ b/src/providers/files/files_auth.c -@@ -0,0 +1,69 @@ -+/* -+ SSSD -+ -+ files_auth.c - PAM operations on the files provider -+ -+ Copyright (C) 2018 Red Hat -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#include -+ -+#include "providers/data_provider/dp.h" -+#include "providers/data_provider.h" -+#include "providers/files/files_private.h" -+#include "util/cert.h" -+ -+struct files_auth_ctx { -+ struct pam_data *pd; -+}; -+ -+struct tevent_req * -+files_auth_handler_send(TALLOC_CTX *mem_ctx, -+ void *unused, -+ struct pam_data *pd, -+ struct dp_req_params *params) -+{ -+ struct files_auth_ctx *state; -+ struct tevent_req *req; -+ -+ req = tevent_req_create(mem_ctx, &state, struct files_auth_ctx); -+ if (req == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); -+ return NULL; -+ } -+ -+ state->pd = pd; -+ state->pd->pam_status = PAM_AUTHINFO_UNAVAIL; -+ -+ tevent_req_done(req); -+ tevent_req_post(req, params->ev); -+ return req; -+} -+ -+errno_t files_auth_handler_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ struct pam_data **_data) -+{ -+ struct files_auth_ctx *state = NULL; -+ -+ state = tevent_req_data(req, struct files_auth_ctx); -+ -+ TEVENT_REQ_RETURN_ON_ERROR(req); -+ -+ *_data = talloc_steal(mem_ctx, state->pd); -+ -+ return EOK; -+} -diff --git a/src/providers/files/files_certmap.c b/src/providers/files/files_certmap.c -new file mode 100644 -index 0000000000000000000000000000000000000000..7d90a1fecf5c3eedbd9c8570ad6195bde49159d9 ---- /dev/null -+++ b/src/providers/files/files_certmap.c -@@ -0,0 +1,186 @@ -+/* -+ SSSD -+ -+ files_init.c - Initialization of the files provider -+ -+ Copyright (C) 2018 Red Hat -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#include "providers/files/files_private.h" -+#include "util/util.h" -+#include "util/cert.h" -+#include "lib/certmap/sss_certmap.h" -+ -+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 files_init_certmap(TALLOC_CTX *mem_ctx, struct files_id_ctx *id_ctx) -+{ -+ int ret; -+ bool hint; -+ struct certmap_info **certmap_list = NULL; -+ size_t c; -+ -+ ret = sysdb_get_certmap(mem_ctx, id_ctx->be->domain->sysdb, -+ &certmap_list, &hint); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_certmap failed.\n"); -+ goto done; -+ } -+ -+ if (certmap_list == NULL || *certmap_list == NULL) { -+ DEBUG(SSSDBG_TRACE_ALL, "No certmap data, nothing to do.\n"); -+ ret = EOK; -+ goto done; -+ } -+ -+ ret = sss_certmap_init(mem_ctx, ext_debug, NULL, &id_ctx->sss_certmap_ctx); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_init failed.\n"); -+ goto done; -+ } -+ -+ for (c = 0; certmap_list[c] != NULL; c++) { -+ DEBUG(SSSDBG_TRACE_ALL, "Trying to add rule [%s][%d][%s][%s].\n", -+ certmap_list[c]->name, -+ certmap_list[c]->priority, -+ certmap_list[c]->match_rule, -+ certmap_list[c]->map_rule); -+ -+ ret = sss_certmap_add_rule(id_ctx->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: -+ talloc_free(certmap_list); -+ -+ return ret; -+} -+ -+errno_t files_map_cert_to_user(struct files_id_ctx *id_ctx, -+ struct dp_id_data *data) -+{ -+ errno_t ret; -+ char *filter; -+ char *user; -+ struct ldb_message *msg = NULL; -+ struct sysdb_attrs *attrs = NULL; -+ TALLOC_CTX *tmp_ctx; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); -+ return ENOMEM; -+ } -+ -+ ret = sss_cert_derb64_to_ldap_filter(tmp_ctx, data->filter_value, "", -+ id_ctx->sss_certmap_ctx, -+ id_ctx->domain, &filter); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sss_cert_derb64_to_ldap_filter failed.\n"); -+ goto done; -+ } -+ if (filter == NULL || filter[0] != '(' -+ || filter[strlen(filter) - 1] != ')') { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sss_cert_derb64_to_ldap_filter returned bad filter [%s].\n", -+ filter); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ filter[strlen(filter) - 1] = '\0'; -+ user = sss_create_internal_fqname(tmp_ctx, &filter[1], -+ id_ctx->domain->name); -+ if (user == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_create_internal_fqname failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ DEBUG(SSSDBG_TRACE_ALL, "Certificate mapped to user: [%s].\n", user); -+ -+ ret = sysdb_search_user_by_name(tmp_ctx, id_ctx->domain, user, NULL, &msg); -+ if (ret == EOK) { -+ attrs = sysdb_new_attrs(tmp_ctx); -+ if (attrs == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = sysdb_attrs_add_base64_blob(attrs, SYSDB_USER_MAPPED_CERT, -+ data->filter_value); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_base64_blob failed.\n"); -+ goto done; -+ } -+ -+ ret = sysdb_set_entry_attr(id_ctx->domain->sysdb, msg->dn, attrs, -+ SYSDB_MOD_ADD); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_entry_attr failed.\n"); -+ goto done; -+ } -+ } else if (ret == ENOENT) { -+ DEBUG(SSSDBG_TRACE_ALL, "Mapped user [%s] not found.\n", user); -+ ret = EOK; -+ goto done; -+ } else { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_name failed.\n"); -+ goto done; -+ } -+ -+ ret = EOK; -+ -+done: -+ talloc_free(tmp_ctx); -+ -+ return ret; -+} -diff --git a/src/providers/files/files_id.c b/src/providers/files/files_id.c -index 41314c66b1e435b51fe0b9bc18779c11ad261773..f6f8c7311be5fd9511ff4d417975b3195678d053 100644 ---- a/src/providers/files/files_id.c -+++ b/src/providers/files/files_id.c -@@ -87,6 +87,26 @@ files_account_info_handler_send(TALLOC_CTX *mem_ctx, - ? true \ - : false; - break; -+ case BE_REQ_BY_CERT: -+ if (data->filter_type != BE_FILTER_CERT) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Unexpected filter type for lookup by cert: %d\n", -+ data->filter_type); -+ ret = EINVAL; -+ goto immediate; -+ } -+ if (id_ctx->sss_certmap_ctx == NULL) { -+ DEBUG(SSSDBG_TRACE_ALL, "Certificate mapping not configured.\n"); -+ ret = EOK; -+ goto immediate; -+ } -+ -+ ret = files_map_cert_to_user(id_ctx, data); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "files_map_cert_to_user failed"); -+ } -+ goto immediate; -+ break; - default: - DEBUG(SSSDBG_CRIT_FAILURE, - "Unexpected entry type: %d\n", data->entry_type & BE_REQ_TYPE_MASK); -diff --git a/src/providers/files/files_init.c b/src/providers/files/files_init.c -index c793bed9cc99db958b50ed9f6d69a2f8f337b409..1ce4bcf2728004d043c1d26b97aa7c41fb81e181 100644 ---- a/src/providers/files/files_init.c -+++ b/src/providers/files/files_init.c -@@ -196,9 +196,16 @@ int sssm_files_init(TALLOC_CTX *mem_ctx, - "Authentication with certificates/Smartcards might not work " - "as expected.\n"); - /* not fatal, ignored */ -+ } else { -+ ret = files_init_certmap(ctx, ctx); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "files_init_certmap failed. " -+ "Authentication with certificates/Smartcards might not work " -+ "as expected.\n"); -+ /* not fatal, ignored */ -+ } - } - -- - *_module_data = ctx; - ret = EOK; - done: -@@ -234,3 +241,15 @@ int sssm_files_id_init(TALLOC_CTX *mem_ctx, - - return EOK; - } -+ -+int sssm_files_auth_init(TALLOC_CTX *mem_ctx, -+ struct be_ctx *be_ctx, -+ void *module_data, -+ struct dp_method *dp_methods) -+{ -+ dp_set_method(dp_methods, DPM_AUTH_HANDLER, -+ files_auth_handler_send, files_auth_handler_recv, NULL, void, -+ struct pam_data, struct pam_data *); -+ -+ return EOK; -+} -diff --git a/src/providers/files/files_private.h b/src/providers/files/files_private.h -index f44e6d4584e5bd593ef77147b649341c3ace42ed..fd178193086672e7f5ef9541eb81eb462366d824 100644 ---- a/src/providers/files/files_private.h -+++ b/src/providers/files/files_private.h -@@ -38,6 +38,7 @@ struct files_id_ctx { - struct be_ctx *be; - struct sss_domain_info *domain; - struct files_ctx *fctx; -+ struct sss_certmap_ctx *sss_certmap_ctx; - - const char **passwd_files; - const char **group_files; -@@ -71,4 +72,20 @@ errno_t files_account_info_handler_recv(TALLOC_CTX *mem_ctx, - void files_account_info_finished(struct files_id_ctx *id_ctx, - int req_type, - errno_t ret); -+ -+/* files_auth.c */ -+struct tevent_req *files_auth_handler_send(TALLOC_CTX *mem_ctx, -+ void *unused, -+ struct pam_data *pd, -+ struct dp_req_params *params); -+ -+errno_t files_auth_handler_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ struct pam_data **_data); -+ -+/* files_certmap.c */ -+errno_t files_init_certmap(TALLOC_CTX *mem_ctx, struct files_id_ctx *id_ctx); -+ -+errno_t files_map_cert_to_user(struct files_id_ctx *id_ctx, -+ struct dp_id_data *data); - #endif /* __FILES_PRIVATE_H_ */ --- -2.14.4 - diff --git a/SOURCES/0011-failover-change-default-timeouts.patch b/SOURCES/0011-failover-change-default-timeouts.patch new file mode 100644 index 0000000..b47979e --- /dev/null +++ b/SOURCES/0011-failover-change-default-timeouts.patch @@ -0,0 +1,120 @@ +From e97ff0adb62c89cfc7e75858b7e592e0303720b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Tue, 11 Jun 2019 14:01:17 +0200 +Subject: [PATCH 11/12] failover: change default timeouts + +Resolves: +https://pagure.io/SSSD/sssd/issue/3217 + +Reviewed-by: Jakub Hrozek +Reviewed-by: Sumit Bose +--- + src/man/include/failover.xml | 6 +++--- + src/man/sssd-ldap.5.xml | 2 +- + src/providers/ad/ad_opts.c | 2 +- + src/providers/data_provider_fo.c | 4 ++-- + src/providers/ipa/ipa_opts.c | 2 +- + src/providers/ldap/ldap_opts.c | 2 +- + 6 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/src/man/include/failover.xml b/src/man/include/failover.xml +index f2a01b933..288d91807 100644 +--- a/src/man/include/failover.xml ++++ b/src/man/include/failover.xml +@@ -81,7 +81,7 @@ + talk to a single DNS server before trying next one. + + +- Default: 2000 ++ Default: 1000 + + + +@@ -97,7 +97,7 @@ + hostname or discovery domain. + + +- Default: 6 ++ Default: 2 + + + +@@ -113,7 +113,7 @@ + queries or locating the site. + + +- Default: 6 ++ Default: 4 + + + +diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml +index f0bc82db5..c205aea64 100644 +--- a/src/man/sssd-ldap.5.xml ++++ b/src/man/sssd-ldap.5.xml +@@ -1432,7 +1432,7 @@ + StartTLS operation. + + +- Default: 6 ++ Default: 8 + + + +diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c +index 978c395ef..3f7ec08b1 100644 +--- a/src/providers/ad/ad_opts.c ++++ b/src/providers/ad/ad_opts.c +@@ -65,7 +65,7 @@ struct dp_option ad_def_ldap_opts[] = { + { "ldap_default_authtok", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB }, + { "ldap_search_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, + { "ldap_network_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, +- { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, ++ { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 8 }, NULL_NUMBER }, + { "ldap_tls_reqcert", DP_OPT_STRING, { "hard" }, NULL_STRING }, + { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, +diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c +index a7af3e2a5..c634b8d49 100644 +--- a/src/providers/data_provider_fo.c ++++ b/src/providers/data_provider_fo.c +@@ -832,8 +832,8 @@ void _be_fo_set_port_status(struct be_ctx *ctx, + static struct dp_option dp_res_default_opts[] = { + { "lookup_family_order", DP_OPT_STRING, { "ipv4_first" }, NULL_STRING }, + { "dns_resolver_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, +- { "dns_resolver_op_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, +- { "dns_resolver_server_timeout", DP_OPT_NUMBER, { .number = 2000 }, NULL_NUMBER }, ++ { "dns_resolver_op_timeout", DP_OPT_NUMBER, { .number = 3 }, NULL_NUMBER }, ++ { "dns_resolver_server_timeout", DP_OPT_NUMBER, { .number = 1000 }, NULL_NUMBER }, + { "dns_discovery_domain", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + DP_OPTION_TERMINATOR + }; +diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c +index c38a7da0e..7974cb8ea 100644 +--- a/src/providers/ipa/ipa_opts.c ++++ b/src/providers/ipa/ipa_opts.c +@@ -76,7 +76,7 @@ struct dp_option ipa_def_ldap_opts[] = { + { "ldap_default_authtok", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB }, + { "ldap_search_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, + { "ldap_network_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, +- { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, ++ { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 8 }, NULL_NUMBER }, + { "ldap_tls_reqcert", DP_OPT_STRING, { "hard" }, NULL_STRING }, + { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, +diff --git a/src/providers/ldap/ldap_opts.c b/src/providers/ldap/ldap_opts.c +index dc56f0712..616934a21 100644 +--- a/src/providers/ldap/ldap_opts.c ++++ b/src/providers/ldap/ldap_opts.c +@@ -36,7 +36,7 @@ struct dp_option default_basic_opts[] = { + { "ldap_default_authtok", DP_OPT_BLOB, NULL_BLOB, NULL_BLOB }, + { "ldap_search_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, + { "ldap_network_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, +- { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 6 }, NULL_NUMBER }, ++ { "ldap_opt_timeout", DP_OPT_NUMBER, { .number = 8 }, NULL_NUMBER }, + { "ldap_tls_reqcert", DP_OPT_STRING, { "hard" }, NULL_STRING }, + { "ldap_user_search_base", DP_OPT_STRING, NULL_STRING, NULL_STRING }, + { "ldap_user_search_scope", DP_OPT_STRING, { "sub" }, NULL_STRING }, +-- +2.20.1 + diff --git a/SOURCES/0011-responder-make-sure-SSS_DP_CERT-is-passed-to-files-p.patch b/SOURCES/0011-responder-make-sure-SSS_DP_CERT-is-passed-to-files-p.patch deleted file mode 100644 index be4740f..0000000 --- a/SOURCES/0011-responder-make-sure-SSS_DP_CERT-is-passed-to-files-p.patch +++ /dev/null @@ -1,69 +0,0 @@ -From c250beca50dbebc0cf1e90cdc1c871e9eeca922d Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 9 Jul 2018 18:45:21 +0200 -Subject: [PATCH 11/19] responder: make sure SSS_DP_CERT is passed to files - provider - -Currently the files provider is only contacted once in a while to update -the full cache with fresh data from the passwd file. To allow rule based -certificate mapping the lookup by certificate request must be always -send to the file provider so that it can evaluate the rules and add the -certificate to cached entry of the matching user. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 9fdc5f1d87a133885e6a22810a7eb980c60dcb55) ---- - src/responder/common/responder_dp.c | 20 +++++++++++++------- - 1 file changed, 13 insertions(+), 7 deletions(-) - -diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c -index 878aa1d73be0ccc56afb79303b61cd5cffe7b5e0..39f0f20c506c7ed63b271461f982ebb4f84afce7 100644 ---- a/src/responder/common/responder_dp.c -+++ b/src/responder/common/responder_dp.c -@@ -34,15 +34,17 @@ sss_dp_account_files_params(struct sss_domain_info *dom, - enum sss_dp_acct_type *_type_out, - const char **_opt_name_out) - { -- if (sss_domain_get_state(dom) != DOM_INCONSISTENT) { -+ if (type_in != SSS_DP_CERT) { -+ if (sss_domain_get_state(dom) != DOM_INCONSISTENT) { -+ DEBUG(SSSDBG_TRACE_INTERNAL, -+ "The entries in the files domain are up-to-date\n"); -+ return EOK; -+ } -+ - DEBUG(SSSDBG_TRACE_INTERNAL, -- "The entries in the files domain are up-to-date\n"); -- return EOK; -+ "Domain files is not consistent, issuing update\n"); - } - -- DEBUG(SSSDBG_TRACE_INTERNAL, -- "Domain files is not consistent, issuing update\n"); -- - switch(type_in) { - case SSS_DP_USER: - case SSS_DP_GROUP: -@@ -56,12 +58,16 @@ sss_dp_account_files_params(struct sss_domain_info *dom, - *_type_out = type_in; - *_opt_name_out = DP_REQ_OPT_FILES_INITGR; - return EAGAIN; -+ case SSS_DP_CERT: -+ /* Let the backend handle certificate mapping for local users */ -+ *_type_out = type_in; -+ *_opt_name_out = opt_name_in; -+ return EAGAIN; - /* These are not handled by the files provider, just fall back */ - case SSS_DP_NETGR: - case SSS_DP_SERVICES: - case SSS_DP_SECID: - case SSS_DP_USER_AND_GROUP: -- case SSS_DP_CERT: - case SSS_DP_WILDCARD_USER: - case SSS_DP_WILDCARD_GROUP: - return EOK; --- -2.14.4 - diff --git a/SOURCES/0012-PAM-add-certificate-matching-rules-from-all-domains.patch b/SOURCES/0012-PAM-add-certificate-matching-rules-from-all-domains.patch deleted file mode 100644 index 2dea1b9..0000000 --- a/SOURCES/0012-PAM-add-certificate-matching-rules-from-all-domains.patch +++ /dev/null @@ -1,167 +0,0 @@ -From 3d2a1323cc24a2af3a0ebaa4bb6096ae49c3a12d Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 9 Jul 2018 18:56:26 +0200 -Subject: [PATCH 12/19] PAM: add certificate matching rules from all domains - -Currently the PAM responder only reads the certificate mapping and -matching rules from the first domain. To support Smartcard -authentication for local and remote users all configured domains must be -taken into account. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit d42f44d54453d3ddb54875374c1b61dc1e7cd821) ---- - src/responder/pam/pamsrv.h | 2 +- - src/responder/pam/pamsrv_cmd.c | 2 +- - src/responder/pam/pamsrv_p11.c | 77 +++++++++++++++++++++++++++--------------- - 3 files changed, 51 insertions(+), 30 deletions(-) - -diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h -index d189cccbaa1db7c00d03cf138b290c7ce99ca9a9..5d877566fc7bacced4f6385f1eae344a9e6d8bd4 100644 ---- a/src/responder/pam/pamsrv.h -+++ b/src/responder/pam/pamsrv.h -@@ -114,7 +114,7 @@ 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); -+ struct sss_domain_info *domains); - - errno_t - pam_set_last_online_auth_with_curr_token(struct sss_domain_info *domain, -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index a6bb2897b7b78ba6cc239adeea020e7ef49629cd..ed9ad57bd6d8c4eda30d8e18f83aeea96474551f 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -1737,7 +1737,7 @@ static void pam_forwarder_cb(struct tevent_req *req) - goto done; - } - -- ret = p11_refresh_certmap_ctx(pctx, pctx->rctx->domains->certmaps); -+ ret = p11_refresh_certmap_ctx(pctx, pctx->rctx->domains); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "p11_refresh_certmap_ctx failed, " -diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c -index bf722074384d9cadd2303b71b5823b0bf47be081..ffa6787e967488ac408ce0f0a11b96066c29b630 100644 ---- a/src/responder/pam/pamsrv_p11.c -+++ b/src/responder/pam/pamsrv_p11.c -@@ -142,11 +142,14 @@ static void ext_debug(void *private, const char *file, long line, - } - - errno_t p11_refresh_certmap_ctx(struct pam_ctx *pctx, -- struct certmap_info **certmap_list) -+ struct sss_domain_info *domains) - { - int ret; - struct sss_certmap_ctx *sss_certmap_ctx = NULL; - size_t c; -+ struct sss_domain_info *dom; -+ bool certmap_found = false; -+ struct certmap_info **certmap_list; - - ret = sss_certmap_init(pctx, ext_debug, NULL, &sss_certmap_ctx); - if (ret != EOK) { -@@ -154,7 +157,15 @@ errno_t p11_refresh_certmap_ctx(struct pam_ctx *pctx, - goto done; - } - -- if (certmap_list == NULL || *certmap_list == NULL) { -+ DLIST_FOR_EACH(dom, domains) { -+ certmap_list = dom->certmaps; -+ if (certmap_list != NULL && *certmap_list != NULL) { -+ certmap_found = true; -+ break; -+ } -+ } -+ -+ if (!certmap_found) { - /* 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); -@@ -166,24 +177,32 @@ errno_t p11_refresh_certmap_ctx(struct pam_ctx *pctx, - 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)); -+ DLIST_FOR_EACH(dom, domains) { -+ certmap_list = dom->certmaps; -+ if (certmap_list == NULL || *certmap_list == NULL) { - continue; - } -+ -+ 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; -@@ -204,19 +223,21 @@ 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; -+ struct sss_domain_info *dom; - -- 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; -+ DLIST_FOR_EACH(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; - } - -- dom->user_name_hint = user_name_hint; -- talloc_free(dom->certmaps); -- dom->certmaps = certmaps; -- -- ret = p11_refresh_certmap_ctx(pctx, dom->certmaps); -+ ret = p11_refresh_certmap_ctx(pctx, pctx->rctx->domains); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "p11_refresh_certmap_ctx failed.\n"); - return ret; --- -2.14.4 - diff --git a/SOURCES/0012-config-add-dns_resolver_op_timeout-to-option-list.patch b/SOURCES/0012-config-add-dns_resolver_op_timeout-to-option-list.patch new file mode 100644 index 0000000..da4c0e0 --- /dev/null +++ b/SOURCES/0012-config-add-dns_resolver_op_timeout-to-option-list.patch @@ -0,0 +1,76 @@ +From 049f3906b9ef2041b5e1df666bd570379ae60718 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Pavel=20B=C5=99ezina?= +Date: Mon, 8 Jul 2019 11:35:28 +0200 +Subject: [PATCH 12/12] config: add dns_resolver_op_timeout to option list + +Resolves: +https://pagure.io/SSSD/sssd/issue/3217 + +Reviewed-by: Jakub Hrozek +Reviewed-by: Sumit Bose +--- + src/config/SSSDConfig/__init__.py.in | 1 + + src/config/SSSDConfigTest.py | 2 ++ + src/config/cfg_rules.ini | 1 + + src/config/etc/sssd.api.conf | 1 + + 4 files changed, 5 insertions(+) + +diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in +index 2d1214e16..ea7995410 100644 +--- a/src/config/SSSDConfig/__init__.py.in ++++ b/src/config/SSSDConfig/__init__.py.in +@@ -172,6 +172,7 @@ option_strings = { + 'lookup_family_order' : _('Restrict or prefer a specific address family when performing DNS lookups'), + 'account_cache_expiration' : _('How long to keep cached entries after last successful login (days)'), + 'dns_resolver_server_timeout' : _('How long should SSSD talk to single DNS server before trying next server (miliseconds)'), ++ 'dns_resolver_op_timeout' : _('How long should keep trying to resolve single DNS query (seconds)'), + 'dns_resolver_timeout' : _('How long to wait for replies from DNS when resolving servers (seconds)'), + 'dns_discovery_domain' : _('The domain part of service discovery DNS query'), + 'override_gid' : _('Override GID value from the identity provider with this value'), +diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py +index 82b1a9700..95dfd677d 100755 +--- a/src/config/SSSDConfigTest.py ++++ b/src/config/SSSDConfigTest.py +@@ -607,6 +607,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): + 'lookup_family_order', + 'account_cache_expiration', + 'dns_resolver_server_timeout', ++ 'dns_resolver_op_timeout', + 'dns_resolver_timeout', + 'dns_discovery_domain', + 'dyndns_update', +@@ -978,6 +979,7 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): + 'account_cache_expiration', + 'lookup_family_order', + 'dns_resolver_server_timeout', ++ 'dns_resolver_op_timeout', + 'dns_resolver_timeout', + 'dns_discovery_domain', + 'dyndns_update', +diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini +index a2efb3a67..30040b595 100644 +--- a/src/config/cfg_rules.ini ++++ b/src/config/cfg_rules.ini +@@ -368,6 +368,7 @@ option = pwd_expiration_warning + option = filter_users + option = filter_groups + option = dns_resolver_server_timeout ++option = dns_resolver_op_timeout + option = dns_resolver_timeout + option = dns_discovery_domain + option = override_gid +diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf +index 288b1cfe7..4a069f2db 100644 +--- a/src/config/etc/sssd.api.conf ++++ b/src/config/etc/sssd.api.conf +@@ -171,6 +171,7 @@ pwd_expiration_warning = int, None, false + filter_users = list, str, false + filter_groups = list, str, false + dns_resolver_server_timeout = int, None, false ++dns_resolver_op_timeout = int, None, false + dns_resolver_timeout = int, None, false + dns_discovery_domain = str, None, false + override_gid = int, None, false +-- +2.20.1 + diff --git a/SOURCES/0013-doc-add-certificate-mapping-section-to-man-page.patch b/SOURCES/0013-doc-add-certificate-mapping-section-to-man-page.patch deleted file mode 100644 index e6641ce..0000000 --- a/SOURCES/0013-doc-add-certificate-mapping-section-to-man-page.patch +++ /dev/null @@ -1,183 +0,0 @@ -From ad3c2c6f89d3d07c5e901706c796de41d160d3bb Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 3 Sep 2018 18:38:42 +0200 -Subject: [PATCH 13/19] doc: add certificate mapping section to man page - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 0c739e969a617bdb4c06cdfd63772bf6d283c518) ---- - src/man/sssd.conf.5.xml | 149 ++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 149 insertions(+) - -diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml -index 881ffc6ab389fec2b85d675f43b951ca5fa0f2fc..04143f199685b7703abe1b5bb82b6c33230e6c72 100644 ---- a/src/man/sssd.conf.5.xml -+++ b/src/man/sssd.conf.5.xml -@@ -3299,6 +3299,135 @@ ldap_user_extra_attrs = phone:telephoneNumber - - - -+ -+ CERTIFICATE MAPPING SECTION -+ -+ To allow authentication with Smartcards and certificates SSSD must -+ be able to map certificates to users. This can be done by adding the -+ full certificate to the LDAP object of the user or to a local -+ override. While using the full certificate is required to use the -+ Smartcard authentication feature of SSH (see -+ -+ sss_ssh_authorizedkeys -+ 8 -+ -+ for details) it might be cumbersome or not even possible to do this -+ for the general case where local services use PAM for -+ authentication. -+ -+ -+ To make the mapping more flexible mapping and matching rules were -+ added to SSSD (see -+ -+ sss-certmap -+ 5 -+ -+ for details). -+ -+ -+ A mapping and matching rule can be added to the SSSD configuration -+ in a section on its own with a name like -+ [certmap/DOMAIN_NAME/RULE_NAME]. -+ In this section the following options are allowed: -+ -+ -+ -+ matchrule (string) -+ -+ -+ Only certificates from the Smartcard which matches this -+ rule will be processed, all others are ignored. -+ -+ -+ Default: KRB5:<EKU>clientAuth, i.e. only -+ certificates which have the Extended Key Usage -+ clientAuth -+ -+ -+ -+ -+ maprule (string) -+ -+ -+ Defines how the user is found for a given certificate. -+ -+ -+ Default: -+ -+ -+ LDAP:(userCertificate;binary={cert!bin}) -+ for LDAP based providers like -+ ldap, AD or -+ ipa. -+ -+ -+ The RULE_NAME for the files -+ provider which tries to find a user with the -+ same name. -+ -+ -+ -+ -+ -+ -+ domains (string) -+ -+ -+ Comma separated list of domain names the rule should be -+ applied. By default a rule is only valid in the domain -+ configured in sssd.conf. If the provider supports -+ subdomains this option can be used to add the rule to -+ subdomains as well. -+ -+ -+ Default: the configured domain in sssd.conf -+ -+ -+ -+ -+ priority (integer) -+ -+ -+ Unsigned integer value defining the priority of the -+ rule. The higher the number the lower the priority. -+ 0 stands for the highest priority while -+ 4294967295 is the lowest. -+ -+ -+ Default: the lowest priority -+ -+ -+ -+ -+ -+ To make the configuration simple and reduce the amount of -+ configuration options the files provider has some -+ special properties: -+ -+ -+ -+ if maprule is not set the RULE_NAME name is assumed to -+ be the name of the matching user -+ -+ -+ -+ -+ if a maprule is used both a single user name or a -+ template like -+ {subject_rfc822_name.short_name} must -+ be in braces like e.g. (username) or -+ ({subject_rfc822_name.short_name}) -+ -+ -+ -+ -+ the domains option is ignored -+ -+ -+ -+ -+ -+ - - EXAMPLES - -@@ -3341,6 +3470,26 @@ enumerate = False - - [domain/ipa.com/child.ad.com] - use_fully_qualified_names = false -+ -+ -+ -+ 3. The following example shows the configuration for two certificate -+ mapping rules. The first is valid for the configured domain -+ my.domain and additionally for the subdomains -+ your.domain and uses the full certificate in the -+ search filter. The second example is valid for the domain -+ files where it is assumed the files provider is used -+ for this domain and contains a matching rule for the local user -+ myname. -+ -+[certmap/my.domain/rule_name] -+matchrule = <ISSUER>^CN=My-CA,DC=MY,DC=DOMAIN$ -+maprule = (userCertificate;binary={cert!bin}) -+domains = my.domain, your.domain -+priority = 10 -+ -+[certmap/files/myname] -+matchrule = <ISSUER>^CN=My-CA,DC=MY,DC=DOMAIN$<SUBJECT>^CN=User.Name,DC=MY,DC=DOMAIN$ - - - --- -2.14.4 - diff --git a/SOURCES/0013-pam_sss-Add-missing-colon-to-the-PIN-prompt.patch b/SOURCES/0013-pam_sss-Add-missing-colon-to-the-PIN-prompt.patch new file mode 100644 index 0000000..b9c83c6 --- /dev/null +++ b/SOURCES/0013-pam_sss-Add-missing-colon-to-the-PIN-prompt.patch @@ -0,0 +1,33 @@ +From db46cd0890057be1f72173a2ca2ae040bcf46c9a Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Wed, 31 Jul 2019 12:20:42 +0200 +Subject: [PATCH] pam_sss: Add missing colon to the PIN prompt + +This can be noticed in the sudo prompt, when the system is configured +to authenticate users using smart cards. + +Resolves: Pagure#4049 + +Signed-off-by: Jakub Jelen + +Reviewed-by: Sumit Bose +--- + src/sss_client/pam_sss.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c +index 6bcda23da..cfd3e3731 100644 +--- a/src/sss_client/pam_sss.c ++++ b/src/sss_client/pam_sss.c +@@ -1609,7 +1609,7 @@ static int prompt_2fa_single(pam_handle_t *pamh, struct pam_items *pi, + return PAM_SUCCESS; + } + +-#define SC_PROMPT_FMT "PIN for %s" ++#define SC_PROMPT_FMT "PIN for %s: " + + #ifndef discard_const + #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) +-- +2.20.1 + diff --git a/SOURCES/0014-intg-user-default-locale.patch b/SOURCES/0014-intg-user-default-locale.patch deleted file mode 100644 index 1e94700..0000000 --- a/SOURCES/0014-intg-user-default-locale.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 2ea286d7c11f7106d2f7d513f9211a7620fbdcb0 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 7 Sep 2018 22:12:02 +0200 -Subject: [PATCH 14/19] intg: user default locale - -Some checks depend on english error messages so checks should be always -run with the default locale. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 16941c47a6f0fc2f1679725d55cde221f3c3a6ef) ---- - src/tests/intg/Makefile.am | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am -index 65da9ca170f57d1aa736c217f311992bdf53d2a1..6f7605bd4edbf26ef3ce97acea74fc92216eede9 100644 ---- a/src/tests/intg/Makefile.am -+++ b/src/tests/intg/Makefile.am -@@ -126,6 +126,7 @@ intgcheck-installed: config.py passwd group - PATH="$$(dirname -- $(SLAPD)):$$PATH" \ - PATH="$(DESTDIR)$(sbindir):$(DESTDIR)$(bindir):$$PATH" \ - PATH="$$PATH:$(abs_builddir):$(abs_srcdir)" \ -+ LANG=C \ - PYTHONPATH="$(abs_builddir):$(abs_srcdir)" \ - LDB_MODULES_PATH="$(DESTDIR)$(ldblibdir)" \ - NON_WRAPPED_UID=$$(id -u) \ --- -2.14.4 - diff --git a/SOURCES/0014-pam-make-sure-p11_child.log-has-the-right-permission.patch b/SOURCES/0014-pam-make-sure-p11_child.log-has-the-right-permission.patch new file mode 100644 index 0000000..5b723b4 --- /dev/null +++ b/SOURCES/0014-pam-make-sure-p11_child.log-has-the-right-permission.patch @@ -0,0 +1,39 @@ +From e9091aba9c0cbcc1f00f5f0656c200554cc485a3 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 2 Aug 2019 13:44:18 +0200 +Subject: [PATCH 14/16] pam: make sure p11_child.log has the right permissions + +If SSSD runs a unprivileged user we should make sure the log files for +child processes have the right permission so that the child process can +write to them. + +Related to https://pagure.io/SSSD/sssd/issue/4056 + +Reviewed-by: Jakub Hrozek +--- + src/responder/pam/pamsrv.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c +index 38db6fc9b..4f5b9b664 100644 +--- a/src/responder/pam/pamsrv.c ++++ b/src/responder/pam/pamsrv.c +@@ -399,6 +399,15 @@ int main(int argc, const char *argv[]) + } + } + ++ /* server_setup() might switch to an unprivileged user, so the permissions ++ * for p11_child.log have to be fixed first. */ ++ ret = chown_debug_file("p11_child", uid, gid); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Cannot chown the p11_child debug file, " ++ "debugging might not work!\n"); ++ } ++ + ret = server_setup("sssd[pam]", 0, uid, gid, CONFDB_PAM_CONF_ENTRY, &main_ctx); + if (ret != EOK) return 2; + +-- +2.20.1 + diff --git a/SOURCES/0015-PAM-use-better-PAM-error-code-for-failed-Smartcard-a.patch b/SOURCES/0015-PAM-use-better-PAM-error-code-for-failed-Smartcard-a.patch deleted file mode 100644 index 39c3c91..0000000 --- a/SOURCES/0015-PAM-use-better-PAM-error-code-for-failed-Smartcard-a.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 8948c89c132d31c8cffd55d60e46a506eb00bbd2 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 7 Sep 2018 22:16:50 +0200 -Subject: [PATCH 15/19] PAM: use better PAM error code for failed Smartcard - authentication - -If the user enters a wrong PIN the PAM responder currently returns -PAM_USER_UNKNOWN better is PAM_AUTH_ERR. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 442ae7b1d0704cdd667d4f1ba4c165ce3f3ffed4) ---- - src/responder/pam/pamsrv_cmd.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index ed9ad57bd6d8c4eda30d8e18f83aeea96474551f..817f3c5134ba4c7358ffb4fbf3c6008fa23ffe0e 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -1436,7 +1436,9 @@ static void pam_forwarder_cert_cb(struct tevent_req *req) - if (pd->cmd == SSS_PAM_AUTHENTICATE) { - DEBUG(SSSDBG_CRIT_FAILURE, - "No certificate returned, authentication failed.\n"); -- ret = ENOENT; -+ preq->pd->pam_status = PAM_AUTH_ERR; -+ pam_reply(preq); -+ return; - } else { - ret = pam_check_user_search(preq); - } --- -2.14.4 - diff --git a/SOURCES/0015-ssh-make-sure-p11_child.log-has-the-right-permission.patch b/SOURCES/0015-ssh-make-sure-p11_child.log-has-the-right-permission.patch new file mode 100644 index 0000000..73cc906 --- /dev/null +++ b/SOURCES/0015-ssh-make-sure-p11_child.log-has-the-right-permission.patch @@ -0,0 +1,40 @@ +From 8119ee216a9471ed2f01b16ed17068f5dc8b83cb Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Mon, 5 Aug 2019 17:04:14 +0200 +Subject: [PATCH 15/16] ssh: make sure p11_child.log has the right permissions + +If SSSD runs a unprivileged user we should make sure the log files for +child processes have the right permission so that the child process can +write to them. + +Related to https://pagure.io/SSSD/sssd/issue/4056 + +Reviewed-by: Jakub Hrozek +--- + src/responder/ssh/sshsrv.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c +index ef2c9d01b..07397834c 100644 +--- a/src/responder/ssh/sshsrv.c ++++ b/src/responder/ssh/sshsrv.c +@@ -187,6 +187,16 @@ int main(int argc, const char *argv[]) + + sss_set_logger(opt_logger); + ++ /* server_setup() might switch to an unprivileged user, so the permissions ++ * for p11_child.log have to be fixed first. We might call p11_child to ++ * validate certificates. */ ++ ret = chown_debug_file("p11_child", uid, gid); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Cannot chown the p11_child debug file, " ++ "debugging might not work!\n"); ++ } ++ + ret = server_setup("sssd[ssh]", 0, uid, gid, + CONFDB_SSH_CONF_ENTRY, &main_ctx); + if (ret != EOK) { +-- +2.20.1 + diff --git a/SOURCES/0016-BE-make-sure-child-log-files-have-the-right-permissi.patch b/SOURCES/0016-BE-make-sure-child-log-files-have-the-right-permissi.patch new file mode 100644 index 0000000..77515ac --- /dev/null +++ b/SOURCES/0016-BE-make-sure-child-log-files-have-the-right-permissi.patch @@ -0,0 +1,61 @@ +From 9339c445b4b98a28146ff834fec2af42bd3a6340 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Mon, 5 Aug 2019 17:05:00 +0200 +Subject: [PATCH 16/16] BE: make sure child log files have the right + permissions + +If SSSD runs a unprivileged user we should make sure the log files for +child processes have the right permission so that the child process can +write to them. + +Related to https://pagure.io/SSSD/sssd/issue/4056 + +Reviewed-by: Jakub Hrozek +--- + src/providers/data_provider_be.c | 23 +++++++++++++++++++++++ + 1 file changed, 23 insertions(+) + +diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c +index 6dce8286d..ce00231ff 100644 +--- a/src/providers/data_provider_be.c ++++ b/src/providers/data_provider_be.c +@@ -554,6 +554,27 @@ done: + return ret; + } + ++static void fix_child_log_permissions(uid_t uid, gid_t gid) ++{ ++ int ret; ++ const char *child_names[] = { "krb5_child", ++ "ldap_child", ++ "selinux_child", ++ "ad_gpo_child", ++ "proxy_child", ++ NULL }; ++ size_t c; ++ ++ for (c = 0; child_names[c] != NULL; c++) { ++ ret = chown_debug_file(child_names[c], uid, gid); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Cannot chown the [%s] debug file, " ++ "debugging might not work!\n", child_names[c]); ++ } ++ } ++} ++ + static void dp_initialized(struct tevent_req *req) + { + struct tevent_signal *tes; +@@ -609,6 +630,8 @@ static void dp_initialized(struct tevent_req *req) + "Cannot chown the debug files, debugging might not work!\n"); + } + ++ fix_child_log_permissions(be_ctx->uid, be_ctx->gid); ++ + ret = become_user(be_ctx->uid, be_ctx->gid); + if (ret != EOK) { + DEBUG(SSSDBG_FUNC_DATA, +-- +2.20.1 + diff --git a/SOURCES/0016-test_ca-test-library-only-for-readable.patch b/SOURCES/0016-test_ca-test-library-only-for-readable.patch deleted file mode 100644 index 6e71fd2..0000000 --- a/SOURCES/0016-test_ca-test-library-only-for-readable.patch +++ /dev/null @@ -1,32 +0,0 @@ -From a29359146455ed7e468a20ce4ad50afbb2b567b5 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 10 Sep 2018 22:03:55 +0200 -Subject: [PATCH 16/19] test_ca: test library only for readable - -On Debian libraries typically do not have the execute-bit set so it is -better to only check for readability. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 91aea762d02731193eb66a00b930ff1fe8bc5ab8) ---- - src/external/test_ca.m4 | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/external/test_ca.m4 b/src/external/test_ca.m4 -index 2cdb3c750cc5b024165a0d4a1a578605792183f7..bb4872698fa291bb651bdf61da1b721cae01bc13 100644 ---- a/src/external/test_ca.m4 -+++ b/src/external/test_ca.m4 -@@ -58,7 +58,7 @@ AC_DEFUN([AM_CHECK_TEST_CA], - AC_MSG_NOTICE([Could not find p11tool]) - fi - -- AM_CONDITIONAL([BUILD_TEST_CA], [test -x "$OPENSSL" -a -x "$SSH_KEYGEN" -a -x "$SOFTHSM2_PATH" -a -x "$SOFTHSM2_UTIL" -a -x "$P11TOOL"]) -+ AM_CONDITIONAL([BUILD_TEST_CA], [test -x "$OPENSSL" -a -x "$SSH_KEYGEN" -a -r "$SOFTHSM2_PATH" -a -x "$SOFTHSM2_UTIL" -a -x "$P11TOOL"]) - fi - - AM_COND_IF([BUILD_TEST_CA], --- -2.14.4 - diff --git a/SOURCES/0017-MAN-Get-rid-of-sssd-secrets-reference.patch b/SOURCES/0017-MAN-Get-rid-of-sssd-secrets-reference.patch new file mode 100644 index 0000000..ca0e6d0 --- /dev/null +++ b/SOURCES/0017-MAN-Get-rid-of-sssd-secrets-reference.patch @@ -0,0 +1,41 @@ +From ca02a20c16a1249a8fcecad31e915bf64df77cc9 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Fri, 5 Oct 2018 13:17:14 +0200 +Subject: [PATCH 17/23] MAN: Get rid of sssd-secrets reference +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Related: +https://pagure.io/SSSD/sssd/issue/3685 + +There were some stray references to the secrets responder in the +sssd-kcm manual page. + +Reviewed-by: Michal Židek +--- + src/man/sssd-kcm.8.xml | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/man/sssd-kcm.8.xml b/src/man/sssd-kcm.8.xml +index fff8b0a16..90b9ad09c 100644 +--- a/src/man/sssd-kcm.8.xml ++++ b/src/man/sssd-kcm.8.xml +@@ -58,11 +58,9 @@ + + + +- the SSSD implementation stores the ccaches in the SSSD +- +- sssd-secrets5 +- +- secrets store, allowing the ccaches to survive KCM server restarts or machine reboots. ++ the SSSD implementation stores the ccaches in a database, ++ typically located at /var/lib/sss/secrets ++ allowing the ccaches to survive KCM server restarts or machine reboots. + + + +-- +2.20.1 + diff --git a/SOURCES/0017-test_ca-set-a-password-PIN-to-nss-databases.patch b/SOURCES/0017-test_ca-set-a-password-PIN-to-nss-databases.patch deleted file mode 100644 index 6df5716..0000000 --- a/SOURCES/0017-test_ca-set-a-password-PIN-to-nss-databases.patch +++ /dev/null @@ -1,58 +0,0 @@ -From fe6b3578e97e44ec92ff6f3f28f97893ed0d41f6 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 7 Sep 2018 22:17:47 +0200 -Subject: [PATCH 17/19] test_ca: set a password/PIN to nss databases - -To make sure the PIN is properly checked during tests the NSS databases -need a password. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit a45a410dc7fa7cf84bcac541e693ee8781e25431) ---- - src/tests/test_CA/Makefile.am | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/src/tests/test_CA/Makefile.am b/src/tests/test_CA/Makefile.am -index 0c7099390f0d0c74a4a22d2b721c0b19a4113190..1bce2c36633b2d1df65c29258f8ee163a4bfce9e 100644 ---- a/src/tests/test_CA/Makefile.am -+++ b/src/tests/test_CA/Makefile.am -@@ -33,7 +33,7 @@ endif - ca_all: clean serial SSSD_test_CA.pem $(certs) $(certs_h) $(pubkeys) $(pubkeys_h) $(pkcs12) $(extra) - - $(pwdfile): -- @echo "12345678" > $@ -+ @echo "123456" > $@ - - SSSD_test_CA.pem: $(openssl_ca_key) $(openssl_ca_config) serial - $(OPENSSL) req -batch -config ${openssl_ca_config} -x509 -new -nodes -key $< -sha256 -days 1024 -set_serial 0 -extensions v3_ca -out $@ -@@ -65,18 +65,18 @@ SSSD_test_cert_pubsshkey_%.h: SSSD_test_cert_pubsshkey_%.pub - # - src/tests/cmocka/test_pam_srv.c - p11_nssdb: SSSD_test_cert_pkcs12_0001.pem SSSD_test_CA.pem $(pwdfile) - mkdir $@ -- $(CERTUTIL) -d sql:./$@ -N --empty-password -- $(CERTUTIL) -d sql:./$@ -A -n 'SSSD test CA' -t CT,CT,CT -a -i SSSD_test_CA.pem -- $(PK12UTIL) -d sql:./$@ -i SSSD_test_cert_pkcs12_0001.pem -w $(pwdfile) -+ $(CERTUTIL) -d sql:./$@ -N -f $(pwdfile) -+ $(CERTUTIL) -d sql:./$@ -A -n 'SSSD test CA' -t CT,CT,CT -a -i SSSD_test_CA.pem -f $(pwdfile) -+ $(PK12UTIL) -d sql:./$@ -i SSSD_test_cert_pkcs12_0001.pem -w $(pwdfile) -k $(pwdfile) - - # This nss db is used in - # - src/tests/cmocka/test_pam_srv.c - p11_nssdb_2certs: SSSD_test_cert_pkcs12_0001.pem SSSD_test_cert_pkcs12_0002.pem SSSD_test_CA.pem $(pwdfile) - mkdir $@ -- $(CERTUTIL) -d sql:./$@ -N --empty-password -- $(CERTUTIL) -d sql:./$@ -A -n 'SSSD test CA' -t CT,CT,CT -a -i SSSD_test_CA.pem -- $(PK12UTIL) -d sql:./$@ p11_nssdb -i SSSD_test_cert_pkcs12_0001.pem -w $(pwdfile) -- $(PK12UTIL) -d sql:./$@ p11_nssdb -i SSSD_test_cert_pkcs12_0002.pem -w $(pwdfile) -+ $(CERTUTIL) -d sql:./$@ -N -f $(pwdfile) -+ $(CERTUTIL) -d sql:./$@ -A -n 'SSSD test CA' -t CT,CT,CT -a -i SSSD_test_CA.pem -f $(pwdfile) -+ $(PK12UTIL) -d sql:./$@ -i SSSD_test_cert_pkcs12_0001.pem -w $(pwdfile) -k $(pwdfile) -+ $(PK12UTIL) -d sql:./$@ -i SSSD_test_cert_pkcs12_0002.pem -w $(pwdfile) -k $(pwdfile) - - # The softhsm2 PKCS#11 setups are used in - # - src/tests/cmocka/test_pam_srv.c --- -2.14.4 - diff --git a/SOURCES/0018-MAN-Document-that-it-is-enough-to-systemctl-restart-.patch b/SOURCES/0018-MAN-Document-that-it-is-enough-to-systemctl-restart-.patch new file mode 100644 index 0000000..5520efa --- /dev/null +++ b/SOURCES/0018-MAN-Document-that-it-is-enough-to-systemctl-restart-.patch @@ -0,0 +1,51 @@ +From 84eca2e812f8a8684a35b4cd0c262660930e0d40 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Fri, 30 Nov 2018 13:15:58 +0100 +Subject: [PATCH 18/23] MAN: Document that it is enough to systemctl restart + sssd-kcm.service lately +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Related: +https://pagure.io/SSSD/sssd/issue/3862 + +We forgot to amend the man page after implementing the sssd-kcm service +reload. + +Reviewed-by: Michal Židek +--- + src/man/sssd-kcm.8.xml | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/src/man/sssd-kcm.8.xml b/src/man/sssd-kcm.8.xml +index 90b9ad09c..4e4aaa38e 100644 +--- a/src/man/sssd-kcm.8.xml ++++ b/src/man/sssd-kcm.8.xml +@@ -162,12 +162,17 @@ systemctl restart sssd-kcm.service + CONFIGURATION OPTIONS + + The KCM service is configured in the kcm +- section of the sssd.conf file. Please note that currently, +- is it not sufficient to restart the sssd-kcm service, because +- the sssd configuration is only parsed and read to an internal +- configuration database by the sssd service. Therefore you +- must restart the sssd service if you change anything in the +- kcm section of sssd.conf. ++ section of the sssd.conf file. Please note that because ++ the KCM service is typically socket-activated, it is ++ enough to just restart the sssd-kcm service ++ after changing options in the kcm section ++ of sssd.conf: ++ ++systemctl restart sssd-kcm.service ++ ++ ++ ++ The KCM service is configured in the kcm + For a detailed syntax reference, refer to the FILE FORMAT section of the + + sssd.conf +-- +2.20.1 + diff --git a/SOURCES/0018-getsockopt_wrapper-add-support-for-PAM-clients.patch b/SOURCES/0018-getsockopt_wrapper-add-support-for-PAM-clients.patch deleted file mode 100644 index c520c4d..0000000 --- a/SOURCES/0018-getsockopt_wrapper-add-support-for-PAM-clients.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 0b519a28b4ed63153adbabb64e1446652bb8b879 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 7 Sep 2018 22:19:26 +0200 -Subject: [PATCH 18/19] getsockopt_wrapper: add support for PAM clients - -PAM clients expect that the private socket of the PAM responder is -handled by root. With this patch getsockopt_wrapper can return the -expected UID and GID to PAM clients. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit d332c8a0e7a4c7f0b3ee1b2110145a23cbd61c2a) ---- - src/tests/intg/getsockopt_wrapper.c | 34 ++++++++++++++++++++++++++++++++++ - 1 file changed, 34 insertions(+) - -diff --git a/src/tests/intg/getsockopt_wrapper.c b/src/tests/intg/getsockopt_wrapper.c -index 510912346709f57e3fffcbc15a684ccb0b2e90bf..2f508892dec1c00dd73c3a9e5cfdb08bb17e48a0 100644 ---- a/src/tests/intg/getsockopt_wrapper.c -+++ b/src/tests/intg/getsockopt_wrapper.c -@@ -45,6 +45,23 @@ static bool is_secrets_socket(int fd) - return NULL != strstr(unix_socket->sun_path, "secrets.socket"); - } - -+static bool peer_is_private_pam(int fd) -+{ -+ int ret; -+ struct sockaddr_storage addr = { 0 }; -+ socklen_t addrlen = sizeof(addr); -+ struct sockaddr_un *unix_socket; -+ -+ ret = getpeername(fd, (struct sockaddr *)&addr, &addrlen); -+ if (ret != 0) return false; -+ -+ if (addr.ss_family != AF_UNIX) return false; -+ -+ unix_socket = (struct sockaddr_un *)&addr; -+ -+ return NULL != strstr(unix_socket->sun_path, "private/pam"); -+} -+ - static uid_t fake_secret_peer(uid_t orig_id) - { - char *val; -@@ -57,6 +74,21 @@ static uid_t fake_secret_peer(uid_t orig_id) - return atoi(val); - } - -+static void fake_peer_uid_gid(uid_t *uid, gid_t *gid) -+{ -+ char *val; -+ -+ val = getenv("SSSD_INTG_PEER_UID"); -+ if (val != NULL) { -+ *uid = atoi(val); -+ } -+ -+ val = getenv("SSSD_INTG_PEER_GID"); -+ if (val != NULL) { -+ *gid = atoi(val); -+ } -+} -+ - typedef typeof(getsockopt) getsockopt_fn_t; - - static getsockopt_fn_t *orig_getsockopt = NULL; -@@ -84,6 +116,8 @@ int getsockopt(int sockfd, int level, int optname, - cr->uid = 0; - } else if (is_secrets_socket(sockfd)) { - cr->uid = fake_secret_peer(cr->uid); -+ } else if (peer_is_private_pam(sockfd)) { -+ fake_peer_uid_gid(&cr->uid, &cr->gid); - } - } - --- -2.14.4 - diff --git a/SOURCES/0019-SECRETS-Use-different-option-names-from-secrets-and-.patch b/SOURCES/0019-SECRETS-Use-different-option-names-from-secrets-and-.patch new file mode 100644 index 0000000..4afec42 --- /dev/null +++ b/SOURCES/0019-SECRETS-Use-different-option-names-from-secrets-and-.patch @@ -0,0 +1,280 @@ +From f74b97860ec7c66df01ed2b719d29a138c958081 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 26 Nov 2018 13:44:08 +0100 +Subject: [PATCH 19/23] SECRETS: Use different option names from secrets and + KCM for quota options +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Related: +https://pagure.io/SSSD/sssd/issue/3386 + +With the separate secrets responder, the quotas for the /secrets and +/kcm hives were configurable in a sub-section of the [secrets] sssd.conf +section using the same option -- the /secrets vs. /kcm distinction was +made using the subsection name. + +With the standalone KCM responder writing directly to the database, it +makes sense to have options with more descriptive names better suitable +for the KCM usage. For that we need the options for secrets quotas and +kcm quotas to be named differently. + +For now, the patch only passes the option name to sss_sec_get_quota() +and sss_sec_get_hive_config() together with the default value in an +instance of a new structure sss_sec_quota_opt. The secrets responder +still uses the same option names for backwards compatibility. + +Reviewed-by: Michal Židek +--- + src/responder/secrets/secsrv.c | 70 ++++++++++++++++++++++++++-------- + src/util/secrets/config.c | 40 +++++++++---------- + src/util/secrets/secrets.h | 21 ++++++---- + 3 files changed, 88 insertions(+), 43 deletions(-) + +diff --git a/src/responder/secrets/secsrv.c b/src/responder/secrets/secsrv.c +index 2de93dedc..e783e231d 100644 +--- a/src/responder/secrets/secsrv.c ++++ b/src/responder/secrets/secsrv.c +@@ -47,6 +47,39 @@ static void adjust_global_quota(struct sec_ctx *sctx, + static int sec_get_config(struct sec_ctx *sctx) + { + int ret; ++ struct sss_sec_quota_opt dfl_sec_nest_level = { ++ .opt_name = CONFDB_SEC_CONTAINERS_NEST_LEVEL, ++ .default_value = DEFAULT_SEC_CONTAINERS_NEST_LEVEL, ++ }; ++ struct sss_sec_quota_opt dfl_sec_max_secrets = { ++ .opt_name = CONFDB_SEC_MAX_SECRETS, ++ .default_value = DEFAULT_SEC_MAX_SECRETS, ++ }; ++ struct sss_sec_quota_opt dfl_sec_max_uid_secrets = { ++ .opt_name = CONFDB_SEC_MAX_UID_SECRETS, ++ .default_value = DEFAULT_SEC_MAX_UID_SECRETS, ++ }; ++ struct sss_sec_quota_opt dfl_sec_max_payload_size = { ++ .opt_name = CONFDB_SEC_MAX_PAYLOAD_SIZE, ++ .default_value = DEFAULT_SEC_MAX_PAYLOAD_SIZE, ++ }; ++ ++ struct sss_sec_quota_opt dfl_kcm_nest_level = { ++ .opt_name = CONFDB_SEC_CONTAINERS_NEST_LEVEL, ++ .default_value = DEFAULT_SEC_CONTAINERS_NEST_LEVEL, ++ }; ++ struct sss_sec_quota_opt dfl_kcm_max_secrets = { ++ .opt_name = CONFDB_SEC_MAX_SECRETS, ++ .default_value = DEFAULT_SEC_KCM_MAX_SECRETS, ++ }; ++ struct sss_sec_quota_opt dfl_kcm_max_uid_secrets = { ++ .opt_name = CONFDB_SEC_MAX_UID_SECRETS, ++ .default_value = DEFAULT_SEC_KCM_MAX_UID_SECRETS, ++ }; ++ struct sss_sec_quota_opt dfl_kcm_max_payload_size = { ++ .opt_name = CONFDB_SEC_MAX_PAYLOAD_SIZE, ++ .default_value = DEFAULT_SEC_KCM_MAX_PAYLOAD_SIZE, ++ }; + + ret = confdb_get_int(sctx->rctx->cdb, + sctx->rctx->confdb_service_path, +@@ -65,15 +98,12 @@ static int sec_get_config(struct sec_ctx *sctx) + sctx->max_payload_size = 1; + + /* Read the global quota first -- this should be removed in a future release */ +- /* Note that this sets the defaults for the sec_config quota to be used +- * in sec_get_hive_config() +- */ + ret = sss_sec_get_quota(sctx->rctx->cdb, + sctx->rctx->confdb_service_path, +- DEFAULT_SEC_CONTAINERS_NEST_LEVEL, +- DEFAULT_SEC_MAX_SECRETS, +- DEFAULT_SEC_MAX_UID_SECRETS, +- DEFAULT_SEC_MAX_PAYLOAD_SIZE, ++ &dfl_sec_nest_level, ++ &dfl_sec_max_secrets, ++ &dfl_sec_max_uid_secrets, ++ &dfl_sec_max_payload_size, + &sctx->sec_config.quota); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, +@@ -81,13 +111,23 @@ static int sec_get_config(struct sec_ctx *sctx) + goto fail; + } + ++ /* Use the global quota values as defaults for the secrets/secrets section */ ++ dfl_sec_nest_level.default_value = \ ++ sctx->sec_config.quota.containers_nest_level; ++ dfl_sec_max_secrets.default_value = \ ++ sctx->sec_config.quota.max_secrets; ++ dfl_sec_max_uid_secrets.default_value = \ ++ sctx->sec_config.quota.max_uid_secrets; ++ dfl_sec_max_payload_size.default_value = \ ++ sctx->sec_config.quota.max_payload_size; ++ + /* Read the per-hive configuration */ + ret = sss_sec_get_hive_config(sctx->rctx->cdb, + "secrets", +- sctx->sec_config.quota.containers_nest_level, +- sctx->sec_config.quota.max_secrets, +- sctx->sec_config.quota.max_uid_secrets, +- sctx->sec_config.quota.max_payload_size, ++ &dfl_sec_nest_level, ++ &dfl_sec_max_secrets, ++ &dfl_sec_max_uid_secrets, ++ &dfl_sec_max_payload_size, + &sctx->sec_config); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, +@@ -98,10 +138,10 @@ static int sec_get_config(struct sec_ctx *sctx) + + ret = sss_sec_get_hive_config(sctx->rctx->cdb, + "kcm", +- DEFAULT_SEC_CONTAINERS_NEST_LEVEL, +- DEFAULT_SEC_KCM_MAX_SECRETS, +- DEFAULT_SEC_KCM_MAX_UID_SECRETS, +- DEFAULT_SEC_KCM_MAX_PAYLOAD_SIZE, ++ &dfl_kcm_nest_level, ++ &dfl_kcm_max_secrets, ++ &dfl_kcm_max_uid_secrets, ++ &dfl_kcm_max_payload_size, + &sctx->kcm_config); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, +diff --git a/src/util/secrets/config.c b/src/util/secrets/config.c +index cb286121f..f5dac0b21 100644 +--- a/src/util/secrets/config.c ++++ b/src/util/secrets/config.c +@@ -24,10 +24,10 @@ + + errno_t sss_sec_get_quota(struct confdb_ctx *cdb, + const char *section_config_path, +- int default_max_containers_nest_level, +- int default_max_num_secrets, +- int default_max_num_uid_secrets, +- int default_max_payload, ++ struct sss_sec_quota_opt *dfl_max_containers_nest_level, ++ struct sss_sec_quota_opt *dfl_max_num_secrets, ++ struct sss_sec_quota_opt *dfl_max_num_uid_secrets, ++ struct sss_sec_quota_opt *dfl_max_payload, + struct sss_sec_quota *quota) + { + int ret; +@@ -38,8 +38,8 @@ errno_t sss_sec_get_quota(struct confdb_ctx *cdb, + + ret = confdb_get_int(cdb, + section_config_path, +- CONFDB_SEC_CONTAINERS_NEST_LEVEL, +- default_max_containers_nest_level, ++ dfl_max_containers_nest_level->opt_name, ++ dfl_max_containers_nest_level->default_value, + "a->containers_nest_level); + + if (ret != EOK) { +@@ -51,8 +51,8 @@ errno_t sss_sec_get_quota(struct confdb_ctx *cdb, + + ret = confdb_get_int(cdb, + section_config_path, +- CONFDB_SEC_MAX_SECRETS, +- default_max_num_secrets, ++ dfl_max_num_secrets->opt_name, ++ dfl_max_num_secrets->default_value, + "a->max_secrets); + + if (ret != EOK) { +@@ -64,8 +64,8 @@ errno_t sss_sec_get_quota(struct confdb_ctx *cdb, + + ret = confdb_get_int(cdb, + section_config_path, +- CONFDB_SEC_MAX_UID_SECRETS, +- default_max_num_uid_secrets, ++ dfl_max_num_uid_secrets->opt_name, ++ dfl_max_num_uid_secrets->default_value, + "a->max_uid_secrets); + + if (ret != EOK) { +@@ -77,8 +77,8 @@ errno_t sss_sec_get_quota(struct confdb_ctx *cdb, + + ret = confdb_get_int(cdb, + section_config_path, +- CONFDB_SEC_MAX_PAYLOAD_SIZE, +- default_max_payload, ++ dfl_max_payload->opt_name, ++ dfl_max_payload->default_value, + "a->max_payload_size); + + if (ret != EOK) { +@@ -93,10 +93,10 @@ errno_t sss_sec_get_quota(struct confdb_ctx *cdb, + + errno_t sss_sec_get_hive_config(struct confdb_ctx *cdb, + const char *hive_name, +- int default_max_containers_nest_level, +- int default_max_num_secrets, +- int default_max_num_uid_secrets, +- int default_max_payload, ++ struct sss_sec_quota_opt *dfl_max_containers_nest_level, ++ struct sss_sec_quota_opt *dfl_max_num_secrets, ++ struct sss_sec_quota_opt *dfl_max_num_uid_secrets, ++ struct sss_sec_quota_opt *dfl_max_payload, + struct sss_sec_hive_config *hive_config) + { + int ret; +@@ -122,10 +122,10 @@ errno_t sss_sec_get_hive_config(struct confdb_ctx *cdb, + + ret = sss_sec_get_quota(cdb, + confdb_section, +- default_max_containers_nest_level, +- default_max_num_secrets, +- default_max_num_uid_secrets, +- default_max_payload, ++ dfl_max_containers_nest_level, ++ dfl_max_num_secrets, ++ dfl_max_num_uid_secrets, ++ dfl_max_payload, + &hive_config->quota); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +diff --git a/src/util/secrets/secrets.h b/src/util/secrets/secrets.h +index 01abfe542..31164bd86 100644 +--- a/src/util/secrets/secrets.h ++++ b/src/util/secrets/secrets.h +@@ -47,6 +47,11 @@ struct sss_sec_ctx; + + struct sss_sec_req; + ++struct sss_sec_quota_opt { ++ const char *opt_name; ++ int default_value; ++}; ++ + struct sss_sec_quota { + int max_secrets; + int max_uid_secrets; +@@ -98,18 +103,18 @@ bool sss_sec_req_is_list(struct sss_sec_req *req); + + errno_t sss_sec_get_quota(struct confdb_ctx *cdb, + const char *section_config_path, +- int default_max_containers_nest_level, +- int default_max_num_secrets, +- int default_max_num_uid_secrets, +- int default_max_payload, ++ struct sss_sec_quota_opt *dfl_max_containers_nest_level, ++ struct sss_sec_quota_opt *dfl_max_num_secrets, ++ struct sss_sec_quota_opt *dfl_max_num_uid_secrets, ++ struct sss_sec_quota_opt *dfl_max_payload, + struct sss_sec_quota *quota); + + errno_t sss_sec_get_hive_config(struct confdb_ctx *cdb, + const char *hive_name, +- int default_max_containers_nest_level, +- int default_max_num_secrets, +- int default_max_num_uid_secrets, +- int default_max_payload, ++ struct sss_sec_quota_opt *dfl_max_containers_nest_level, ++ struct sss_sec_quota_opt *dfl_max_num_secrets, ++ struct sss_sec_quota_opt *dfl_max_num_uid_secrets, ++ struct sss_sec_quota_opt *dfl_max_payload, + struct sss_sec_hive_config *hive_config); + + #endif /* __SECRETS_H_ */ +-- +2.20.1 + diff --git a/SOURCES/0019-intg-add-Smartcard-authentication-tests.patch b/SOURCES/0019-intg-add-Smartcard-authentication-tests.patch deleted file mode 100644 index f7912ec..0000000 --- a/SOURCES/0019-intg-add-Smartcard-authentication-tests.patch +++ /dev/null @@ -1,331 +0,0 @@ -From 6155a267d399d111706c4496c3877e216936c3b2 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 7 Sep 2018 22:26:21 +0200 -Subject: [PATCH 19/19] intg: add Smartcard authentication tests - -Two test for Smartcard authentication of a local user, i.e. a user -managed by the files provider, are added. One for a successful -authentication, the other for a failed authentication with a wrong PIN. - -Related to https://pagure.io/SSSD/sssd/issue/3500 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 657f3b89bca9adfb13f0867c91f1d76845d2d6dd) ---- - configure.ac | 1 + - contrib/ci/deps.sh | 2 + - contrib/sssd.spec.in | 1 + - src/external/cwrap.m4 | 5 ++ - src/external/intgcheck.m4 | 1 + - src/tests/intg/Makefile.am | 24 ++++++- - src/tests/intg/test_pam_responder.py | 131 ++++++++++++++++++++++++++++++++--- - 7 files changed, 155 insertions(+), 10 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 1aac65f4d85b9974adc5ba3e5196b00be5d279f1..891610e14490a4e78e1e95e63c18d9c6a9a8afb4 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -488,6 +488,7 @@ AM_CONDITIONAL([HAVE_CHECK], [test x$have_check != x]) - AM_CHECK_CMOCKA - AM_CHECK_UID_WRAPPER - AM_CHECK_NSS_WRAPPER -+AM_CHECK_PAM_WRAPPER - AM_CHECK_TEST_CA - - # Check if the user wants SSSD to be compiled with systemtap probes -diff --git a/contrib/ci/deps.sh b/contrib/ci/deps.sh -index 5906e5332ba99ce137174f3630e269b8c561f996..c04c7aab03f78185d96000142a71001ab52a66a7 100644 ---- a/contrib/ci/deps.sh -+++ b/contrib/ci/deps.sh -@@ -46,6 +46,7 @@ if [[ "$DISTRO_BRANCH" == -redhat-* ]]; then - pyldb - rpm-build - uid_wrapper -+ pam_wrapper - python-requests - curl-devel - krb5-server -@@ -117,6 +118,7 @@ if [[ "$DISTRO_BRANCH" == -debian-* ]]; then - fakeroot - libnss-wrapper - libuid-wrapper -+ libpam-wrapper - python-pytest - python-ldap - python-ldb -diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in -index 5ebd51f41f60cfdcd1d65c1c58dea4b296fd1ed1..26fae6d68dbe4d14f85ddf34bb4871bc34db3b3d 100644 ---- a/contrib/sssd.spec.in -+++ b/contrib/sssd.spec.in -@@ -237,6 +237,7 @@ BuildRequires: selinux-policy-targeted - BuildRequires: libcmocka-devel >= 1.0.0 - BuildRequires: uid_wrapper - BuildRequires: nss_wrapper -+BuildRequires: pam_wrapper - - # Test CA requires openssl independent if SSSD is build with NSS or openssl, - # openssh is needed for ssh-keygen and NSS builds need nss-tools for certutil. -diff --git a/src/external/cwrap.m4 b/src/external/cwrap.m4 -index b8489cc765f34f3bc6ad4e4b7e69626f6ea8060e..6e3487c13f734e311a2262b0f71495167489c710 100644 ---- a/src/external/cwrap.m4 -+++ b/src/external/cwrap.m4 -@@ -28,3 +28,8 @@ AC_DEFUN([AM_CHECK_NSS_WRAPPER], - [ - AM_CHECK_WRAPPER(nss_wrapper, HAVE_NSS_WRAPPER) - ]) -+ -+AC_DEFUN([AM_CHECK_PAM_WRAPPER], -+[ -+ AM_CHECK_WRAPPER(pam_wrapper, HAVE_PAM_WRAPPER) -+]) -diff --git a/src/external/intgcheck.m4 b/src/external/intgcheck.m4 -index 60a7bf306ddefd748cf9bac62d3767e7512b6d64..c14f66978b8087586cf1c5ac2d60a07e4f90d45d 100644 ---- a/src/external/intgcheck.m4 -+++ b/src/external/intgcheck.m4 -@@ -22,6 +22,7 @@ AC_DEFUN([SSS_ENABLE_INTGCHECK_REQS], [ - if test x"$enable_intgcheck_reqs" = xyes; then - SSS_INTGCHECK_REQ([HAVE_UID_WRAPPER], [uid_wrapper]) - SSS_INTGCHECK_REQ([HAVE_NSS_WRAPPER], [nss_wrapper]) -+ SSS_INTGCHECK_REQ([HAVE_PAM_WRAPPER], [pam_wrapper]) - SSS_INTGCHECK_REQ([HAVE_SLAPD], [slapd]) - SSS_INTGCHECK_REQ([HAVE_LDAPMODIFY], [ldapmodify]) - SSS_INTGCHECK_REQ([HAVE_FAKEROOT], [fakeroot]) -diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am -index 6f7605bd4edbf26ef3ce97acea74fc92216eede9..bb3a7f01ae4f79fa05cd661993e8f9872ecd0450 100644 ---- a/src/tests/intg/Makefile.am -+++ b/src/tests/intg/Makefile.am -@@ -105,13 +105,29 @@ passwd: root - group: - echo "root:x:0:" > $@ - -+PAM_SERVICE_DIR=pam_service_dir -+pam_sss_service: -+ $(MKDIR_P) $(PAM_SERVICE_DIR) -+ echo "auth required $(DESTDIR)$(pammoddir)/pam_sss.so" > $(PAM_SERVICE_DIR)/$@ -+ echo "account required $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@ -+ echo "password required $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@ -+ echo "session required $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@ -+ - CLEANFILES=config.py config.pyc passwd group - - clean-local: - rm -Rf root - rm -f $(builddir)/cwrap-dbus-system.conf - --intgcheck-installed: config.py passwd group -+if HAVE_NSS -+PAM_CERT_DB_PATH="sql:$(DESTDIR)$(sysconfdir)/pki/nssdb" -+SOFTHSM2_CONF="" -+else -+PAM_CERT_DB_PATH="$(abs_builddir)/../test_CA/SSSD_test_CA.pem" -+SOFTHSM2_CONF="$(abs_builddir)/../test_CA/softhsm2_one.conf" -+endif -+ -+intgcheck-installed: config.py passwd group pam_sss_service - pipepath="$(DESTDIR)$(pipepath)"; \ - if test $${#pipepath} -gt 80; then \ - echo "error: Pipe directory path too long," \ -@@ -131,12 +147,18 @@ intgcheck-installed: config.py passwd group - LDB_MODULES_PATH="$(DESTDIR)$(ldblibdir)" \ - NON_WRAPPED_UID=$$(id -u) \ - LD_PRELOAD="$(libdir)/getsockopt_wrapper.so:$$nss_wrapper:$$uid_wrapper" \ -+ LD_LIBRARY_PATH="$$LD_LIBRARY_PATH:$(DESTDIR)$(nsslibdir)" \ - NSS_WRAPPER_PASSWD="$(abs_builddir)/passwd" \ - NSS_WRAPPER_GROUP="$(abs_builddir)/group" \ - NSS_WRAPPER_MODULE_SO_PATH="$(DESTDIR)$(nsslibdir)/libnss_sss.so.2" \ - NSS_WRAPPER_MODULE_FN_PREFIX="sss" \ - UID_WRAPPER=1 \ - UID_WRAPPER_ROOT=1 \ -+ PAM_WRAPPER=0 \ -+ PAM_WRAPPER_SERVICE_DIR="$(abs_builddir)/$(PAM_SERVICE_DIR)" \ -+ PAM_WRAPPER_PATH=$$(pkg-config --libs pam_wrapper) \ -+ PAM_CERT_DB_PATH=$(PAM_CERT_DB_PATH) \ -+ SOFTHSM2_CONF=$(SOFTHSM2_CONF) \ - DBUS_SOCK_DIR="$(DESTDIR)$(runstatedir)/dbus/" \ - DBUS_SESSION_BUS_ADDRESS="unix:path=$$DBUS_SOCK_DIR/fake_socket" \ - DBUS_SYSTEM_BUS_ADDRESS="unix:path=$$DBUS_SOCK_DIR/system_bus_socket" \ -diff --git a/src/tests/intg/test_pam_responder.py b/src/tests/intg/test_pam_responder.py -index cf6fff2db7ba9c9c69e1dd9abe5663a02cedd72e..c6d048cd342838fe312287eaffff734e30ba9e1c 100644 ---- a/src/tests/intg/test_pam_responder.py -+++ b/src/tests/intg/test_pam_responder.py -@@ -27,31 +27,44 @@ import signal - import errno - import subprocess - import time --import pytest -+import shutil - - import config - --from util import unindent -+import pytest - -+from intg.util import unindent -+from intg.files_ops import passwd_ops_setup - --def format_pam_cert_auth_conf(): -+USER1 = dict(name='user1', passwd='x', uid=10001, gid=20001, -+ gecos='User for tests', -+ dir='/home/user1', -+ shell='/bin/bash') -+ -+ -+def format_pam_cert_auth_conf(config): - """Format a basic SSSD configuration""" - return unindent("""\ - [sssd] -+ debug_level = 10 - domains = auth_only -- services = pam -+ services = pam, nss - - [nss] -+ debug_level = 10 - - [pam] - pam_cert_auth = True -+ pam_p11_allowed_services = +pam_sss_service -+ pam_cert_db_path = {config.PAM_CERT_DB_PATH} - debug_level = 10 - - [domain/auth_only] -- id_provider = ldap -- auth_provider = ldap -- chpass_provider = ldap -- access_provider = ldap -+ debug_level = 10 -+ id_provider = files -+ -+ [certmap/auth_only/user1] -+ matchrule = .*CN=SSSD test cert 0001.* - """).format(**locals()) - - -@@ -79,6 +92,8 @@ def create_conf_fixture(request, contents): - - def create_sssd_process(): - """Start the SSSD process""" -+ os.environ["SSS_FILES_PASSWD"] = os.environ["NSS_WRAPPER_PASSWD"] -+ os.environ["SSS_FILES_GROUP"] = os.environ["NSS_WRAPPER_GROUP"] - if subprocess.call(["sssd", "-D", "-f"]) != 0: - raise Exception("sssd start failed") - -@@ -116,12 +131,41 @@ def create_sssd_fixture(request): - request.addfinalizer(cleanup_sssd_process) - - -+def create_nssdb(): -+ os.mkdir(config.SYSCONFDIR + "/pki") -+ os.mkdir(config.SYSCONFDIR + "/pki/nssdb") -+ if subprocess.call(["certutil", "-N", "-d", -+ "sql:" + config.SYSCONFDIR + "/pki/nssdb/", -+ "--empty-password"]) != 0: -+ raise Exception("certutil failed") -+ -+ pkcs11_txt = open(config.SYSCONFDIR + "/pki/nssdb/pkcs11.txt", "w") -+ pkcs11_txt.write("library=libsoftokn3.so\nname=soft\n" + -+ "parameters=configdir='sql:" + config.ABS_BUILDDIR + -+ "/../test_CA/p11_nssdb' " + -+ "dbSlotDescription='SSSD Test Slot' " + -+ "dbTokenDescription='SSSD Test Token' " + -+ "secmod='secmod.db' flags=readOnly)\n\n") -+ pkcs11_txt.close() -+ -+ -+def cleanup_nssdb(): -+ shutil.rmtree(config.SYSCONFDIR + "/pki") -+ -+ -+def create_nssdb_fixture(request): -+ create_nssdb() -+ request.addfinalizer(cleanup_nssdb) -+ -+ - @pytest.fixture - def simple_pam_cert_auth(request): - """Setup SSSD with pam_cert_auth=True""" -- conf = format_pam_cert_auth_conf() -+ config.PAM_CERT_DB_PATH = os.environ['PAM_CERT_DB_PATH'] -+ conf = format_pam_cert_auth_conf(config) - create_conf_fixture(request, conf) - create_sssd_fixture(request) -+ create_nssdb_fixture(request) - return None - - -@@ -129,3 +173,72 @@ def test_preauth_indicator(simple_pam_cert_auth): - """Check if preauth indicator file is created""" - statinfo = os.stat(config.PUBCONF_PATH + "/pam_preauth_available") - assert stat.S_ISREG(statinfo.st_mode) -+ -+ -+@pytest.fixture -+def pam_wrapper_setup(request): -+ pwrap_runtimedir = os.getenv("PAM_WRAPPER_SERVICE_DIR") -+ if pwrap_runtimedir is None: -+ raise ValueError("The PAM_WRAPPER_SERVICE_DIR variable is unset\n") -+ -+ -+def test_sc_auth_wrong_pin(simple_pam_cert_auth, pam_wrapper_setup, -+ passwd_ops_setup): -+ -+ passwd_ops_setup.useradd(**USER1) -+ current_env = os.environ.copy() -+ current_env['PAM_WRAPPER'] = "1" -+ current_env['SSSD_INTG_PEER_UID'] = "0" -+ current_env['SSSD_INTG_PEER_GID'] = "0" -+ current_env['LD_PRELOAD'] += ':' + os.environ['PAM_WRAPPER_PATH'] -+ -+ sssctl = subprocess.Popen(["sssctl", "user-checks", "user1", -+ "--action=auth", "--service=pam_sss_service"], -+ universal_newlines=True, -+ env=current_env, stdin=subprocess.PIPE, -+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ -+ try: -+ out, err = sssctl.communicate(input="111") -+ except: -+ sssctl.kill() -+ out, err = sssctl.communicate() -+ -+ sssctl.stdin.close() -+ sssctl.stdout.close() -+ -+ if sssctl.wait() != 0: -+ raise Exception("sssctl failed") -+ -+ assert err.find("pam_authenticate for user [user1]: " + -+ "Authentication failure") != -1 -+ -+ -+def test_sc_auth(simple_pam_cert_auth, pam_wrapper_setup, passwd_ops_setup): -+ -+ passwd_ops_setup.useradd(**USER1) -+ current_env = os.environ.copy() -+ current_env['PAM_WRAPPER'] = "1" -+ current_env['SSSD_INTG_PEER_UID'] = "0" -+ current_env['SSSD_INTG_PEER_GID'] = "0" -+ current_env['LD_PRELOAD'] += ':' + os.environ['PAM_WRAPPER_PATH'] -+ -+ sssctl = subprocess.Popen(["sssctl", "user-checks", "user1", -+ "--action=auth", "--service=pam_sss_service"], -+ universal_newlines=True, -+ env=current_env, stdin=subprocess.PIPE, -+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ -+ try: -+ out, err = sssctl.communicate(input="123456") -+ except: -+ sssctl.kill() -+ out, err = sssctl.communicate() -+ -+ sssctl.stdin.close() -+ sssctl.stdout.close() -+ -+ if sssctl.wait() != 0: -+ raise Exception("sssctl failed") -+ -+ assert err.find("pam_authenticate for user [user1]: Success") != -1 --- -2.14.4 - diff --git a/SOURCES/0020-SECRETS-Don-t-limit-the-global-number-of-ccaches.patch b/SOURCES/0020-SECRETS-Don-t-limit-the-global-number-of-ccaches.patch new file mode 100644 index 0000000..a05c43e --- /dev/null +++ b/SOURCES/0020-SECRETS-Don-t-limit-the-global-number-of-ccaches.patch @@ -0,0 +1,51 @@ +From 940002ca21abde53ad81df622d1f4dd3b5e8e014 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Fri, 30 Nov 2018 13:34:22 +0100 +Subject: [PATCH 20/23] SECRETS: Don't limit the global number of ccaches +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Related: +https://pagure.io/SSSD/sssd/issue/3386 + +In the KCM context, the global number of ccaches would limit the number +of users who can store their ccaches in the KCM deamon. + +In more detail, the options have the following semantics with KCM: + - DEFAULT_SEC_KCM_MAX_SECRETS - global number of secrets, would + cover both how many ccaches can a user store, but this is better + served with DEFAULT_SEC_KCM_MAX_UID_SECRETS + + - DEFAULT_SEC_KCM_MAX_UID_SECRETS - how many 'principals' can a user + kinit with + + - DEFAULT_SEC_KCM_MAX_PAYLOAD_SIZE - the payload size of service + tickets + +With the above in mind, I think the most important limits are +max_uid_secrets to limit and the payload size to constraint how much +space can a user occupy and it doesn't make much sense to limit the +global quota. + +Reviewed-by: Michal Židek +--- + src/util/secrets/secrets.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/secrets/secrets.h b/src/util/secrets/secrets.h +index 31164bd86..9cf397516 100644 +--- a/src/util/secrets/secrets.h ++++ b/src/util/secrets/secrets.h +@@ -39,7 +39,7 @@ + * but the secret size must be large because one secret in the /kcm + * hive holds the whole ccache which consists of several credentials + */ +-#define DEFAULT_SEC_KCM_MAX_SECRETS 256 ++#define DEFAULT_SEC_KCM_MAX_SECRETS 0 /* unlimited */ + #define DEFAULT_SEC_KCM_MAX_UID_SECRETS 64 + #define DEFAULT_SEC_KCM_MAX_PAYLOAD_SIZE 65536 + +-- +2.20.1 + diff --git a/SOURCES/0020-sbus-dectect-python-binary-for-sbus_generate.sh.patch b/SOURCES/0020-sbus-dectect-python-binary-for-sbus_generate.sh.patch deleted file mode 100644 index bd0e5ee..0000000 --- a/SOURCES/0020-sbus-dectect-python-binary-for-sbus_generate.sh.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 8b43e5149d9726de3a573ba8b4e44fd68b328f92 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 10 Sep 2018 15:40:14 +0200 -Subject: [PATCH] sbus: dectect python binary for sbus_generate.sh -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We already detect python2 and python3 binaries during configure. With -this patch PYTHON_EXEC is set to the python3 binary if python3 bindings -are generated and to the python2 binary otherwise. With the help of an -environment variable sbus_generate.sh is made aware of it. - -Related to https://pagure.io/SSSD/sssd/issue/3807 - -Reviewed-by: Pavel Březina -(cherry picked from commit b03179ead11db7dbfd6a00d3eeef3dac0990f826) ---- - Makefile.am | 4 ++-- - configure.ac | 8 ++++++++ - sbus_generate.sh => sbus_generate.sh.in | 2 +- - 3 files changed, 11 insertions(+), 3 deletions(-) - rename sbus_generate.sh => sbus_generate.sh.in (93%) - -diff --git a/Makefile.am b/Makefile.am -index 85952818c9a8efd957ce99f4595b251265cc5417..1602ec6236799015fa7fd9f1707cb2bcdb20e07b 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1019,14 +1019,14 @@ libsss_cert_la_LDFLAGS = \ - $(NULL) - - generate-sbus-code: -- $(srcdir)/sbus_generate.sh $(abs_srcdir) -+ $(builddir)/sbus_generate.sh $(abs_srcdir) - - .PHONY: generate-sbus-code - - BUILT_SOURCES += generate-sbus-code - - EXTRA_DIST += \ -- sbus_generate.sh \ -+ sbus_generate.sh.in \ - src/sbus/codegen/dbus.xml \ - src/sbus/codegen/sbus_CodeGen.py \ - src/sbus/codegen/sbus_DataType.py \ -diff --git a/configure.ac b/configure.ac -index 891610e14490a4e78e1e95e63c18d9c6a9a8afb4..5816b04c6651ee9cd4ddfae9a1cb0ab44f3ea4e0 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -373,6 +373,13 @@ them please use argument --without-python3-bindings when running configure.])]) - SSS_CLEAN_PYTHON_VARIABLES - fi - -+if test x$HAVE_PYTHON3_BINDINGS = x1; then -+ PYTHON_EXEC=$PYTHON3 -+else -+ PYTHON_EXEC=$PYTHON2 -+fi -+AC_SUBST(PYTHON_EXEC) -+ - AM_CONDITIONAL([BUILD_PYTHON_BINDINGS], - [test x"$with_python2_bindings" = xyes \ - -o x"$with_python3_bindings" = xyes]) -@@ -525,4 +532,5 @@ AC_CONFIG_FILES([Makefile contrib/sssd.spec src/examples/rwtab src/doxy.config - src/config/setup.py - src/systemtap/sssd.stp - src/config/SSSDConfig/__init__.py]) -+AC_CONFIG_FILES([sbus_generate.sh], [chmod +x sbus_generate.sh]) - AC_OUTPUT -diff --git a/sbus_generate.sh b/sbus_generate.sh.in -similarity index 93% -rename from sbus_generate.sh -rename to sbus_generate.sh.in -index 338fd9d3387d6d4694e08de3d537d6a54e78a560..b2c695e700901bcff77ebbe2d1887cd572ec5e52 100755 ---- a/sbus_generate.sh -+++ b/sbus_generate.sh.in -@@ -13,7 +13,7 @@ generate() { - - echo "Generating sbus code for: $XML" - -- python $CODEGEN --sbus sbus --util util \ -+ @PYTHON_EXEC@ $CODEGEN --sbus sbus --util util \ - --headers "$HEADERS" \ - --dest "$SRCDIR/src/$DEST" \ - --fileprefix "sbus_${PREFIX}_" \ --- -2.14.4 - diff --git a/SOURCES/0021-CONFDB-Skip-local-domain-if-not-supported.patch b/SOURCES/0021-CONFDB-Skip-local-domain-if-not-supported.patch deleted file mode 100644 index 1f608ec..0000000 --- a/SOURCES/0021-CONFDB-Skip-local-domain-if-not-supported.patch +++ /dev/null @@ -1,42 +0,0 @@ -From fea818f425178931cce9cbaccae9070e462d5659 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michal=20=C5=BDidek?= -Date: Tue, 18 Sep 2018 15:23:54 +0200 -Subject: [PATCH] CONFDB: Skip 'local' domain if not supported - -When SSSD is built without the support for local -domain, we should gracegully skip local domains -and let other domains start. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3828 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 10fa27eddb9bbe135277d587c6a2de4b311da6df) ---- - src/confdb/confdb.c | 10 ++++++++-- - 1 file changed, 8 insertions(+), 2 deletions(-) - -diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c -index 6370a0411d98b6611dd384e9ab0de1d580be9c2d..954c3ba766617f7cfcf637d9143c891bd998d7ff 100644 ---- a/src/confdb/confdb.c -+++ b/src/confdb/confdb.c -@@ -945,8 +945,14 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb, - goto done; - } - -- if (local_provider_is_built() -- && strcasecmp(domain->provider, "local") == 0) { -+ if (strcasecmp(domain->provider, "local") == 0) { -+ if (!local_provider_is_built()) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "ID provider 'local' no longer supported, disabling\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ - /* If this is the local provider, we need to ensure that - * no other provider was specified for other types, since - * the local provider cannot load them. --- -2.14.4 - diff --git a/SOURCES/0021-KCM-Pass-confdb-context-to-the-ccache-db-initializat.patch b/SOURCES/0021-KCM-Pass-confdb-context-to-the-ccache-db-initializat.patch new file mode 100644 index 0000000..964b175 --- /dev/null +++ b/SOURCES/0021-KCM-Pass-confdb-context-to-the-ccache-db-initializat.patch @@ -0,0 +1,176 @@ +From f00db73d7bbf312e3e2a772b8b10895d5460b989 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 28 Nov 2018 21:24:08 +0100 +Subject: [PATCH 21/23] KCM: Pass confdb context to the ccache db + initialization +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Resolves: +https://pagure.io/SSSD/sssd/issue/3386 + +The libsecrets back end needs to read the quota options from confdb, +therefore it needs to know the section and access the confdb handle. + +These parameters are unused for other ccache back end types, but they +are harmless and IMO it makes more sense to keep the ccache back end +abstract. + +Reviewed-by: Michal Židek +--- + src/responder/kcm/kcm.c | 14 ++++++++++++-- + src/responder/kcm/kcmsrv_ccache.c | 4 +++- + src/responder/kcm/kcmsrv_ccache.h | 2 ++ + src/responder/kcm/kcmsrv_ccache_be.h | 4 +++- + src/responder/kcm/kcmsrv_ccache_mem.c | 4 +++- + src/responder/kcm/kcmsrv_ccache_secdb.c | 6 +++--- + src/responder/kcm/kcmsrv_ccache_secrets.c | 4 +++- + 7 files changed, 29 insertions(+), 9 deletions(-) + +diff --git a/src/responder/kcm/kcm.c b/src/responder/kcm/kcm.c +index 005dd168f..045c7801f 100644 +--- a/src/responder/kcm/kcm.c ++++ b/src/responder/kcm/kcm.c +@@ -170,6 +170,8 @@ static int kcm_data_destructor(void *ptr) + + static struct kcm_resp_ctx *kcm_data_setup(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, ++ struct confdb_ctx *cdb, ++ const char *confdb_service_path, + enum kcm_ccdb_be cc_be) + { + struct kcm_resp_ctx *kcm_data; +@@ -181,7 +183,11 @@ static struct kcm_resp_ctx *kcm_data_setup(TALLOC_CTX *mem_ctx, + return NULL; + } + +- kcm_data->db = kcm_ccdb_init(kcm_data, ev, cc_be); ++ kcm_data->db = kcm_ccdb_init(kcm_data, ++ ev, ++ cdb, ++ confdb_service_path, ++ cc_be); + if (kcm_data->db == NULL) { + talloc_free(kcm_data); + return NULL; +@@ -235,7 +241,11 @@ static int kcm_process_init(TALLOC_CTX *mem_ctx, + goto fail; + } + +- kctx->kcm_data = kcm_data_setup(kctx, ev, kctx->cc_be); ++ kctx->kcm_data = kcm_data_setup(kctx, ++ ev, ++ kctx->rctx->cdb, ++ kctx->rctx->confdb_service_path, ++ kctx->cc_be); + if (kctx->kcm_data == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, + "fatal error initializing responder data\n"); +diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c +index e7800662a..085cc4464 100644 +--- a/src/responder/kcm/kcmsrv_ccache.c ++++ b/src/responder/kcm/kcmsrv_ccache.c +@@ -229,6 +229,8 @@ struct sss_iobuf *kcm_cred_get_creds(struct kcm_cred *crd) + + struct kcm_ccdb *kcm_ccdb_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, ++ struct confdb_ctx *cdb, ++ const char *confdb_service_path, + enum kcm_ccdb_be cc_be) + { + errno_t ret; +@@ -270,7 +272,7 @@ struct kcm_ccdb *kcm_ccdb_init(TALLOC_CTX *mem_ctx, + return NULL; + } + +- ret = ccdb->ops->init(ccdb); ++ ret = ccdb->ops->init(ccdb, cdb, confdb_service_path); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot initialize ccache database\n"); + talloc_free(ccdb); +diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h +index 0fd33325f..199b75b16 100644 +--- a/src/responder/kcm/kcmsrv_ccache.h ++++ b/src/responder/kcm/kcmsrv_ccache.h +@@ -125,6 +125,8 @@ struct kcm_ccdb; + */ + struct kcm_ccdb *kcm_ccdb_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, ++ struct confdb_ctx *cdb, ++ const char *confdb_service_path, + enum kcm_ccdb_be cc_be); + + /* +diff --git a/src/responder/kcm/kcmsrv_ccache_be.h b/src/responder/kcm/kcmsrv_ccache_be.h +index 7315f6435..166af3a76 100644 +--- a/src/responder/kcm/kcmsrv_ccache_be.h ++++ b/src/responder/kcm/kcmsrv_ccache_be.h +@@ -30,7 +30,9 @@ + #include "responder/kcm/kcmsrv_ccache.h" + + typedef errno_t +-(*ccdb_init_fn)(struct kcm_ccdb *db); ++(*ccdb_init_fn)(struct kcm_ccdb *db, ++ struct confdb_ctx *cdb, ++ const char *confdb_service_path); + + typedef struct tevent_req * + (*ccdb_nextid_send_fn)(TALLOC_CTX *mem_ctx, +diff --git a/src/responder/kcm/kcmsrv_ccache_mem.c b/src/responder/kcm/kcmsrv_ccache_mem.c +index 38bc2050d..35955b2f4 100644 +--- a/src/responder/kcm/kcmsrv_ccache_mem.c ++++ b/src/responder/kcm/kcmsrv_ccache_mem.c +@@ -151,7 +151,9 @@ static int ccwrap_destructor(void *ptr) + return 0; + } + +-static errno_t ccdb_mem_init(struct kcm_ccdb *db) ++static errno_t ccdb_mem_init(struct kcm_ccdb *db, ++ struct confdb_ctx *cdb, ++ const char *confdb_service_path) + { + struct ccdb_mem *memdb = NULL; + +diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c +index c68f53f97..d0d9a7e4c 100644 +--- a/src/responder/kcm/kcmsrv_ccache_secdb.c ++++ b/src/responder/kcm/kcmsrv_ccache_secdb.c +@@ -520,7 +520,9 @@ done: + return ret; + } + +-static errno_t ccdb_secdb_init(struct kcm_ccdb *db) ++static errno_t ccdb_secdb_init(struct kcm_ccdb *db, ++ struct confdb_ctx *cdb, ++ const char *confdb_service_path) + { + struct ccdb_secdb *secdb = NULL; + errno_t ret; +@@ -530,8 +532,6 @@ static errno_t ccdb_secdb_init(struct kcm_ccdb *db) + return ENOMEM; + } + +- /* TODO: read configuration from the config file, adjust quotas */ +- + ret = sss_sec_init(db, NULL, &secdb->sctx); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, +diff --git a/src/responder/kcm/kcmsrv_ccache_secrets.c b/src/responder/kcm/kcmsrv_ccache_secrets.c +index 93be4fafa..6fa2a6dcc 100644 +--- a/src/responder/kcm/kcmsrv_ccache_secrets.c ++++ b/src/responder/kcm/kcmsrv_ccache_secrets.c +@@ -659,7 +659,9 @@ static errno_t sec_get_ccache_recv(struct tevent_req *req, + /* + * The actual sssd-secrets back end + */ +-static errno_t ccdb_sec_init(struct kcm_ccdb *db) ++static errno_t ccdb_sec_init(struct kcm_ccdb *db, ++ struct confdb_ctx *cdb, ++ const char *confdb_service_path) + { + struct ccdb_sec *secdb = NULL; + +-- +2.20.1 + diff --git a/SOURCES/0022-KCM-Configurable-quotas-for-the-secdb-ccache-back-en.patch b/SOURCES/0022-KCM-Configurable-quotas-for-the-secdb-ccache-back-en.patch new file mode 100644 index 0000000..495e3e2 --- /dev/null +++ b/SOURCES/0022-KCM-Configurable-quotas-for-the-secdb-ccache-back-en.patch @@ -0,0 +1,179 @@ +From f024b5e46b62ad49f0099ed8db8155e7ea475639 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 28 Nov 2018 21:22:22 +0100 +Subject: [PATCH 22/23] KCM: Configurable quotas for the secdb ccache back end +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Related: +https://pagure.io/SSSD/sssd/issue/3386 + +Exposes three new options for the [kcm] responder to set the global +ccache limit, the per-uid ccache limit and the payload size. + +Reviewed-by: Michal Židek +--- + src/confdb/confdb.h | 3 ++ + src/config/cfg_rules.ini | 3 ++ + src/man/sssd-kcm.8.xml | 37 +++++++++++++++ + src/responder/kcm/kcmsrv_ccache_secdb.c | 61 ++++++++++++++++++++++++- + 4 files changed, 103 insertions(+), 1 deletion(-) + +diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h +index d09d6b4c3..727841659 100644 +--- a/src/confdb/confdb.h ++++ b/src/confdb/confdb.h +@@ -266,6 +266,9 @@ + #define CONFDB_KCM_CONF_ENTRY "config/kcm" + #define CONFDB_KCM_SOCKET "socket_path" + #define CONFDB_KCM_DB "ccache_storage" /* Undocumented on purpose */ ++#define CONFDB_KCM_MAX_CCACHES "max_ccaches" ++#define CONFDB_KCM_MAX_UID_CCACHES "max_uid_ccaches" ++#define CONFDB_KCM_MAX_CCACHE_SIZE "max_ccache_size" + + /* Certificate mapping rules */ + #define CONFDB_CERTMAP_BASEDN "cn=certmap,cn=config" +diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini +index 30040b595..59d6cc512 100644 +--- a/src/config/cfg_rules.ini ++++ b/src/config/cfg_rules.ini +@@ -312,6 +312,9 @@ option = description + option = socket_path + option = ccache_storage + option = responder_idle_timeout ++option = max_ccaches ++option = max_uid_ccaches ++option = max_ccache_size + + # Session recording + [rule/allowed_session_recording_options] +diff --git a/src/man/sssd-kcm.8.xml b/src/man/sssd-kcm.8.xml +index 4e4aaa38e..2f66e56a4 100644 +--- a/src/man/sssd-kcm.8.xml ++++ b/src/man/sssd-kcm.8.xml +@@ -201,6 +201,43 @@ systemctl restart sssd-kcm.service + + + ++ ++ max_ccaches (integer) ++ ++ ++ How many credential caches does the KCM database allow ++ for all users. ++ ++ ++ Default: 0 (unlimited, only the per-UID quota is enforced) ++ ++ ++ ++ ++ max_uid_ccaches (integer) ++ ++ ++ How many credential caches does the KCM database allow ++ per UID. This is equivalent to with how many ++ principals you can kinit. ++ ++ ++ Default: 64 ++ ++ ++ ++ ++ max_ccache_size (integer) ++ ++ ++ How big can a credential cache be per ccache. Each ++ service ticket accounts into this quota. ++ ++ ++ Default: 65536 ++ ++ ++ + + + +diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c +index d0d9a7e4c..dc9cefb32 100644 +--- a/src/responder/kcm/kcmsrv_ccache_secdb.c ++++ b/src/responder/kcm/kcmsrv_ccache_secdb.c +@@ -526,13 +526,72 @@ static errno_t ccdb_secdb_init(struct kcm_ccdb *db, + { + struct ccdb_secdb *secdb = NULL; + errno_t ret; ++ struct sss_sec_hive_config **kcm_section_quota; ++ struct sss_sec_quota_opt dfl_kcm_nest_level = { ++ .opt_name = CONFDB_SEC_CONTAINERS_NEST_LEVEL, ++ .default_value = DEFAULT_SEC_CONTAINERS_NEST_LEVEL, ++ }; ++ struct sss_sec_quota_opt dfl_kcm_max_secrets = { ++ .opt_name = CONFDB_KCM_MAX_CCACHES, ++ .default_value = DEFAULT_SEC_KCM_MAX_SECRETS, ++ }; ++ struct sss_sec_quota_opt dfl_kcm_max_uid_secrets = { ++ .opt_name = CONFDB_KCM_MAX_UID_CCACHES, ++ .default_value = DEFAULT_SEC_KCM_MAX_UID_SECRETS, ++ }; ++ struct sss_sec_quota_opt dfl_kcm_max_payload_size = { ++ .opt_name = CONFDB_KCM_MAX_CCACHE_SIZE, ++ .default_value = DEFAULT_SEC_KCM_MAX_PAYLOAD_SIZE, ++ }; ++ + + secdb = talloc_zero(db, struct ccdb_secdb); + if (secdb == NULL) { + return ENOMEM; + } + +- ret = sss_sec_init(db, NULL, &secdb->sctx); ++ kcm_section_quota = talloc_zero_array(secdb, ++ struct sss_sec_hive_config *, ++ 2); ++ if (kcm_section_quota == NULL) { ++ talloc_free(secdb); ++ return ENOMEM; ++ } ++ ++ kcm_section_quota[0] = talloc_zero(kcm_section_quota, ++ struct sss_sec_hive_config); ++ if (kcm_section_quota == NULL) { ++ talloc_free(secdb); ++ return ENOMEM; ++ } ++ kcm_section_quota[0]->hive_name = "kcm"; ++ ++ ret = sss_sec_get_quota(cdb, ++ confdb_service_path, ++ &dfl_kcm_nest_level, ++ &dfl_kcm_max_secrets, ++ &dfl_kcm_max_uid_secrets, ++ &dfl_kcm_max_payload_size, ++ &kcm_section_quota[0]->quota); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_FATAL_FAILURE, ++ "Failed to get KCM global quotas [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ talloc_free(secdb); ++ return ret; ++ } ++ ++ if (kcm_section_quota[0]->quota.max_uid_secrets > 0) { ++ /* Even cn=default is considered a secret that adds up to ++ * the quota. To avoid off-by-one-confusion, increase ++ * the quota by two to 1) account for the cn=default object ++ * and 2) always allow writing to cn=defaults even if we ++ * are exactly at the quota limit ++ */ ++ kcm_section_quota[0]->quota.max_uid_secrets += 2; ++ } ++ ++ ret = sss_sec_init(db, kcm_section_quota, &secdb->sctx); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Cannot initialize the security database\n"); +-- +2.20.1 + diff --git a/SOURCES/0022-SELINUX-Always-add-SELinux-user-to-the-semanage-data.patch b/SOURCES/0022-SELINUX-Always-add-SELinux-user-to-the-semanage-data.patch deleted file mode 100644 index 3b1da28..0000000 --- a/SOURCES/0022-SELINUX-Always-add-SELinux-user-to-the-semanage-data.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 06c13c32faff1d9dcb5156f496a4848bfe1f1462 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Thu, 23 Aug 2018 13:55:51 +0200 -Subject: [PATCH 22/28] SELINUX: Always add SELinux user to the semanage - database if it doesn't exist -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Previously, we tried to optimize too much and only set the SELinux user -to Linux user mapping in case the SELinux user was different from the -system default. But this doesn't work for the case where the Linux user -has a non-standard home directory, because then SELinux would not have -any idea that this user's home directory should be labeled as a home -directory. - -This patch relaxes the optimization in the sense that on the first -login, the SELinux context is saved regardless of whether it is the same -as the default or different. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3819 - -Reviewed-by: Michal Židek -(cherry picked from commit 945865ae16120ffade267227ca48cefd58822fd2) ---- - src/providers/ipa/selinux_child.c | 10 ++++++++-- - src/util/sss_semanage.c | 30 ++++++++++++++++++++++++++++++ - src/util/util.h | 1 + - src/util/util_errors.c | 1 + - src/util/util_errors.h | 1 + - 5 files changed, 41 insertions(+), 2 deletions(-) - -diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c -index d061417a5a30aacb231d973fa1aa7ddab869fc51..925591ec902d3b6f3b687fcb4a5f160b1b1d9a8d 100644 ---- a/src/providers/ipa/selinux_child.c -+++ b/src/providers/ipa/selinux_child.c -@@ -176,13 +176,16 @@ static bool seuser_needs_update(const char *username, - - ret = sss_get_seuser(username, &db_seuser, &db_mls_range); - DEBUG(SSSDBG_TRACE_INTERNAL, -- "getseuserbyname: ret: %d seuser: %s mls: %s\n", -+ "sss_get_seuser: ret: %d seuser: %s mls: %s\n", - ret, db_seuser ? db_seuser : "unknown", - db_mls_range ? db_mls_range : "unknown"); - if (ret == EOK && db_seuser && db_mls_range && - strcmp(db_seuser, seuser) == 0 && - strcmp(db_mls_range, mls_range) == 0) { -- needs_update = false; -+ ret = sss_seuser_exists(username); -+ if (ret == EOK) { -+ needs_update = false; -+ } - } - /* OR */ - if (ret == ERR_SELINUX_NOT_MANAGED) { -@@ -191,6 +194,9 @@ static bool seuser_needs_update(const char *username, - - free(db_seuser); - free(db_mls_range); -+ DEBUG(SSSDBG_TRACE_FUNC, -+ "The SELinux user does %sneed an update\n", -+ needs_update ? "" : "not "); - return needs_update; - } - -diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c -index bcce57b603bd1c4d5c6465dbb5cc7a3fbe72412d..aea03852ac07dd344b6170d7ec2a030f30e0f202 100644 ---- a/src/util/sss_semanage.c -+++ b/src/util/sss_semanage.c -@@ -248,6 +248,36 @@ done: - return ret; - } - -+int sss_seuser_exists(const char *linuxuser) -+{ -+ int ret; -+ int exists; -+ semanage_seuser_key_t *sm_key = NULL; -+ semanage_handle_t *sm_handle = NULL; -+ -+ ret = sss_semanage_init(&sm_handle); -+ if (ret != EOK) { -+ return ret; -+ } -+ -+ ret = semanage_seuser_key_create(sm_handle, linuxuser, &sm_key); -+ if (ret < 0) { -+ sss_semanage_close(sm_handle); -+ return EIO; -+ } -+ -+ ret = semanage_seuser_exists(sm_handle, sm_key, &exists); -+ semanage_seuser_key_free(sm_key); -+ sss_semanage_close(sm_handle); -+ if (ret < 0) { -+ return EIO; -+ } -+ -+ DEBUG(SSSDBG_TRACE_FUNC, "seuser exists: %s\n", exists ? "yes" : "no"); -+ -+ return exists ? EOK : ERR_SELINUX_USER_NOT_FOUND; -+} -+ - int sss_get_seuser(const char *linuxuser, - char **selinuxuser, - char **level) -diff --git a/src/util/util.h b/src/util/util.h -index 867acf26fff18becb01397697ea6dde2961d9ece..59e7a96ba58aa9400166514064922d25fb713deb 100644 ---- a/src/util/util.h -+++ b/src/util/util.h -@@ -663,6 +663,7 @@ int sss_del_seuser(const char *login_name); - int sss_get_seuser(const char *linuxuser, - char **selinuxuser, - char **level); -+int sss_seuser_exists(const char *linuxuser); - - /* convert time from generalized form to unix time */ - errno_t sss_utc_to_time_t(const char *str, const char *format, time_t *unix_time); -diff --git a/src/util/util_errors.c b/src/util/util_errors.c -index 920a178615bef081c9fd035570e661ba6438350a..5f8a2a29ab5af44432c01a85c02f61ece3cdc8b5 100644 ---- a/src/util/util_errors.c -+++ b/src/util/util_errors.c -@@ -75,6 +75,7 @@ struct err_string error_to_str[] = { - { "LDAP search returned a referral" }, /* ERR_REFERRAL */ - { "Error setting SELinux user context" }, /* ERR_SELINUX_CONTEXT */ - { "SELinux is not managed by libsemanage" }, /* ERR_SELINUX_NOT_MANAGED */ -+ { "SELinux user does not exist" }, /* ERR_SELINUX_USER_NOT_FOUND */ - { "Username format not allowed by re_expression" }, /* ERR_REGEX_NOMATCH */ - { "Time specification not supported" }, /* ERR_TIMESPEC_NOT_SUPPORTED */ - { "Invalid SSSD configuration detected" }, /* ERR_INVALID_CONFIG */ -diff --git a/src/util/util_errors.h b/src/util/util_errors.h -index 5a509362616248ec3f688e28996ec4b6e25ee131..c6731d4f999bdadcef2bb65a6be199d0db009674 100644 ---- a/src/util/util_errors.h -+++ b/src/util/util_errors.h -@@ -97,6 +97,7 @@ enum sssd_errors { - ERR_REFERRAL, - ERR_SELINUX_CONTEXT, - ERR_SELINUX_NOT_MANAGED, -+ ERR_SELINUX_USER_NOT_FOUND, - ERR_REGEX_NOMATCH, - ERR_TIMESPEC_NOT_SUPPORTED, - ERR_INVALID_CONFIG, --- -2.14.4 diff --git a/SOURCES/0023-MAN-Document-that-PAM-stack-contains-the-systemd-use.patch b/SOURCES/0023-MAN-Document-that-PAM-stack-contains-the-systemd-use.patch new file mode 100644 index 0000000..24d44c3 --- /dev/null +++ b/SOURCES/0023-MAN-Document-that-PAM-stack-contains-the-systemd-use.patch @@ -0,0 +1,36 @@ +From 820151f3813f08c704cb87a99988fe39f9f48a8d Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Thu, 4 Jul 2019 10:22:25 +0200 +Subject: [PATCH] MAN: Document that PAM stack contains the systemd-user + service in the account phase in RHEL-8 + +Resolves: +https://pagure.io/SSSD/sssd/issue/3932 + +Reviewed-by: Tomas Halman +--- + src/man/sssd-ldap.5.xml | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml +index c205aea64..aca0f9e72 100644 +--- a/src/man/sssd-ldap.5.xml ++++ b/src/man/sssd-ldap.5.xml +@@ -834,6 +834,14 @@ + ldap_user_authorized_service option + to work. + ++ ++ Some distributions (such as Fedora-29+ or RHEL-8) ++ always include the systemd-user PAM ++ service as part of the login process. Therefore when ++ using service-based access control, the ++ systemd-user service might need to be ++ added to the list of allowed services. ++ + + Default: authorizedService + +-- +2.20.1 + diff --git a/SOURCES/0023-proxy-access-provider-directly-not-through-be_ctx.patch b/SOURCES/0023-proxy-access-provider-directly-not-through-be_ctx.patch deleted file mode 100644 index 2ac0feb..0000000 --- a/SOURCES/0023-proxy-access-provider-directly-not-through-be_ctx.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 61c442994706365c177a62799194e62ec46f3ae0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Wed, 5 Sep 2018 13:35:54 +0200 -Subject: [PATCH 23/28] proxy: access provider directly not through be_ctx - -Modules are initialized as part of dp_init_send() but be_ctx->provider is set -only after this request is finished therefore it is not available here. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3812 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 4ffe3ab9023ff858410256bc5c38a03d9cd88cf9) ---- - src/providers/proxy/proxy_init.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/src/providers/proxy/proxy_init.c b/src/providers/proxy/proxy_init.c -index cf4f82e1246f08e2dbecd986a044500eee912b13..98c6dd1798dbf98419db71004cb55fcf21f58f81 100644 ---- a/src/providers/proxy/proxy_init.c -+++ b/src/providers/proxy/proxy_init.c -@@ -192,6 +192,7 @@ static errno_t proxy_auth_conf(TALLOC_CTX *mem_ctx, - - static errno_t proxy_init_auth_ctx(TALLOC_CTX *mem_ctx, - struct be_ctx *be_ctx, -+ struct data_provider *provider, - struct proxy_auth_ctx **_auth_ctx) - { - struct proxy_auth_ctx *auth_ctx; -@@ -213,7 +214,7 @@ static errno_t proxy_init_auth_ctx(TALLOC_CTX *mem_ctx, - goto done; - } - -- ret = proxy_client_init(dp_sbus_conn(be_ctx->provider), auth_ctx); -+ ret = proxy_client_init(dp_sbus_conn(provider), auth_ctx); - if (ret != EOK) { - goto done; - } -@@ -273,7 +274,7 @@ errno_t sssm_proxy_init(TALLOC_CTX *mem_ctx, - - /* Initialize auth_ctx since one of the access, auth or chpass is set. */ - -- ret = proxy_init_auth_ctx(mem_ctx, be_ctx, &auth_ctx); -+ ret = proxy_init_auth_ctx(mem_ctx, be_ctx, provider, &auth_ctx); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create auth context [%d]: %s\n", - ret, sss_strerror(ret)); --- -2.14.4 diff --git a/SOURCES/0024-Don-t-qualify-users-from-files-domain-when-default_d.patch b/SOURCES/0024-Don-t-qualify-users-from-files-domain-when-default_d.patch new file mode 100644 index 0000000..c288f24 --- /dev/null +++ b/SOURCES/0024-Don-t-qualify-users-from-files-domain-when-default_d.patch @@ -0,0 +1,119 @@ +From 41da9ddfd084024ba9ca20b6d3c0b531c0473231 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Fri, 2 Aug 2019 12:07:51 +0200 +Subject: [PATCH] Don't qualify users from files domain when + default_domain_suffix is set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Resolves: +https://pagure.io/SSSD/sssd/issue/4052 + +The files domain should always be non-qualified. The usual rules like +qualification of all domains except the one set with +default_domain_suffix should not apply. + +Reviewed-by: Michal Židek +--- + src/confdb/confdb.c | 7 ++++-- + src/man/sssd.conf.5.xml | 8 ++++++- + src/tests/intg/test_files_provider.py | 31 +++++++++++++++++++++++++++ + 3 files changed, 43 insertions(+), 3 deletions(-) + +diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c +index f6fdbc3aa..be65310dc 100644 +--- a/src/confdb/confdb.c ++++ b/src/confdb/confdb.c +@@ -1049,7 +1049,8 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb, + + /* Determine if user/group names will be Fully Qualified + * in NSS interfaces */ +- if (default_domain != NULL) { ++ if (default_domain != NULL ++ && is_files_provider(domain) == false) { + DEBUG(SSSDBG_CONF_SETTINGS, + "Default domain suffix set. Changing default for " + "use_fully_qualified_names to True.\n"); +@@ -1064,7 +1065,9 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb, + goto done; + } + +- if (default_domain != NULL && domain->fqnames == false) { ++ if (default_domain != NULL ++ && domain->fqnames == false ++ && is_files_provider(domain) == false) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Invalid configuration detected (default_domain_suffix is used " + "while use_fully_qualified_names was set to false).\n"); +diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml +index 304a6a170..c81012357 100644 +--- a/src/man/sssd.conf.5.xml ++++ b/src/man/sssd.conf.5.xml +@@ -412,7 +412,13 @@ + to log in. Setting this option changes default + of use_fully_qualified_names to True. It is not + allowed to use this option together with +- use_fully_qualified_names set to False. ++ use_fully_qualified_names set to False. One ++ exception from this rule are domains with ++ id_provider=files that always try ++ to match the behaviour of nss_files ++ and therefore their output is not ++ qualified even when the default_domain_suffix ++ option is used. + + + Default: not set +diff --git a/src/tests/intg/test_files_provider.py b/src/tests/intg/test_files_provider.py +index 784bfa91f..9f3aad994 100644 +--- a/src/tests/intg/test_files_provider.py ++++ b/src/tests/intg/test_files_provider.py +@@ -310,6 +310,22 @@ def domain_resolution_order(request): + return None + + ++@pytest.fixture ++def default_domain_suffix(request): ++ conf = unindent("""\ ++ [sssd] ++ domains = files ++ services = nss ++ default_domain_suffix = foo ++ ++ [domain/files] ++ id_provider = files ++ """).format(**locals()) ++ create_conf_fixture(request, conf) ++ create_sssd_fixture(request) ++ return None ++ ++ + @pytest.fixture + def override_homedir_and_shell(request): + conf = unindent("""\ +@@ -1206,6 +1222,21 @@ def test_files_with_domain_resolution_order(add_user_with_canary, + check_user(USER1) + + ++def test_files_with_default_domain_suffix(add_user_with_canary, ++ default_domain_suffix): ++ """ ++ Test that when using domain_resolution_order the user won't be using ++ its fully-qualified name. ++ """ ++ ret = poll_canary(call_sssd_getpwuid, CANARY["uid"]) ++ if ret is False: ++ return NssReturnCode.NOTFOUND, None ++ ++ res, found_user = call_sssd_getpwuid(USER1["uid"]) ++ assert res == NssReturnCode.SUCCESS ++ assert found_user == USER1 ++ ++ + def test_files_with_override_homedir(add_user_with_canary, + override_homedir_and_shell): + res, user = sssd_getpwnam_sync(USER1["name"]) +-- +2.20.1 + diff --git a/SOURCES/0024-dp-set-be_ctx-provider-as-part-of-dp_init-request.patch b/SOURCES/0024-dp-set-be_ctx-provider-as-part-of-dp_init-request.patch deleted file mode 100644 index cef0070..0000000 --- a/SOURCES/0024-dp-set-be_ctx-provider-as-part-of-dp_init-request.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 65c689876b89e1ae2a1d214d509e8ef4a611cd4c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Wed, 5 Sep 2018 13:51:55 +0200 -Subject: [PATCH 24/28] dp: set be_ctx->provider as part of dp_init request - -Backend context is overused inside sssd code even during its initialization. -Some parts of initialization code requires access to be_ctx->provider so we -must make it available as soon as possible. - -Better solution would be to always use 'provider' directly in initialization -but this makes it safer for any future changes as one does not have to keep -in mind when it is safe to use be_ctx->provider and when not. Now it is -always safe. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3812 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 4c5a1afa0df41aac05d34455c6e54a6f52a8dd28) ---- - src/providers/data_provider/dp.c | 21 +++++++++++++-------- - src/providers/data_provider/dp.h | 1 - - src/providers/data_provider_be.c | 2 +- - src/providers/proxy/proxy_init.c | 2 +- - 4 files changed, 15 insertions(+), 11 deletions(-) - -diff --git a/src/providers/data_provider/dp.c b/src/providers/data_provider/dp.c -index fd19d2803334726d0b59e76cc6c936a62d72d5e5..bd003c8b3e2919409941c11b3f1aa76ed074da7d 100644 ---- a/src/providers/data_provider/dp.c -+++ b/src/providers/data_provider/dp.c -@@ -120,6 +120,7 @@ static int dp_destructor(struct data_provider *provider) - } - - struct dp_init_state { -+ struct be_ctx *be_ctx; - struct data_provider *provider; - char *sbus_name; - }; -@@ -158,6 +159,7 @@ dp_init_send(TALLOC_CTX *mem_ctx, - goto done; - } - -+ state->be_ctx = be_ctx; - state->provider->ev = ev; - state->provider->uid = uid; - state->provider->gid = gid; -@@ -224,12 +226,14 @@ static void dp_init_done(struct tevent_req *subreq) - sbus_server_set_on_connection(state->provider->sbus_server, - dp_client_init, state->provider); - -+ /* be_ctx->provider must be accessible from modules and targets */ -+ state->be_ctx->provider = talloc_steal(state->be_ctx, state->provider); -+ - ret = dp_init_modules(state->provider, &state->provider->modules); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize DP modules " - "[%d]: %s\n", ret, sss_strerror(ret)); -- tevent_req_error(req, ret); -- return; -+ goto done; - } - - ret = dp_init_targets(state->provider, state->provider->be_ctx, -@@ -237,25 +241,27 @@ static void dp_init_done(struct tevent_req *subreq) - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize DP targets " - "[%d]: %s\n", ret, sss_strerror(ret)); -- tevent_req_error(req, ret); -- return; -+ goto done; - } - - ret = dp_init_interface(state->provider); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize DP interface " - "[%d]: %s\n", ret, sss_strerror(ret)); -+ goto done; -+ } -+ -+done: -+ if (ret != EOK) { -+ talloc_zfree(state->be_ctx->provider); - tevent_req_error(req, ret); -- return; - } - - tevent_req_done(req); -- return; - } - - errno_t dp_init_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, -- struct data_provider **_provider, - const char **_sbus_name) - { - struct dp_init_state *state; -@@ -263,7 +269,6 @@ errno_t dp_init_recv(TALLOC_CTX *mem_ctx, - - TEVENT_REQ_RETURN_ON_ERROR(req); - -- *_provider = talloc_steal(mem_ctx, state->provider); - *_sbus_name = talloc_steal(mem_ctx, state->sbus_name); - - return EOK; -diff --git a/src/providers/data_provider/dp.h b/src/providers/data_provider/dp.h -index 33e6e6567bc56ac8ac8180edca01e8d937d0d39d..0028eb1cbdcb7e9db004a8c9c2f6c13b317cae7d 100644 ---- a/src/providers/data_provider/dp.h -+++ b/src/providers/data_provider/dp.h -@@ -117,7 +117,6 @@ dp_init_send(TALLOC_CTX *mem_ctx, - - errno_t dp_init_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, -- struct data_provider **_provider, - const char **_sbus_name); - - bool _dp_target_enabled(struct data_provider *provider, -diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c -index 670ddb477cb7363b5f831e8b7b50b6b7f39c6289..6d2477e34b02ae84d241714b72296c62a2560bb1 100644 ---- a/src/providers/data_provider_be.c -+++ b/src/providers/data_provider_be.c -@@ -541,7 +541,7 @@ static void dp_initialized(struct tevent_req *req) - - be_ctx = tevent_req_callback_data(req, struct be_ctx); - -- ret = dp_init_recv(be_ctx, req, &be_ctx->provider, &be_ctx->sbus_name); -+ ret = dp_init_recv(be_ctx, req, &be_ctx->sbus_name); - talloc_zfree(req); - if (ret != EOK) { - goto done; -diff --git a/src/providers/proxy/proxy_init.c b/src/providers/proxy/proxy_init.c -index 98c6dd1798dbf98419db71004cb55fcf21f58f81..32343a3bf52df866708a69f3f4364a4c65c1d3c6 100644 ---- a/src/providers/proxy/proxy_init.c -+++ b/src/providers/proxy/proxy_init.c -@@ -214,7 +214,7 @@ static errno_t proxy_init_auth_ctx(TALLOC_CTX *mem_ctx, - goto done; - } - -- ret = proxy_client_init(dp_sbus_conn(provider), auth_ctx); -+ ret = proxy_client_init(dp_sbus_conn(be_ctx->provider), auth_ctx); - if (ret != EOK) { - goto done; - } --- -2.14.4 diff --git a/SOURCES/0025-pam-fix-loop-in-Smartcard-authentication.patch b/SOURCES/0025-pam-fix-loop-in-Smartcard-authentication.patch new file mode 100644 index 0000000..d193fb7 --- /dev/null +++ b/SOURCES/0025-pam-fix-loop-in-Smartcard-authentication.patch @@ -0,0 +1,42 @@ +From 5574de0f87e72d85547add9a48f9ac0def27f47d Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 2 Aug 2019 13:43:49 +0200 +Subject: [PATCH] pam: fix loop in Smartcard authentication + +If 'try_cert_auth' or 'require_cert_auth' options are used and a wrong +PIN is entered the PAM responder might end in an endless loop. This +patch uses a flag to avoid the loop and makes sure that during +authentication the error code causing the loop is not returned. + +Related to https://pagure.io/SSSD/sssd/issue/4051 + +Reviewed-by: Jakub Hrozek +--- + src/responder/pam/pamsrv_cmd.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c +index 89bdb78a1..72412204b 100644 +--- a/src/responder/pam/pamsrv_cmd.c ++++ b/src/responder/pam/pamsrv_cmd.c +@@ -814,6 +814,7 @@ static void pam_reply(struct pam_auth_req *preq) + pd->pam_status, pam_strerror(NULL, pd->pam_status)); + + if (pd->cmd == SSS_PAM_AUTHENTICATE ++ && !preq->cert_auth_local + && (pd->pam_status == PAM_AUTHINFO_UNAVAIL + || pd->pam_status == PAM_NO_MODULE_DATA + || pd->pam_status == PAM_BAD_ITEM) +@@ -1475,7 +1476,8 @@ static void pam_forwarder_cert_cb(struct tevent_req *req) + "No certificate found and no logon name given, " \ + "authentication not possible.\n"); + ret = ENOENT; +- } else if (pd->cli_flags & PAM_CLI_FLAGS_TRY_CERT_AUTH) { ++ } else if (pd->cmd == SSS_PAM_PREAUTH ++ && (pd->cli_flags & PAM_CLI_FLAGS_TRY_CERT_AUTH)) { + DEBUG(SSSDBG_TRACE_ALL, + "try_cert_auth flag set but no certificate available, " + "request finished.\n"); +-- +2.20.1 + diff --git a/SOURCES/0025-sbus-read-destination-after-sender-is-set.patch b/SOURCES/0025-sbus-read-destination-after-sender-is-set.patch deleted file mode 100644 index 30364d0..0000000 --- a/SOURCES/0025-sbus-read-destination-after-sender-is-set.patch +++ /dev/null @@ -1,42 +0,0 @@ -From d47b031bc09b43fe2002fd5c737969b733b4789b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Wed, 12 Sep 2018 13:21:11 +0200 -Subject: [PATCH 25/28] sbus: read destination after sender is set - -dbus_message_set_sender may reallocate internal fields which will yield pointer -obtained by dbus_message_get_* invalid. - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 9245bf1afe6767a0412212bc0040e606ee850e7d) ---- - src/sbus/server/sbus_server_handler.c | 8 +++++--- - 1 file changed, 5 insertions(+), 3 deletions(-) - -diff --git a/src/sbus/server/sbus_server_handler.c b/src/sbus/server/sbus_server_handler.c -index c300d81e1272fdb3d042491680ba9b678e00fbb1..d4e454780a29e321b322dced4b4c0ec7110233ad 100644 ---- a/src/sbus/server/sbus_server_handler.c -+++ b/src/sbus/server/sbus_server_handler.c -@@ -148,9 +148,6 @@ sbus_server_filter(DBusConnection *dbus_conn, - return DBUS_HANDLER_RESULT_HANDLED; - } - -- destination = dbus_message_get_destination(message); -- type = dbus_message_get_type(message); -- - conn = dbus_connection_get_data(dbus_conn, server->data_slot); - if (conn == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unknown connection!\n"); -@@ -173,6 +170,11 @@ sbus_server_filter(DBusConnection *dbus_conn, - return DBUS_HANDLER_RESULT_HANDLED; - } - -+ /* Set sender may reallocate internal fields so this needs to be read -+ * after we call dbus_message_set_sender(). */ -+ destination = dbus_message_get_destination(message); -+ type = dbus_message_get_type(message); -+ - if (type == DBUS_MESSAGE_TYPE_SIGNAL) { - return sbus_server_route_signal(server, conn, message, destination); - } --- -2.14.4 diff --git a/SOURCES/0026-SYSDB-Add-sysdb_search_with_ts_attr.patch b/SOURCES/0026-SYSDB-Add-sysdb_search_with_ts_attr.patch new file mode 100644 index 0000000..e0d1c3c --- /dev/null +++ b/SOURCES/0026-SYSDB-Add-sysdb_search_with_ts_attr.patch @@ -0,0 +1,592 @@ +From f46afb46a1705d41e21451cd0adf6981936b21c1 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 28 May 2019 14:56:05 +0200 +Subject: [PATCH 26/48] SYSDB: Add sysdb_search_with_ts_attr + +Adds a new public sysdb call sysdb_search_with_ts_attr() that allows to +search on the timestamp cache attributes, but merge back persistent +cache attributes. The converse also works, when searching the persistent +cache the timestamp attributes or even entries matches only in the +timestamp cache are merged. + +What does not work is AND-ed complex filter that contains both +attributes from the timestamp cache and the persistent cache because +the searches use the same filter, which doesn't match. We would need to +decompose the filter ourselves. + +Because matching and merging the results can be time-consuming, two +flags are provided: + SYSDB_SEARCH_WITH_TS_ONLY_TS_FILTER that only searches the timestamp + cache, but merges back the corresponding entries from the persistent + cache + SYSDB_SEARCH_WITH_TS_ONLY_SYSDB_FILTER that only searches the + persistent cache but merges back the attributes from the timestamp + cache + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + src/db/sysdb.h | 12 ++ + src/db/sysdb_ops.c | 16 +- + src/db/sysdb_private.h | 10 ++ + src/db/sysdb_search.c | 231 +++++++++++++++++++++++-- + src/tests/cmocka/test_sysdb_ts_cache.c | 198 +++++++++++++++++++++ + 5 files changed, 446 insertions(+), 21 deletions(-) + +diff --git a/src/db/sysdb.h b/src/db/sysdb.h +index 89b0d9571..28801e030 100644 +--- a/src/db/sysdb.h ++++ b/src/db/sysdb.h +@@ -1181,6 +1181,18 @@ int sysdb_search_users(TALLOC_CTX *mem_ctx, + size_t *msgs_count, + struct ldb_message ***msgs); + ++#define SYSDB_SEARCH_WITH_TS_ONLY_TS_FILTER 0x0001 ++#define SYSDB_SEARCH_WITH_TS_ONLY_SYSDB_FILTER 0x0002 ++ ++errno_t sysdb_search_with_ts_attr(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *domain, ++ struct ldb_dn *base_dn, ++ enum ldb_scope scope, ++ int optflags, ++ const char *filter, ++ const char *attrs[], ++ struct ldb_result **_result); ++ + int sysdb_search_users_by_timestamp(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + const char *sub_filter, +diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c +index 59fb227a4..55ba62140 100644 +--- a/src/db/sysdb_ops.c ++++ b/src/db/sysdb_ops.c +@@ -261,14 +261,14 @@ done: + + /* =Search-Entry========================================================== */ + +-static int sysdb_cache_search_entry(TALLOC_CTX *mem_ctx, +- struct ldb_context *ldb, +- struct ldb_dn *base_dn, +- enum ldb_scope scope, +- const char *filter, +- const char **attrs, +- size_t *_msgs_count, +- struct ldb_message ***_msgs) ++int sysdb_cache_search_entry(TALLOC_CTX *mem_ctx, ++ struct ldb_context *ldb, ++ struct ldb_dn *base_dn, ++ enum ldb_scope scope, ++ const char *filter, ++ const char **attrs, ++ size_t *_msgs_count, ++ struct ldb_message ***_msgs) + { + TALLOC_CTX *tmp_ctx; + struct ldb_result *res; +diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h +index 58544d826..53603b30e 100644 +--- a/src/db/sysdb_private.h ++++ b/src/db/sysdb_private.h +@@ -252,6 +252,16 @@ errno_t sysdb_merge_msg_list_ts_attrs(struct sysdb_ctx *ctx, + struct ldb_result *sss_merge_ldb_results(struct ldb_result *res, + struct ldb_result *subres); + ++/* Search Entry in an ldb cache */ ++int sysdb_cache_search_entry(TALLOC_CTX *mem_ctx, ++ struct ldb_context *ldb, ++ struct ldb_dn *base_dn, ++ enum ldb_scope scope, ++ const char *filter, ++ const char **attrs, ++ size_t *_msgs_count, ++ struct ldb_message ***_msgs); ++ + /* Search Entry in the timestamp cache */ + int sysdb_search_ts_entry(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, +diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c +index f0918bf9a..a71c43112 100644 +--- a/src/db/sysdb_search.c ++++ b/src/db/sysdb_search.c +@@ -68,6 +68,29 @@ static errno_t merge_ts_attr(struct ldb_message *ts_msg, + return EOK; + } + ++static errno_t merge_all_ts_attrs(struct ldb_message *ts_msg, ++ struct ldb_message *sysdb_msg, ++ const char *want_attrs[]) ++{ ++ int ret; ++ ++ /* Deliberately start from 2 in order to not merge ++ * objectclass/objectcategory and avoid breaking MPGs where the OC might ++ * be made up ++ */ ++ for (size_t c = 2; sysdb_ts_cache_attrs[c]; c++) { ++ ret = merge_ts_attr(ts_msg, sysdb_msg, ++ sysdb_ts_cache_attrs[c], want_attrs); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Cannot merge ts attr %s\n", sysdb_ts_cache_attrs[c]); ++ return ret; ++ } ++ } ++ ++ return EOK; ++} ++ + static errno_t merge_msg_ts_attrs(struct sysdb_ctx *sysdb, + struct ldb_message *sysdb_msg, + const char *attrs[]) +@@ -114,21 +137,46 @@ static errno_t merge_msg_ts_attrs(struct sysdb_ctx *sysdb, + return EIO; + } + +- /* Deliberately start from 2 in order to not merge +- * objectclass/objectcategory and avoid breaking MPGs where the OC might +- * be made up +- */ +- for (size_t c = 2; sysdb_ts_cache_attrs[c]; c++) { +- ret = merge_ts_attr(ts_msgs[0], sysdb_msg, +- sysdb_ts_cache_attrs[c], attrs); +- if (ret != EOK) { +- DEBUG(SSSDBG_MINOR_FAILURE, +- "Cannot merge ts attr %s\n", sysdb_ts_cache_attrs[c]); +- goto done; +- } ++ ret = merge_all_ts_attrs(ts_msgs[0], sysdb_msg, attrs); ++done: ++ talloc_zfree(tmp_ctx); ++ return ret; ++} ++ ++static errno_t merge_msg_sysdb_attrs(TALLOC_CTX *mem_ctx, ++ struct sysdb_ctx *sysdb, ++ struct ldb_message *ts_msg, ++ struct ldb_message **_sysdb_msg, ++ const char *attrs[]) ++{ ++ errno_t ret; ++ TALLOC_CTX *tmp_ctx; ++ size_t msgs_count; ++ struct ldb_message **sysdb_msgs; ++ ++ tmp_ctx = talloc_new(NULL); ++ if (tmp_ctx == NULL) { ++ return ENOMEM; + } + +- ret = EOK; ++ ret = sysdb_cache_search_entry(tmp_ctx, sysdb->ldb, ts_msg->dn, LDB_SCOPE_BASE, ++ NULL, attrs, &msgs_count, &sysdb_msgs); ++ if (ret != EOK) { ++ goto done; ++ } ++ ++ if (msgs_count != 1) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "Expected 1 result for base search, got %zu\n", msgs_count); ++ goto done; ++ } ++ ++ ret = merge_all_ts_attrs(ts_msg, sysdb_msgs[0], attrs); ++ if (ret != EOK) { ++ goto done; ++ } ++ ++ *_sysdb_msg = talloc_steal(mem_ctx, sysdb_msgs[0]); + done: + talloc_zfree(tmp_ctx); + return ret; +@@ -166,6 +214,50 @@ errno_t sysdb_merge_res_ts_attrs(struct sysdb_ctx *ctx, + return EOK; + } + ++static errno_t merge_res_sysdb_attrs(TALLOC_CTX *mem_ctx, ++ struct sysdb_ctx *ctx, ++ struct ldb_result *ts_res, ++ struct ldb_result **_ts_cache_res, ++ const char *attrs[]) ++{ ++ errno_t ret; ++ struct ldb_result *ts_cache_res = NULL; ++ ++ if (ts_res == NULL || ctx->ldb_ts == NULL) { ++ return EOK; ++ } ++ ++ ts_cache_res = talloc_zero(mem_ctx, struct ldb_result); ++ if (ts_cache_res == NULL) { ++ return ENOMEM; ++ } ++ ts_cache_res->count = ts_res->count; ++ ts_cache_res->msgs = talloc_zero_array(ts_cache_res, ++ struct ldb_message *, ++ ts_res->count); ++ if (ts_cache_res->msgs == NULL) { ++ talloc_free(ts_cache_res); ++ return ENOMEM; ++ } ++ ++ for (size_t c = 0; c < ts_res->count; c++) { ++ ret = merge_msg_sysdb_attrs(ts_cache_res->msgs, ++ ctx, ++ ts_res->msgs[c], ++ &ts_cache_res->msgs[c], attrs); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Cannot merge sysdb cache values for %s\n", ++ ldb_dn_get_linearized(ts_res->msgs[c]->dn)); ++ /* non-fatal, we just get only the non-timestamp attrs */ ++ continue; ++ } ++ } ++ ++ *_ts_cache_res = ts_cache_res; ++ return EOK; ++} ++ + errno_t sysdb_merge_msg_list_ts_attrs(struct sysdb_ctx *ctx, + size_t msgs_count, + struct ldb_message **msgs, +@@ -543,6 +635,119 @@ done: + return ret; + } + ++errno_t sysdb_search_with_ts_attr(TALLOC_CTX *mem_ctx, ++ struct sss_domain_info *domain, ++ struct ldb_dn *base_dn, ++ enum ldb_scope scope, ++ int optflags, ++ const char *filter, ++ const char *attrs[], ++ struct ldb_result **_res) ++{ ++ TALLOC_CTX *tmp_ctx = NULL; ++ struct ldb_result *res; ++ errno_t ret; ++ struct ldb_message **ts_msgs = NULL; ++ struct ldb_result *ts_cache_res = NULL; ++ size_t ts_count; ++ ++ if (filter == NULL) { ++ return EINVAL; ++ } ++ ++ tmp_ctx = talloc_new(NULL); ++ if (tmp_ctx == NULL) { ++ return ENOMEM; ++ } ++ ++ res = talloc_zero(tmp_ctx, struct ldb_result); ++ if (res == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ if (optflags & SYSDB_SEARCH_WITH_TS_ONLY_SYSDB_FILTER) { ++ /* We only care about searching the persistent db */ ++ ts_cache_res = talloc_zero(tmp_ctx, struct ldb_result); ++ if (ts_cache_res == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ ts_cache_res->count = 0; ++ ts_cache_res->msgs = NULL; ++ } else { ++ /* Because the timestamp database does not contain all the ++ * attributes, we need to search the persistent db for each ++ * of the entries found and merge the results ++ */ ++ struct ldb_result ts_res; ++ ++ /* We assume that some of the attributes are more up-to-date in ++ * timestamps db and we're supposed to search by them, so let's ++ * first search the timestamp db ++ */ ++ ret = sysdb_search_ts_entry(tmp_ctx, domain->sysdb, base_dn, ++ scope, filter, attrs, ++ &ts_count, &ts_msgs); ++ if (ret == ENOENT) { ++ ts_count = 0; ++ } else if (ret != EOK) { ++ goto done; ++ } ++ ++ memset(&ts_res, 0, sizeof(struct ldb_result)); ++ ts_res.count = ts_count; ++ ts_res.msgs = ts_msgs; ++ ++ /* Overlay the results from the main cache with the ts attrs */ ++ ret = merge_res_sysdb_attrs(tmp_ctx, ++ domain->sysdb, ++ &ts_res, ++ &ts_cache_res, ++ attrs); ++ if (ret != EOK) { ++ goto done; ++ } ++ } ++ ++ if (optflags & SYSDB_SEARCH_WITH_TS_ONLY_TS_FILTER) { ++ /* The filter only contains timestamp attrs, no need to search the ++ * persistent db ++ */ ++ if (ts_cache_res) { ++ res->count = ts_cache_res->count; ++ res->msgs = talloc_steal(res, ts_cache_res->msgs); ++ } ++ } else { ++ /* Because some of the attributes being searched might exist in the persistent ++ * database only, we also search the persistent db ++ */ ++ size_t count; ++ ++ ret = sysdb_search_entry(res, domain->sysdb, base_dn, scope, ++ filter, attrs, &count, &res->msgs); ++ if (ret == ENOENT) { ++ res->count = 0; ++ } else if (ret != EOK) { ++ goto done; ++ } ++ res->count = count; /* Just to cleanly assign size_t to unsigned */ ++ ++ res = sss_merge_ldb_results(res, ts_cache_res); ++ if (res == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ } ++ ++ *_res = talloc_steal(mem_ctx, res); ++ ret = EOK; ++ ++done: ++ talloc_zfree(tmp_ctx); ++ return ret; ++} ++ + static errno_t sysdb_enum_dn_filter(TALLOC_CTX *mem_ctx, + struct ldb_result *ts_res, + const char *name_filter, +diff --git a/src/tests/cmocka/test_sysdb_ts_cache.c b/src/tests/cmocka/test_sysdb_ts_cache.c +index fdf9935da..d2296d1b8 100644 +--- a/src/tests/cmocka/test_sysdb_ts_cache.c ++++ b/src/tests/cmocka/test_sysdb_ts_cache.c +@@ -1411,6 +1411,201 @@ static void test_sysdb_zero_now(void **state) + assert_true(cache_expire_ts > TEST_CACHE_TIMEOUT); + } + ++static void test_sysdb_search_with_ts(void **state) ++{ ++ int ret; ++ struct sysdb_ts_test_ctx *test_ctx = talloc_get_type_abort(*state, ++ struct sysdb_ts_test_ctx); ++ struct ldb_result *res = NULL; ++ struct ldb_dn *base_dn; ++ const char *attrs[] = { SYSDB_NAME, ++ SYSDB_OBJECTCATEGORY, ++ SYSDB_GIDNUM, ++ SYSDB_CACHE_EXPIRE, ++ NULL }; ++ struct sysdb_attrs *group_attrs = NULL; ++ char *filter; ++ uint64_t cache_expire_sysdb; ++ uint64_t cache_expire_ts; ++ size_t count; ++ struct ldb_message **msgs; ++ ++ base_dn = sysdb_base_dn(test_ctx->tctx->dom->sysdb, test_ctx); ++ assert_non_null(base_dn); ++ ++ /* Nothing must be stored in either cache at the beginning of the test */ ++ ret = sysdb_search_with_ts_attr(test_ctx, ++ test_ctx->tctx->dom, ++ base_dn, ++ LDB_SCOPE_SUBTREE, ++ 0, ++ SYSDB_NAME"=*", ++ attrs, ++ &res); ++ assert_int_equal(ret, EOK); ++ assert_int_equal(res->count, 0); ++ talloc_free(res); ++ ++ group_attrs = create_modstamp_attrs(test_ctx, TEST_MODSTAMP_1); ++ assert_non_null(group_attrs); ++ ++ ret = sysdb_store_group(test_ctx->tctx->dom, ++ TEST_GROUP_NAME, ++ TEST_GROUP_GID, ++ group_attrs, ++ TEST_CACHE_TIMEOUT, ++ TEST_NOW_1); ++ assert_int_equal(ret, EOK); ++ talloc_zfree(group_attrs); ++ ++ group_attrs = create_modstamp_attrs(test_ctx, TEST_MODSTAMP_1); ++ assert_non_null(group_attrs); ++ ++ ret = sysdb_store_group(test_ctx->tctx->dom, ++ TEST_GROUP_NAME_2, ++ TEST_GROUP_GID_2, ++ group_attrs, ++ TEST_CACHE_TIMEOUT, ++ TEST_NOW_2); ++ assert_int_equal(ret, EOK); ++ talloc_zfree(group_attrs); ++ ++ /* Bump the timestamps in the cache so that the ts cache ++ * and sysdb differ ++ */ ++ ++ group_attrs = create_modstamp_attrs(test_ctx, TEST_MODSTAMP_1); ++ assert_non_null(group_attrs); ++ ++ ret = sysdb_store_group(test_ctx->tctx->dom, ++ TEST_GROUP_NAME, ++ TEST_GROUP_GID, ++ group_attrs, ++ TEST_CACHE_TIMEOUT, ++ TEST_NOW_3); ++ assert_int_equal(ret, EOK); ++ ++ talloc_zfree(group_attrs); ++ ++ ++ group_attrs = create_modstamp_attrs(test_ctx, TEST_MODSTAMP_1); ++ assert_non_null(group_attrs); ++ ++ ret = sysdb_store_group(test_ctx->tctx->dom, ++ TEST_GROUP_NAME_2, ++ TEST_GROUP_GID_2, ++ group_attrs, ++ TEST_CACHE_TIMEOUT, ++ TEST_NOW_4); ++ assert_int_equal(ret, EOK); ++ ++ talloc_zfree(group_attrs); ++ ++ get_gr_timestamp_attrs(test_ctx, TEST_GROUP_NAME, ++ &cache_expire_sysdb, &cache_expire_ts); ++ assert_int_equal(cache_expire_sysdb, TEST_CACHE_TIMEOUT + TEST_NOW_1); ++ assert_int_equal(cache_expire_ts, TEST_CACHE_TIMEOUT + TEST_NOW_3); ++ ++ get_gr_timestamp_attrs(test_ctx, TEST_GROUP_NAME_2, ++ &cache_expire_sysdb, &cache_expire_ts); ++ assert_int_equal(cache_expire_sysdb, TEST_CACHE_TIMEOUT + TEST_NOW_2); ++ assert_int_equal(cache_expire_ts, TEST_CACHE_TIMEOUT + TEST_NOW_4); ++ ++ /* Search for groups that don't expire until TEST_NOW_4 */ ++ filter = talloc_asprintf(test_ctx, SYSDB_CACHE_EXPIRE">=%d", TEST_NOW_4); ++ assert_non_null(filter); ++ ++ /* This search should yield only one group (so, it needs to search the ts ++ * cache to hit the TEST_NOW_4), but should return attributes merged from ++ * both caches ++ */ ++ ret = sysdb_search_with_ts_attr(test_ctx, ++ test_ctx->tctx->dom, ++ base_dn, ++ LDB_SCOPE_SUBTREE, ++ 0, ++ filter, ++ attrs, ++ &res); ++ assert_int_equal(ret, EOK); ++ assert_int_equal(res->count, 1); ++ assert_int_equal(TEST_GROUP_GID_2, ldb_msg_find_attr_as_uint64(res->msgs[0], ++ SYSDB_GIDNUM, 0)); ++ talloc_free(res); ++ ++ /* ++ * In contrast, sysdb_search_entry merges the timestamp attributes, but does ++ * not search the timestamp cache ++ */ ++ ret = sysdb_search_entry(test_ctx, ++ test_ctx->tctx->dom->sysdb, ++ base_dn, ++ LDB_SCOPE_SUBTREE, ++ filter, ++ attrs, ++ &count, ++ &msgs); ++ assert_int_equal(ret, ENOENT); ++ ++ /* Should get the same result when searching by ts attrs only */ ++ ret = sysdb_search_with_ts_attr(test_ctx, ++ test_ctx->tctx->dom, ++ base_dn, ++ LDB_SCOPE_SUBTREE, ++ SYSDB_SEARCH_WITH_TS_ONLY_TS_FILTER, ++ filter, ++ attrs, ++ &res); ++ talloc_zfree(filter); ++ assert_int_equal(ret, EOK); ++ assert_int_equal(res->count, 1); ++ assert_int_equal(TEST_GROUP_GID_2, ldb_msg_find_attr_as_uint64(res->msgs[0], ++ SYSDB_GIDNUM, 0)); ++ talloc_free(res); ++ ++ /* We can also search in sysdb only as well, we should get back ts attrs */ ++ filter = talloc_asprintf(test_ctx, SYSDB_GIDNUM"=%d", TEST_GROUP_GID); ++ assert_non_null(filter); ++ ++ ret = sysdb_search_with_ts_attr(test_ctx, ++ test_ctx->tctx->dom, ++ base_dn, ++ LDB_SCOPE_SUBTREE, ++ SYSDB_SEARCH_WITH_TS_ONLY_SYSDB_FILTER, ++ filter, ++ attrs, ++ &res); ++ talloc_zfree(filter); ++ assert_int_equal(ret, EOK); ++ assert_int_equal(res->count, 1); ++ assert_int_equal(TEST_GROUP_GID, ldb_msg_find_attr_as_uint64(res->msgs[0], ++ SYSDB_GIDNUM, 0)); ++ assert_int_equal(TEST_CACHE_TIMEOUT + TEST_NOW_3, ++ ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_CACHE_EXPIRE, 0)); ++ talloc_free(res); ++ ++ /* We can also search in both using an OR-filter. Note that an AND-filter is not possible ++ * unless we deconstruct the filter.. ++ */ ++ filter = talloc_asprintf(test_ctx, "(|("SYSDB_GIDNUM"=%d)" ++ "("SYSDB_CACHE_EXPIRE">=%d))", ++ TEST_GROUP_GID, TEST_NOW_4); ++ assert_non_null(filter); ++ ++ ret = sysdb_search_with_ts_attr(test_ctx, ++ test_ctx->tctx->dom, ++ base_dn, ++ LDB_SCOPE_SUBTREE, ++ 0, ++ filter, ++ attrs, ++ &res); ++ talloc_zfree(filter); ++ assert_int_equal(ret, EOK); ++ assert_int_equal(res->count, 2); ++ talloc_free(res); ++} ++ + int main(int argc, const char *argv[]) + { + int rv; +@@ -1462,6 +1657,9 @@ int main(int argc, const char *argv[]) + cmocka_unit_test_setup_teardown(test_sysdb_zero_now, + test_sysdb_ts_setup, + test_sysdb_ts_teardown), ++ cmocka_unit_test_setup_teardown(test_sysdb_search_with_ts, ++ test_sysdb_ts_setup, ++ test_sysdb_ts_teardown), + }; + + /* Set debug level to invalid value so we can decide if -d 0 was used. */ +-- +2.20.1 + diff --git a/SOURCES/0026-sbus-do-not-try-to-remove-signal-listeners-when-disc.patch b/SOURCES/0026-sbus-do-not-try-to-remove-signal-listeners-when-disc.patch deleted file mode 100644 index ec4f920..0000000 --- a/SOURCES/0026-sbus-do-not-try-to-remove-signal-listeners-when-disc.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 6c90ff0c0f8e4dce2d80cad8a042b2658bf68205 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Wed, 12 Sep 2018 13:22:34 +0200 -Subject: [PATCH 26/28] sbus: do not try to remove signal listeners when - disconnecting - -This may cause some troubles if the dbus connection was dropped -as dbus will try to actually send the messages. Also when the -connectin is being freed, tevent integration is already disabled -so there is no point in doing this. - -Reviewed-by: Jakub Hrozek -(cherry picked from commit b821ee3ca93beb94a7a9b22b6f7a205e4900212e) ---- - src/sbus/router/sbus_router_hash.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/sbus/router/sbus_router_hash.c b/src/sbus/router/sbus_router_hash.c -index 186dc613fc7874bfcce3f832c1c2299a217381d9..2d407b2fba12b6b57eed896e7154f85b0a65dcde 100644 ---- a/src/sbus/router/sbus_router_hash.c -+++ b/src/sbus/router/sbus_router_hash.c -@@ -384,6 +384,10 @@ sbus_router_listeners_delete_cb(hash_entry_t *item, - return; - } - -+ if (conn->disconnecting) { -+ return; -+ } -+ - /* If we still have the D-Bus connection available, we try to unregister - * the previously registered listener when its removed from table. */ - --- -2.14.4 diff --git a/SOURCES/0027-BE-search-with-sysdb_search_with_ts_attr.patch b/SOURCES/0027-BE-search-with-sysdb_search_with_ts_attr.patch new file mode 100644 index 0000000..c65ca44 --- /dev/null +++ b/SOURCES/0027-BE-search-with-sysdb_search_with_ts_attr.patch @@ -0,0 +1,69 @@ +From a5cd021e92695ccf45be92e5b05394f46ccebd2e Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 28 May 2019 14:56:15 +0200 +Subject: [PATCH 27/48] BE: search with sysdb_search_with_ts_attr + +Previously, the background refresh code had used sysdb_search_entry() +which does not run the search on the timestamp cache. Instead, this +patch changes to using sysdb_search_with_ts_attr with the +SYSDB_SEARCH_WITH_TS_ONLY_TS_FILTER optimization because currently only +the dataExpireTimestamp attribute is included in the filter. + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + src/providers/be_refresh.c | 19 +++++++++---------- + 1 file changed, 9 insertions(+), 10 deletions(-) + +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index e8cf5da75..c6bb66b68 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -40,9 +40,8 @@ static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx, + const char *attrs[] = {attr, NULL}; + const char *filter = NULL; + char **values = NULL; +- struct ldb_message **msgs = NULL; + struct sysdb_attrs **records = NULL; +- size_t count; ++ struct ldb_result *res; + time_t now = time(NULL); + errno_t ret; + +@@ -58,23 +57,23 @@ static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx, + goto done; + } + +- ret = sysdb_search_entry(tmp_ctx, domain->sysdb, base_dn, +- LDB_SCOPE_SUBTREE, filter, attrs, +- &count, &msgs); +- if (ret == ENOENT) { +- count = 0; +- } else if (ret != EOK) { ++ ret = sysdb_search_with_ts_attr(tmp_ctx, domain, base_dn, ++ LDB_SCOPE_SUBTREE, ++ SYSDB_SEARCH_WITH_TS_ONLY_TS_FILTER, ++ filter, attrs, ++ &res); ++ if (ret != EOK) { + goto done; + } + +- ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &records); ++ ret = sysdb_msg2attrs(tmp_ctx, res->count, res->msgs, &records); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not convert ldb message to sysdb_attrs\n"); + goto done; + } + +- ret = sysdb_attrs_to_list(tmp_ctx, records, count, attr, &values); ++ ret = sysdb_attrs_to_list(tmp_ctx, records, res->count, attr, &values); + if (ret != EOK) { + goto done; + } +-- +2.20.1 + diff --git a/SOURCES/0027-sbus-free-watch_fd-fdevent-explicitly.patch b/SOURCES/0027-sbus-free-watch_fd-fdevent-explicitly.patch deleted file mode 100644 index 8fd0972..0000000 --- a/SOURCES/0027-sbus-free-watch_fd-fdevent-explicitly.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 5db4c971b5a8c5753cb3790c9551f8cfb277dad7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Wed, 12 Sep 2018 13:24:27 +0200 -Subject: [PATCH 27/28] sbus: free watch_fd->fdevent explicitly - -We never reproduced this with gdb but valgrind shows invalid read in sbus_watch_handler -after the watch_fd was freed. This should not be needed since watch_fd is memory parent -of fdevent but it seems to help. - -Reviewed-by: Jakub Hrozek -(cherry picked from commit f1f9af528f71f42ac41bb7a272f4f7d940fd3a0f) ---- - src/sbus/connection/sbus_watch.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/sbus/connection/sbus_watch.c b/src/sbus/connection/sbus_watch.c -index 3898311dfc3508edafa5ecc0488b3977cb290773..0e4bd01d10f74e9524d33ca46bd5d9bb31d591fb 100644 ---- a/src/sbus/connection/sbus_watch.c -+++ b/src/sbus/connection/sbus_watch.c -@@ -280,6 +280,7 @@ sbus_watch_remove(DBusWatch *dbus_watch, void *data) - - if (watch_fd->dbus_watch.read == NULL - && watch_fd->dbus_watch.write == NULL) { -+ talloc_free(watch_fd->fdevent); - talloc_free(watch_fd); - } - } --- -2.14.4 diff --git a/SOURCES/0028-BE-Enable-refresh-for-multiple-domains.patch b/SOURCES/0028-BE-Enable-refresh-for-multiple-domains.patch new file mode 100644 index 0000000..e1f65f7 --- /dev/null +++ b/SOURCES/0028-BE-Enable-refresh-for-multiple-domains.patch @@ -0,0 +1,34 @@ +From b90b9c79eab4110ba626d0a3f94f70ab6dd80735 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 24 Apr 2019 21:09:53 +0200 +Subject: [PATCH 28/48] BE: Enable refresh for multiple domains + +Descend into subdomains on back end refresh and make sure to start from +users again. + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + src/providers/be_refresh.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index c6bb66b68..02e478c95 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -255,7 +255,9 @@ static errno_t be_refresh_step(struct tevent_req *req) + + /* if not found than continue with next domain */ + if (state->index == BE_REFRESH_TYPE_SENTINEL) { +- state->domain = get_next_domain(state->domain, 0); ++ state->domain = get_next_domain(state->domain, ++ SSS_GND_DESCEND); ++ state->index = 0; + continue; + } + +-- +2.20.1 + diff --git a/SOURCES/0028-doc-remove-local-provider-reference-from-manpages.patch b/SOURCES/0028-doc-remove-local-provider-reference-from-manpages.patch deleted file mode 100644 index aa12719..0000000 --- a/SOURCES/0028-doc-remove-local-provider-reference-from-manpages.patch +++ /dev/null @@ -1,139 +0,0 @@ -From d6cc81b7f8b40575d146b2fa7d33c8a03c6253da Mon Sep 17 00:00:00 2001 -From: Tomas Halman -Date: Thu, 27 Sep 2018 16:03:40 +0200 -Subject: [PATCH 28/28] doc: remove local provider reference from manpages - -Introduce new condition for documentation build. Related part of -documentation is excluded, if build is done without local provider. - -Resolves https://pagure.io/SSSD/sssd/issue/3826 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit de8c9caf61e7b971cda9563cc5851ea222db5830) ---- - src/man/Makefile.am | 6 +++++- - src/man/include/seealso.xml | 44 +++++++++++++++++++++++--------------------- - src/man/sssd.conf.5.xml | 15 +++++++++------ - 3 files changed, 37 insertions(+), 28 deletions(-) - -diff --git a/src/man/Makefile.am b/src/man/Makefile.am -index b4c20d8cf9574523c6d9c6aa631fe38979e54582..54a30d10f79eabf06353d6870da6ae38dcd980c1 100644 ---- a/src/man/Makefile.am -+++ b/src/man/Makefile.am -@@ -51,7 +51,11 @@ CRYPTO_CONDS = ;with_nss - else - CRYPTO_CONDS = ;with_openssl - endif --CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(PAC_RESPONDER_CONDS)$(IFP_CONDS)$(GPO_CONDS)$(SEC_CONDS)$(SYSTEMD_CONDS)$(FILES_CONDS)$(KCM_CONDS)$(STAP_CONDS)$(CRYPTO_CONDS) -+if BUILD_LOCAL_PROVIDER -+LOCAL_PROVIDER_CONDS = ;enable_local_provider -+endif -+ -+CONDS = with_false$(SUDO_CONDS)$(AUTOFS_CONDS)$(SSH_CONDS)$(PAC_RESPONDER_CONDS)$(IFP_CONDS)$(GPO_CONDS)$(SEC_CONDS)$(SYSTEMD_CONDS)$(FILES_CONDS)$(KCM_CONDS)$(STAP_CONDS)$(CRYPTO_CONDS)$(LOCAL_PROVIDER_CONDS) - - - #Special Rules: -diff --git a/src/man/include/seealso.xml b/src/man/include/seealso.xml -index 52798e460e0a00ab436a4f4fa071cee104e1bb8b..f324b663717c44e8efdaae0409e28d04b9300ae7 100644 ---- a/src/man/include/seealso.xml -+++ b/src/man/include/seealso.xml -@@ -44,27 +44,29 @@ - - sss_debuglevel8 - , -- -- sss_groupadd8 -- , -- -- sss_groupdel8 -- , -- -- sss_groupshow8 -- , -- -- sss_groupmod8 -- , -- -- sss_useradd8 -- , -- -- sss_userdel8 -- , -- -- sss_usermod8 -- , -+ -+ -+ sss_groupadd8 -+ , -+ -+ sss_groupdel8 -+ , -+ -+ sss_groupshow8 -+ , -+ -+ sss_groupmod8 -+ , -+ -+ sss_useradd8 -+ , -+ -+ sss_userdel8 -+ , -+ -+ sss_usermod8 -+ , -+ - - sss_obfuscate8 - , -diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml -index 04143f199685b7703abe1b5bb82b6c33230e6c72..c1e38950f99cb8df4c59fe10866632030d3c6f25 100644 ---- a/src/man/sssd.conf.5.xml -+++ b/src/man/sssd.conf.5.xml -@@ -2179,7 +2179,7 @@ pam_p11_allowed_services = +my_pam_service, -login - - proxy: Support a legacy NSS provider. - -- -+ - local: SSSD internal provider for - local users (DEPRECATED). - -@@ -2324,7 +2324,7 @@ pam_p11_allowed_services = +my_pam_service, -login - - proxy for relaying authentication to some other PAM target. - -- -+ - local: SSSD internal provider for - local users - -@@ -2836,9 +2836,12 @@ pam_p11_allowed_services = +my_pam_service, -login - case_sensitive (string) - - -- Treat user and group names as case sensitive. At -- the moment, this option is not supported in -- the local provider. Possible option values are: -+ Treat user and group names as case sensitive. -+ -+ At the moment, this option is not supported in -+ the local provider. -+ -+ Possible option values are: - - - True -@@ -3148,7 +3151,7 @@ ldap_user_extra_attrs = phone:telephoneNumber - - - -- -+ - The local domain section - - This section contains settings for domain that stores users and --- -2.14.4 diff --git a/SOURCES/0029-BE-Make-be_refresh_ctx_init-set-up-the-periodical-ta.patch b/SOURCES/0029-BE-Make-be_refresh_ctx_init-set-up-the-periodical-ta.patch new file mode 100644 index 0000000..005a505 --- /dev/null +++ b/SOURCES/0029-BE-Make-be_refresh_ctx_init-set-up-the-periodical-ta.patch @@ -0,0 +1,111 @@ +From 47c33b9c8b8613956ed4687d58e26cb9fe7dc9eb Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 20 May 2019 22:32:13 +0200 +Subject: [PATCH 29/48] BE: Make be_refresh_ctx_init set up the periodical + task, too + +This is mostly a preparatory patch that rolls in setting up the ptask +into be_refresh_ctx_init. Since in later patches we will call +be_refresh_ctx_init from several different places, this will prevent +code duplication. + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + src/providers/be_refresh.c | 21 +++++++++++++++++++-- + src/providers/be_refresh.h | 2 +- + src/providers/data_provider_be.c | 14 -------------- + 3 files changed, 20 insertions(+), 17 deletions(-) + +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index 02e478c95..c7b048a95 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -134,11 +134,13 @@ struct be_refresh_ctx { + struct be_refresh_cb callbacks[BE_REFRESH_TYPE_SENTINEL]; + }; + +-struct be_refresh_ctx *be_refresh_ctx_init(TALLOC_CTX *mem_ctx) ++struct be_refresh_ctx *be_refresh_ctx_init(struct be_ctx *be_ctx) + { + struct be_refresh_ctx *ctx = NULL; ++ uint32_t refresh_interval; ++ errno_t ret; + +- ctx = talloc_zero(mem_ctx, struct be_refresh_ctx); ++ ctx = talloc_zero(be_ctx, struct be_refresh_ctx); + if (ctx == NULL) { + return NULL; + } +@@ -147,6 +149,21 @@ struct be_refresh_ctx *be_refresh_ctx_init(TALLOC_CTX *mem_ctx) + ctx->callbacks[BE_REFRESH_TYPE_GROUPS].name = "groups"; + ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].name = "netgroups"; + ++ refresh_interval = be_ctx->domain->refresh_expired_interval; ++ if (refresh_interval > 0) { ++ ret = be_ptask_create(be_ctx, be_ctx, refresh_interval, 30, 5, 0, ++ refresh_interval, BE_PTASK_OFFLINE_SKIP, 0, ++ be_refresh_send, be_refresh_recv, ++ be_ctx->refresh_ctx, "Refresh Records", NULL); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_FATAL_FAILURE, ++ "Unable to initialize refresh periodic task [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ talloc_free(ctx); ++ return NULL; ++ } ++ } ++ + return ctx; + } + +diff --git a/src/providers/be_refresh.h b/src/providers/be_refresh.h +index 927fa4a33..664f01816 100644 +--- a/src/providers/be_refresh.h ++++ b/src/providers/be_refresh.h +@@ -52,7 +52,7 @@ enum be_refresh_type { + + struct be_refresh_ctx; + +-struct be_refresh_ctx *be_refresh_ctx_init(TALLOC_CTX *mem_ctx); ++struct be_refresh_ctx *be_refresh_ctx_init(struct be_ctx *be_ctx); + + errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, + enum be_refresh_type type, +diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c +index db62efdc6..a1e7999c7 100644 +--- a/src/providers/data_provider_be.c ++++ b/src/providers/data_provider_be.c +@@ -454,7 +454,6 @@ errno_t be_process_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct confdb_ctx *cdb) + { +- uint32_t refresh_interval; + struct tevent_req *req; + struct be_ctx *be_ctx; + char *str = NULL; +@@ -545,19 +544,6 @@ errno_t be_process_init(TALLOC_CTX *mem_ctx, + goto done; + } + +- refresh_interval = be_ctx->domain->refresh_expired_interval; +- if (refresh_interval > 0) { +- ret = be_ptask_create(be_ctx, be_ctx, refresh_interval, 30, 5, 0, +- refresh_interval, BE_PTASK_OFFLINE_SKIP, 0, +- be_refresh_send, be_refresh_recv, +- be_ctx->refresh_ctx, "Refresh Records", NULL); +- if (ret != EOK) { +- DEBUG(SSSDBG_FATAL_FAILURE, +- "Unable to initialize refresh periodic task\n"); +- goto done; +- } +- } +- + req = dp_init_send(be_ctx, be_ctx->ev, be_ctx, be_ctx->uid, be_ctx->gid); + if (req == NULL) { + ret = ENOMEM; +-- +2.20.1 + diff --git a/SOURCES/0029-confdb-log-an-error-when-domain-is-misconfigured.patch b/SOURCES/0029-confdb-log-an-error-when-domain-is-misconfigured.patch deleted file mode 100644 index f8120b9..0000000 --- a/SOURCES/0029-confdb-log-an-error-when-domain-is-misconfigured.patch +++ /dev/null @@ -1,48 +0,0 @@ -From c0d527f9ea9786712b86b5b51c6dab074a66342d Mon Sep 17 00:00:00 2001 -From: Tomas Halman -Date: Mon, 1 Oct 2018 15:49:06 +0200 -Subject: [PATCH] confdb: log an error when domain is misconfigured - -We need to inform user that there is misconfiguration -and particular domain will not be started. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3827 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 081b18e75c746f9a2ad1fb412c825293090311f8) ---- - src/confdb/confdb.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c -index 954c3ba766617f7cfcf637d9143c891bd998d7ff..2f3d90087e640f77835400b11184b684852d7fda 100644 ---- a/src/confdb/confdb.c -+++ b/src/confdb/confdb.c -@@ -39,6 +39,9 @@ - #define SAME_DOMAINS_ERROR_MSG "Domain '%s' is the same as or differs only "\ - "in case from domain '%s'.\n" - -+#define RETRIEVE_DOMAIN_ERROR_MSG "Error (%d [%s]) retrieving domain [%s], "\ -+ "skipping!\n" -+ - static char *prepend_cn(char *str, int *slen, const char *comp, int clen) - { - char *ret; -@@ -1522,8 +1525,12 @@ int confdb_get_domains(struct confdb_ctx *cdb, - ret = confdb_get_domain_internal(cdb, cdb, domlist[i], &domain); - if (ret) { - DEBUG(SSSDBG_FATAL_FAILURE, -- "Error (%d [%s]) retrieving domain [%s], skipping!\n", -+ RETRIEVE_DOMAIN_ERROR_MSG, - ret, sss_strerror(ret), domlist[i]); -+ sss_log(SSS_LOG_CRIT, -+ RETRIEVE_DOMAIN_ERROR_MSG, -+ ret, sss_strerror(ret), domlist[i]); -+ - continue; - } - --- -2.14.4 - diff --git a/SOURCES/0030-BE-LDAP-Call-be_refresh_ctx_init-in-the-provider-lib.patch b/SOURCES/0030-BE-LDAP-Call-be_refresh_ctx_init-in-the-provider-lib.patch new file mode 100644 index 0000000..f099332 --- /dev/null +++ b/SOURCES/0030-BE-LDAP-Call-be_refresh_ctx_init-in-the-provider-lib.patch @@ -0,0 +1,143 @@ +From 4f32364e1a516cdcd311d369142e93d90a48e11c Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 20 May 2019 22:42:47 +0200 +Subject: [PATCH 30/48] BE/LDAP: Call be_refresh_ctx_init() in the provider + libraries, not in back end + +Since later patches will pass different parameters to +be_refresh_ctx_init(), let's call the init function in the provider +libraries not directly in the back end. + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + src/providers/ad/ad_init.c | 2 +- + src/providers/data_provider_be.c | 8 -------- + src/providers/ipa/ipa_init.c | 2 +- + src/providers/ldap/ldap_common.h | 2 +- + src/providers/ldap/ldap_init.c | 2 +- + src/providers/ldap/sdap_refresh.c | 17 +++++++++++++---- + 6 files changed, 17 insertions(+), 16 deletions(-) + +diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c +index 423071dcd..b8ebaea2f 100644 +--- a/src/providers/ad/ad_init.c ++++ b/src/providers/ad/ad_init.c +@@ -408,7 +408,7 @@ static errno_t ad_init_misc(struct be_ctx *be_ctx, + return ret; + } + +- ret = sdap_refresh_init(be_ctx->refresh_ctx, sdap_id_ctx); ++ ret = sdap_refresh_init(be_ctx, sdap_id_ctx); + if (ret != EOK && ret != EEXIST) { + DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh " + "will not work [%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c +index a1e7999c7..877841055 100644 +--- a/src/providers/data_provider_be.c ++++ b/src/providers/data_provider_be.c +@@ -536,14 +536,6 @@ errno_t be_process_init(TALLOC_CTX *mem_ctx, + goto done; + } + +- /* Initialize be_refresh periodic task. */ +- be_ctx->refresh_ctx = be_refresh_ctx_init(be_ctx); +- if (be_ctx->refresh_ctx == NULL) { +- DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n"); +- ret = ENOMEM; +- goto done; +- } +- + req = dp_init_send(be_ctx, be_ctx->ev, be_ctx, be_ctx->uid, be_ctx->gid); + if (req == NULL) { + ret = ENOMEM; +diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c +index 6818e2171..b3060e228 100644 +--- a/src/providers/ipa/ipa_init.c ++++ b/src/providers/ipa/ipa_init.c +@@ -594,7 +594,7 @@ static errno_t ipa_init_misc(struct be_ctx *be_ctx, + } + } + +- ret = sdap_refresh_init(be_ctx->refresh_ctx, sdap_id_ctx); ++ ret = sdap_refresh_init(be_ctx, sdap_id_ctx); + if (ret != EOK && ret != EEXIST) { + DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh " + "will not work [%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h +index 5d6302dcd..60e3ef297 100644 +--- a/src/providers/ldap/ldap_common.h ++++ b/src/providers/ldap/ldap_common.h +@@ -365,7 +365,7 @@ struct sdap_id_ctx * + sdap_id_ctx_new(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, + struct sdap_service *sdap_service); + +-errno_t sdap_refresh_init(struct be_refresh_ctx *refresh_ctx, ++errno_t sdap_refresh_init(struct be_ctx *be_ctx, + struct sdap_id_ctx *id_ctx); + + errno_t sdap_init_certmap(TALLOC_CTX *mem_ctx, struct sdap_id_ctx *id_ctx); +diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c +index 057e173ad..3ce574e28 100644 +--- a/src/providers/ldap/ldap_init.c ++++ b/src/providers/ldap/ldap_init.c +@@ -432,7 +432,7 @@ static errno_t ldap_init_misc(struct be_ctx *be_ctx, + } + + /* Setup periodical refresh of expired records */ +- ret = sdap_refresh_init(be_ctx->refresh_ctx, id_ctx); ++ ret = sdap_refresh_init(be_ctx, id_ctx); + if (ret != EOK && ret != EEXIST) { + DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh will not work " + "[%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index 6d6c43e20..457df8be2 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -255,12 +255,19 @@ static errno_t sdap_refresh_netgroups_recv(struct tevent_req *req) + return sdap_refresh_recv(req); + } + +-errno_t sdap_refresh_init(struct be_refresh_ctx *refresh_ctx, ++errno_t sdap_refresh_init(struct be_ctx *be_ctx, + struct sdap_id_ctx *id_ctx) + { + errno_t ret; + +- ret = be_refresh_add_cb(refresh_ctx, BE_REFRESH_TYPE_USERS, ++ be_ctx->refresh_ctx = be_refresh_ctx_init(be_ctx); ++ if (be_ctx->refresh_ctx == NULL) { ++ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n"); ++ return ENOMEM; ++ } ++ ++ ret = be_refresh_add_cb(be_ctx->refresh_ctx, ++ BE_REFRESH_TYPE_USERS, + sdap_refresh_users_send, + sdap_refresh_users_recv, + id_ctx); +@@ -269,7 +276,8 @@ errno_t sdap_refresh_init(struct be_refresh_ctx *refresh_ctx, + "will not work [%d]: %s\n", ret, strerror(ret)); + } + +- ret = be_refresh_add_cb(refresh_ctx, BE_REFRESH_TYPE_GROUPS, ++ ret = be_refresh_add_cb(be_ctx->refresh_ctx, ++ BE_REFRESH_TYPE_USERS, + sdap_refresh_groups_send, + sdap_refresh_groups_recv, + id_ctx); +@@ -278,7 +286,8 @@ errno_t sdap_refresh_init(struct be_refresh_ctx *refresh_ctx, + "will not work [%d]: %s\n", ret, strerror(ret)); + } + +- ret = be_refresh_add_cb(refresh_ctx, BE_REFRESH_TYPE_NETGROUPS, ++ ret = be_refresh_add_cb(be_ctx->refresh_ctx, ++ BE_REFRESH_TYPE_USERS, + sdap_refresh_netgroups_send, + sdap_refresh_netgroups_recv, + id_ctx); +-- +2.20.1 + diff --git a/SOURCES/0030-be-use-be_is_offline-for-the-main-domain-when-asking.patch b/SOURCES/0030-be-use-be_is_offline-for-the-main-domain-when-asking.patch deleted file mode 100644 index 30cb266..0000000 --- a/SOURCES/0030-be-use-be_is_offline-for-the-main-domain-when-asking.patch +++ /dev/null @@ -1,58 +0,0 @@ -From c9c4b9cbe87e39d3305be2217535d25d1b272af6 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Fri, 14 Sep 2018 12:30:57 +0200 -Subject: [PATCH] be: use be_is_offline for the main domain when asking for - domain status -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The DOM_ACTIVE/INACTIVE flag is not used with the main domain as it -is used only for subdomains. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3830 - -Reviewed-by: Michal Židek -(cherry picked from commit dfa7bf1133f002a9fbbd3495a70909913db25b16) ---- - src/providers/data_provider/dp_iface_backend.c | 20 ++++++++++++++------ - 1 file changed, 14 insertions(+), 6 deletions(-) - -diff --git a/src/providers/data_provider/dp_iface_backend.c b/src/providers/data_provider/dp_iface_backend.c -index 25a00f327116bdf513a939c3b68dae375a1d0538..85159a71be603ffadaa7bd2bd5f3bcf03c0a3eca 100644 ---- a/src/providers/data_provider/dp_iface_backend.c -+++ b/src/providers/data_provider/dp_iface_backend.c -@@ -37,15 +37,23 @@ dp_backend_is_online(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain; - - if (SBUS_REQ_STRING_IS_EMPTY(domname)) { -- *_is_online = be_is_offline(be_ctx); -- return EOK; -+ domain = be_ctx->domain; -+ } else { -+ domain = find_domain_by_name(be_ctx->domain, domname, false); -+ if (domain == NULL) { -+ return ERR_DOMAIN_NOT_FOUND; -+ } - } - -- domain = find_domain_by_name(be_ctx->domain, domname, false); -- if (domain == NULL) { -- return ERR_DOMAIN_NOT_FOUND; -+ /** -+ * FIXME: https://pagure.io/SSSD/sssd/issue/3831 -+ * domain->state is set only for subdomains not for the main domain -+ */ -+ if (be_ctx->domain == domain) { -+ *_is_online = be_is_offline(be_ctx) == false; -+ } else { -+ *_is_online = domain->state == DOM_ACTIVE; - } - -- *_is_online = domain->state == DOM_ACTIVE; - return EOK; - } --- -2.14.4 - diff --git a/SOURCES/0031-BE-Pass-in-attribute-to-look-up-with-instead-of-hard.patch b/SOURCES/0031-BE-Pass-in-attribute-to-look-up-with-instead-of-hard.patch new file mode 100644 index 0000000..61161cd --- /dev/null +++ b/SOURCES/0031-BE-Pass-in-attribute-to-look-up-with-instead-of-hard.patch @@ -0,0 +1,108 @@ +From 828edc4089ef570245081afb3bf81bbad4c9f91a Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 21 May 2019 12:09:24 +0200 +Subject: [PATCH 31/48] BE: Pass in attribute to look up with instead of + hardcoding SYSDB_NAME + +In later patches, we will implement refreshes for AD or IPA which might +refresh objects that do not have a name yet, but always do have a different +attribute, like a SID or a uniqueID. In this case, it's better to use that +different attribute instead of name. + +This patch allows the caller to tell the refresh module which attribute +to use. + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + src/providers/be_refresh.c | 12 ++++++++---- + src/providers/be_refresh.h | 3 ++- + src/providers/ldap/sdap_refresh.c | 2 +- + 3 files changed, 11 insertions(+), 6 deletions(-) + +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index c7b048a95..66cc4cf98 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -89,6 +89,7 @@ done: + + static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx, + enum be_refresh_type type, ++ const char *attr_name, + struct sss_domain_info *domain, + time_t period, + char ***_values) +@@ -116,7 +117,7 @@ static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx, + } + + ret = be_refresh_get_values_ex(mem_ctx, domain, period, +- base_dn, SYSDB_NAME, _values); ++ base_dn, attr_name, _values); + + talloc_free(base_dn); + return ret; +@@ -131,10 +132,12 @@ struct be_refresh_cb { + }; + + struct be_refresh_ctx { ++ const char *attr_name; + struct be_refresh_cb callbacks[BE_REFRESH_TYPE_SENTINEL]; + }; + +-struct be_refresh_ctx *be_refresh_ctx_init(struct be_ctx *be_ctx) ++struct be_refresh_ctx *be_refresh_ctx_init(struct be_ctx *be_ctx, ++ const char *attr_name) + { + struct be_refresh_ctx *ctx = NULL; + uint32_t refresh_interval; +@@ -145,6 +148,7 @@ struct be_refresh_ctx *be_refresh_ctx_init(struct be_ctx *be_ctx) + return NULL; + } + ++ ctx->attr_name = attr_name; + ctx->callbacks[BE_REFRESH_TYPE_USERS].name = "users"; + ctx->callbacks[BE_REFRESH_TYPE_GROUPS].name = "groups"; + ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].name = "netgroups"; +@@ -284,8 +288,8 @@ static errno_t be_refresh_step(struct tevent_req *req) + goto done; + } + +- ret = be_refresh_get_values(state, state->index, state->domain, +- state->period, &values); ++ ret = be_refresh_get_values(state, state->index, state->ctx->attr_name, ++ state->domain, state->period, &values); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain DN list [%d]: %s\n", + ret, sss_strerror(ret)); +diff --git a/src/providers/be_refresh.h b/src/providers/be_refresh.h +index 664f01816..8c7b1d0ba 100644 +--- a/src/providers/be_refresh.h ++++ b/src/providers/be_refresh.h +@@ -52,7 +52,8 @@ enum be_refresh_type { + + struct be_refresh_ctx; + +-struct be_refresh_ctx *be_refresh_ctx_init(struct be_ctx *be_ctx); ++struct be_refresh_ctx *be_refresh_ctx_init(struct be_ctx *be_ctx, ++ const char *attr_name); + + errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, + enum be_refresh_type type, +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index 457df8be2..ed04da36a 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -260,7 +260,7 @@ errno_t sdap_refresh_init(struct be_ctx *be_ctx, + { + errno_t ret; + +- be_ctx->refresh_ctx = be_refresh_ctx_init(be_ctx); ++ be_ctx->refresh_ctx = be_refresh_ctx_init(be_ctx, SYSDB_NAME); + if (be_ctx->refresh_ctx == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n"); + return ENOMEM; +-- +2.20.1 + diff --git a/SOURCES/0031-sudo-respect-case-sensitivity-in-sudo-responder.patch b/SOURCES/0031-sudo-respect-case-sensitivity-in-sudo-responder.patch deleted file mode 100644 index aa983bd..0000000 --- a/SOURCES/0031-sudo-respect-case-sensitivity-in-sudo-responder.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 2b8665e50f601e2b707b0bc77690821211a79e2d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Thu, 6 Sep 2018 13:38:56 +0200 -Subject: [PATCH] sudo: respect case sensitivity in sudo responder -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If the domain is not case sensitive and the case of the original user -or group name differs from the name in the rule we failed to find the -rule. - -Now we filter the rule only with lower cased values in such domain. - -Steps to reproduce: -1. Add user/group with upper case, e.g. USER-1 -2. Add sudo rule with lower cased name, e.g. sudoUser: user-1 -3. Login to system with lower case, e.g. user-1 -4. Run sudo -l - -Without the patch, rule is not found. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3820 - -Reviewed-by: Michal Židek -(cherry picked from commit d7f0b58e2896ed2ef9ed5a390815c1e4df6caaee) ---- - src/db/sysdb_sudo.c | 17 ++++++++++++++--- - 1 file changed, 14 insertions(+), 3 deletions(-) - -diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c -index 3ad462d8fd131bfc6bc5aa15bc48346d64241ee6..19ed97b8666c92c491131765398423062791ba0a 100644 ---- a/src/db/sysdb_sudo.c -+++ b/src/db/sysdb_sudo.c -@@ -418,7 +418,17 @@ sysdb_get_sudo_user_info(TALLOC_CTX *mem_ctx, - ret = EINVAL; - goto done; - } -- DEBUG(SSSDBG_TRACE_FUNC, "original name: %s\n", orig_name); -+ -+ DEBUG(SSSDBG_TRACE_FUNC, "Original name: %s\n", orig_name); -+ -+ orig_name = sss_get_cased_name(tmp_ctx, orig_name, domain->case_sensitive); -+ if (orig_name == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory!\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ DEBUG(SSSDBG_TRACE_FUNC, "Cased name: %s\n", orig_name); - - if (_uid != NULL) { - uid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM, 0); -@@ -450,8 +460,9 @@ sysdb_get_sudo_user_info(TALLOC_CTX *mem_ctx, - continue; - } - -- sysdb_groupnames[num_groups] = talloc_strdup(sysdb_groupnames, -- groupname); -+ sysdb_groupnames[num_groups] = \ -+ sss_get_cased_name(sysdb_groupnames, groupname, -+ domain->case_sensitive); - if (sysdb_groupnames[num_groups] == NULL) { - DEBUG(SSSDBG_MINOR_FAILURE, "Cannot strdup %s\n", groupname); - continue; --- -2.14.4 - diff --git a/SOURCES/0032-BE-Change-be_refresh_ctx_init-to-return-errno-and-se.patch b/SOURCES/0032-BE-Change-be_refresh_ctx_init-to-return-errno-and-se.patch new file mode 100644 index 0000000..72be1ee --- /dev/null +++ b/SOURCES/0032-BE-Change-be_refresh_ctx_init-to-return-errno-and-se.patch @@ -0,0 +1,99 @@ +From 87ae9cf0fd747e39d1769e6b432b7f48d41f9302 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 21 May 2019 12:07:34 +0200 +Subject: [PATCH 32/48] BE: Change be_refresh_ctx_init to return errno and set + be_ctx->refresh_ctx + +It is a bit odd that a caller to a be_ function would set a property of +be_ctx. IMO it is cleaner if the function has a side-effect and sets the +property internally and rather returns errno. + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + src/providers/be_refresh.c | 13 +++++++------ + src/providers/be_refresh.h | 4 ++-- + src/providers/ldap/sdap_refresh.c | 4 ++-- + 3 files changed, 11 insertions(+), 10 deletions(-) + +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index 66cc4cf98..8a6e1ba58 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -136,8 +136,8 @@ struct be_refresh_ctx { + struct be_refresh_cb callbacks[BE_REFRESH_TYPE_SENTINEL]; + }; + +-struct be_refresh_ctx *be_refresh_ctx_init(struct be_ctx *be_ctx, +- const char *attr_name) ++errno_t be_refresh_ctx_init(struct be_ctx *be_ctx, ++ const char *attr_name) + { + struct be_refresh_ctx *ctx = NULL; + uint32_t refresh_interval; +@@ -145,7 +145,7 @@ struct be_refresh_ctx *be_refresh_ctx_init(struct be_ctx *be_ctx, + + ctx = talloc_zero(be_ctx, struct be_refresh_ctx); + if (ctx == NULL) { +- return NULL; ++ return ENOMEM; + } + + ctx->attr_name = attr_name; +@@ -158,17 +158,18 @@ struct be_refresh_ctx *be_refresh_ctx_init(struct be_ctx *be_ctx, + ret = be_ptask_create(be_ctx, be_ctx, refresh_interval, 30, 5, 0, + refresh_interval, BE_PTASK_OFFLINE_SKIP, 0, + be_refresh_send, be_refresh_recv, +- be_ctx->refresh_ctx, "Refresh Records", NULL); ++ ctx, "Refresh Records", NULL); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Unable to initialize refresh periodic task [%d]: %s\n", + ret, sss_strerror(ret)); + talloc_free(ctx); +- return NULL; ++ return ret; + } + } + +- return ctx; ++ be_ctx->refresh_ctx = ctx; ++ return EOK; + } + + errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, +diff --git a/src/providers/be_refresh.h b/src/providers/be_refresh.h +index 8c7b1d0ba..980ac7d06 100644 +--- a/src/providers/be_refresh.h ++++ b/src/providers/be_refresh.h +@@ -52,8 +52,8 @@ enum be_refresh_type { + + struct be_refresh_ctx; + +-struct be_refresh_ctx *be_refresh_ctx_init(struct be_ctx *be_ctx, +- const char *attr_name); ++errno_t be_refresh_ctx_init(struct be_ctx *be_ctx, ++ const char *attr_name); + + errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, + enum be_refresh_type type, +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index ed04da36a..baa7fa59f 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -260,8 +260,8 @@ errno_t sdap_refresh_init(struct be_ctx *be_ctx, + { + errno_t ret; + +- be_ctx->refresh_ctx = be_refresh_ctx_init(be_ctx, SYSDB_NAME); +- if (be_ctx->refresh_ctx == NULL) { ++ ret = be_refresh_ctx_init(be_ctx, SYSDB_NAME); ++ if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n"); + return ENOMEM; + } +-- +2.20.1 + diff --git a/SOURCES/0032-sbus-fix-typo.patch b/SOURCES/0032-sbus-fix-typo.patch deleted file mode 100644 index af080fc..0000000 --- a/SOURCES/0032-sbus-fix-typo.patch +++ /dev/null @@ -1,27 +0,0 @@ -From fd7cb6f2605a60770a7f83e431b16bb888b5df45 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Thu, 16 Aug 2018 11:42:44 +0200 -Subject: [PATCH 32/47] sbus: fix typo - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 8c8f74b0dfa29643279d31b12300ced47d5c2ab5) ---- - src/sbus/sbus_message.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/sbus/sbus_message.h b/src/sbus/sbus_message.h -index 99dd9309b8ced478b4f9bb761db99000440ef105..92d5cea83b3c19ac19701849972a82ce67b09849 100644 ---- a/src/sbus/sbus_message.h -+++ b/src/sbus/sbus_message.h -@@ -49,7 +49,7 @@ sbus_message_bound(TALLOC_CTX *mem_ctx, DBusMessage *msg); - * - * DO NOT USE dbus_message_unref() on such message anymore since it would not - * release internal data about the bound. The message will be automatically -- * unreferenced whent the talloc context is freed. -+ * unreferenced when the talloc context is freed. - * - * @param mem_ctx Memory context to bound the message with. It can not be NULL. - * @param msg Message to be bound with memory context. --- -2.14.4 - diff --git a/SOURCES/0033-BE-LDAP-Split-out-a-helper-function-from-sdap_refres.patch b/SOURCES/0033-BE-LDAP-Split-out-a-helper-function-from-sdap_refres.patch new file mode 100644 index 0000000..0523de5 --- /dev/null +++ b/SOURCES/0033-BE-LDAP-Split-out-a-helper-function-from-sdap_refres.patch @@ -0,0 +1,131 @@ +From 003f8647f9dbeec1a54060fb4e376f04865aafea Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 8 May 2019 14:38:44 +0200 +Subject: [PATCH 33/48] BE/LDAP: Split out a helper function from sdap_refresh + for later reuse + +Every refresh request will send a similar account_req. Let's split out +the function that creates the account_req into a reusable one. + +Also removes the type string as it was only used in DEBUG messages and +there is already a function in the back end API that provides the same +functionality. + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + src/providers/be_refresh.c | 18 ++++++++++++++++++ + src/providers/be_refresh.h | 4 ++++ + src/providers/ldap/sdap_refresh.c | 29 +++++------------------------ + 3 files changed, 27 insertions(+), 24 deletions(-) + +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index 8a6e1ba58..c49229e71 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -362,3 +362,21 @@ errno_t be_refresh_recv(struct tevent_req *req) + + return EOK; + } ++ ++struct dp_id_data *be_refresh_acct_req(TALLOC_CTX *mem_ctx, ++ uint32_t entry_type, ++ struct sss_domain_info *domain) ++{ ++ struct dp_id_data *account_req; ++ ++ account_req = talloc_zero(mem_ctx, struct dp_id_data); ++ if (account_req == NULL) { ++ return NULL; ++ } ++ ++ account_req->entry_type = entry_type; ++ account_req->filter_type = BE_FILTER_NAME; ++ account_req->extra_value = NULL; ++ account_req->domain = domain->name; ++ return account_req; ++} +diff --git a/src/providers/be_refresh.h b/src/providers/be_refresh.h +index 980ac7d06..b7ba5d4c2 100644 +--- a/src/providers/be_refresh.h ++++ b/src/providers/be_refresh.h +@@ -69,4 +69,8 @@ struct tevent_req *be_refresh_send(TALLOC_CTX *mem_ctx, + + errno_t be_refresh_recv(struct tevent_req *req); + ++struct dp_id_data *be_refresh_acct_req(TALLOC_CTX *mem_ctx, ++ uint32_t entry_type, ++ struct sss_domain_info *domain); ++ + #endif /* _DP_REFRESH_H_ */ +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index baa7fa59f..af39d8686 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -30,7 +30,6 @@ struct sdap_refresh_state { + struct dp_id_data *account_req; + struct sdap_id_ctx *id_ctx; + struct sdap_domain *sdom; +- const char *type; + char **names; + size_t index; + }; +@@ -74,32 +73,12 @@ static struct tevent_req *sdap_refresh_send(TALLOC_CTX *mem_ctx, + goto immediately; + } + +- switch (entry_type) { +- case BE_REQ_USER: +- state->type = "user"; +- break; +- case BE_REQ_GROUP: +- state->type = "group"; +- break; +- case BE_REQ_NETGROUP: +- state->type = "netgroup"; +- break; +- default: +- DEBUG(SSSDBG_CRIT_FAILURE, "Invalid entry type [%d]!\n", entry_type); +- } +- +- state->account_req = talloc_zero(state, struct dp_id_data); ++ state->account_req = be_refresh_acct_req(state, entry_type, domain); + if (state->account_req == NULL) { + ret = ENOMEM; + goto immediately; + } + +- state->account_req->entry_type = entry_type; +- state->account_req->filter_type = BE_FILTER_NAME; +- state->account_req->extra_value = NULL; +- state->account_req->domain = domain->name; +- /* filter will be filled later */ +- + ret = sdap_refresh_step(req); + if (ret == EOK) { + DEBUG(SSSDBG_TRACE_FUNC, "Nothing to refresh\n"); +@@ -143,7 +122,8 @@ static errno_t sdap_refresh_step(struct tevent_req *req) + } + + DEBUG(SSSDBG_TRACE_FUNC, "Issuing refresh of %s %s\n", +- state->type, state->account_req->filter_value); ++ be_req2str(state->account_req->entry_type), ++ state->account_req->filter_value); + + subreq = sdap_handle_acct_req_send(state, state->be_ctx, + state->account_req, state->id_ctx, +@@ -178,7 +158,8 @@ static void sdap_refresh_done(struct tevent_req *subreq) + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to refresh %s [dp_error: %d, " +- "sdap_ret: %d, errno: %d]: %s\n", state->type, ++ "sdap_ret: %d, errno: %d]: %s\n", ++ be_req2str(state->account_req->entry_type), + dp_error, sdap_ret, ret, err_msg); + goto done; + } +-- +2.20.1 + diff --git a/SOURCES/0033-sbus-check-for-null-message-in-sbus_message_bound.patch b/SOURCES/0033-sbus-check-for-null-message-in-sbus_message_bound.patch deleted file mode 100644 index e257239..0000000 --- a/SOURCES/0033-sbus-check-for-null-message-in-sbus_message_bound.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 25ccb26a6c58cf7284e900588bf68ce6eec21b4c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Thu, 16 Aug 2018 12:57:47 +0200 -Subject: [PATCH 33/47] sbus: check for null message in sbus_message_bound - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 30f4adf874aff174734ad77902a79fc5727ab495) ---- - src/sbus/request/sbus_message.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/src/sbus/request/sbus_message.c b/src/sbus/request/sbus_message.c -index 950be9122610f3394d982173a3616f9d9fac23d9..7314fd724dd3daec520ba0d1fdd2974995446e8c 100644 ---- a/src/sbus/request/sbus_message.c -+++ b/src/sbus/request/sbus_message.c -@@ -83,6 +83,11 @@ sbus_message_bound(TALLOC_CTX *mem_ctx, DBusMessage *msg) - return EINVAL; - } - -+ if (msg == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Message can not be NULL!\n"); -+ return EINVAL; -+ } -+ - /* Create a talloc context that will unreference this message when - * the parent context is freed. */ - talloc_msg = talloc(mem_ctx, struct sbus_talloc_msg); -@@ -122,6 +127,11 @@ sbus_message_bound(TALLOC_CTX *mem_ctx, DBusMessage *msg) - errno_t - sbus_message_bound_ref(TALLOC_CTX *mem_ctx, DBusMessage *msg) - { -+ if (msg == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Message can not be NULL!\n"); -+ return EINVAL; -+ } -+ - dbus_message_ref(msg); - return sbus_message_bound(mem_ctx, msg); - } --- -2.14.4 - diff --git a/SOURCES/0034-BE-Pass-in-filter_type-when-creating-the-refresh-acc.patch b/SOURCES/0034-BE-Pass-in-filter_type-when-creating-the-refresh-acc.patch new file mode 100644 index 0000000..9ac5adf --- /dev/null +++ b/SOURCES/0034-BE-Pass-in-filter_type-when-creating-the-refresh-acc.patch @@ -0,0 +1,70 @@ +From 91f0382974ca7ed158ddb3da179b41c96292cc19 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 21 May 2019 12:07:59 +0200 +Subject: [PATCH 34/48] BE: Pass in filter_type when creating the refresh + account request + +For refreshing AD users and groups, we'll want to create a request by +SID, for all other requests we'll want to create a request by name. This +patch allows parametrizing the request creation by the caller. + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + src/providers/be_refresh.c | 3 ++- + src/providers/be_refresh.h | 1 + + src/providers/ldap/sdap_refresh.c | 3 ++- + 3 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index c49229e71..c4ff71e1f 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -365,6 +365,7 @@ errno_t be_refresh_recv(struct tevent_req *req) + + struct dp_id_data *be_refresh_acct_req(TALLOC_CTX *mem_ctx, + uint32_t entry_type, ++ uint32_t filter_type, + struct sss_domain_info *domain) + { + struct dp_id_data *account_req; +@@ -375,7 +376,7 @@ struct dp_id_data *be_refresh_acct_req(TALLOC_CTX *mem_ctx, + } + + account_req->entry_type = entry_type; +- account_req->filter_type = BE_FILTER_NAME; ++ account_req->filter_type = filter_type; + account_req->extra_value = NULL; + account_req->domain = domain->name; + return account_req; +diff --git a/src/providers/be_refresh.h b/src/providers/be_refresh.h +index b7ba5d4c2..c7b4872df 100644 +--- a/src/providers/be_refresh.h ++++ b/src/providers/be_refresh.h +@@ -71,6 +71,7 @@ errno_t be_refresh_recv(struct tevent_req *req); + + struct dp_id_data *be_refresh_acct_req(TALLOC_CTX *mem_ctx, + uint32_t entry_type, ++ uint32_t filter_type, + struct sss_domain_info *domain); + + #endif /* _DP_REFRESH_H_ */ +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index af39d8686..2206d6670 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -73,7 +73,8 @@ static struct tevent_req *sdap_refresh_send(TALLOC_CTX *mem_ctx, + goto immediately; + } + +- state->account_req = be_refresh_acct_req(state, entry_type, domain); ++ state->account_req = be_refresh_acct_req(state, entry_type, ++ BE_FILTER_NAME, domain); + if (state->account_req == NULL) { + ret = ENOMEM; + goto immediately; +-- +2.20.1 + diff --git a/SOURCES/0034-sbus-replace-sbus_message_bound_ref-with-sbus_messag.patch b/SOURCES/0034-sbus-replace-sbus_message_bound_ref-with-sbus_messag.patch deleted file mode 100644 index 2fb9d4f..0000000 --- a/SOURCES/0034-sbus-replace-sbus_message_bound_ref-with-sbus_messag.patch +++ /dev/null @@ -1,337 +0,0 @@ -From 7ece0bc4b566ab0b7b5596924983d3a84c372836 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Thu, 16 Aug 2018 13:17:13 +0200 -Subject: [PATCH 34/47] sbus: replace sbus_message_bound_ref with - sbus_message_bound_steal - -The memory context used to new message reference accidentally overwrote -the one use by the initial sbus_message_bound call. This caused a memory -leak of message as its reference counter got increased but number of -talloc contexts bound this this message decreased at the same time. - -Fixing this is non-trival and it would require separate data slot for -each reference. Because we do not have any existing use case for this -and we use it only as an equivalent of talloc_steal it is better to -provide a real equivalent for this talloc function. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3810 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit ca50c40511f08c0f7c786598e5793a06789c6cce) ---- - src/responder/ifp/ifp_iface/sbus_ifp_client_sync.c | 4 +- - src/sbus/codegen/templates/client_async.c.tpl | 4 +- - src/sbus/codegen/templates/client_sync.c.tpl | 4 +- - src/sbus/interface_dbus/sbus_dbus_client_async.c | 8 ++-- - src/sbus/interface_dbus/sbus_dbus_client_sync.c | 8 ++-- - src/sbus/request/sbus_message.c | 51 +++++++++++++++++----- - src/sbus/request/sbus_request.c | 10 ++--- - src/sbus/request/sbus_request_call.c | 5 +-- - src/sbus/sbus_message.h | 8 +--- - src/sbus/sync/sbus_sync_call.c | 5 +-- - 10 files changed, 65 insertions(+), 42 deletions(-) - -diff --git a/src/responder/ifp/ifp_iface/sbus_ifp_client_sync.c b/src/responder/ifp/ifp_iface/sbus_ifp_client_sync.c -index 4859b93ea8fe793f1cca3712663aedd25de25a86..1f0a8e367905e20e921e9a31714b9c7de53f47cd 100644 ---- a/src/responder/ifp/ifp_iface/sbus_ifp_client_sync.c -+++ b/src/responder/ifp/ifp_iface/sbus_ifp_client_sync.c -@@ -526,9 +526,9 @@ sbus_method_in_sas_out_raw - goto done; - } - -- ret = sbus_message_bound_ref(mem_ctx, reply); -+ ret = sbus_message_bound_steal(mem_ctx, reply); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to bound message [%d]: %s\n", -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", - ret, sss_strerror(ret)); - goto done; - } -diff --git a/src/sbus/codegen/templates/client_async.c.tpl b/src/sbus/codegen/templates/client_async.c.tpl -index 6ffb4f83c77bd33653011bfcf5008ce86a89e099..e16ce42c7f97e3b4b564570fb73faaa9a5c274c8 100644 ---- a/src/sbus/codegen/templates/client_async.c.tpl -+++ b/src/sbus/codegen/templates/client_async.c.tpl -@@ -193,9 +193,9 @@ - return EINVAL; - } - -- ret = sbus_message_bound_ref(mem_ctx, state->reply); -+ ret = sbus_message_bound_steal(mem_ctx, state->reply); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to bound message [%d]: %s\n", -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", - ret, sss_strerror(ret)); - return ret; - } -diff --git a/src/sbus/codegen/templates/client_sync.c.tpl b/src/sbus/codegen/templates/client_sync.c.tpl -index 30fa009fe6f010483ff58d369451c272dfdbd3ec..fe9a3a4726014aa2bcb221a1bbcc949f7d900237 100644 ---- a/src/sbus/codegen/templates/client_sync.c.tpl -+++ b/src/sbus/codegen/templates/client_sync.c.tpl -@@ -110,9 +110,9 @@ - goto done; - } - -- ret = sbus_message_bound_ref(mem_ctx, reply); -+ ret = sbus_message_bound_steal(mem_ctx, reply); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to bound message [%d]: %s\n", -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", - ret, sss_strerror(ret)); - goto done; - } -diff --git a/src/sbus/interface_dbus/sbus_dbus_client_async.c b/src/sbus/interface_dbus/sbus_dbus_client_async.c -index 9dbd72cedc95e328d6659283e959c554c39797dc..0060e8b91d5d0c2073558818bd529fda9c97b3f8 100644 ---- a/src/sbus/interface_dbus/sbus_dbus_client_async.c -+++ b/src/sbus/interface_dbus/sbus_dbus_client_async.c -@@ -301,9 +301,9 @@ sbus_method_in_s_out_raw_recv - return EINVAL; - } - -- ret = sbus_message_bound_ref(mem_ctx, state->reply); -+ ret = sbus_message_bound_steal(mem_ctx, state->reply); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to bound message [%d]: %s\n", -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", - ret, sss_strerror(ret)); - return ret; - } -@@ -513,9 +513,9 @@ sbus_method_in_ss_out_raw_recv - return EINVAL; - } - -- ret = sbus_message_bound_ref(mem_ctx, state->reply); -+ ret = sbus_message_bound_steal(mem_ctx, state->reply); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to bound message [%d]: %s\n", -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", - ret, sss_strerror(ret)); - return ret; - } -diff --git a/src/sbus/interface_dbus/sbus_dbus_client_sync.c b/src/sbus/interface_dbus/sbus_dbus_client_sync.c -index a0473cd377e97021acea594b48b52f4aa565bad9..3ab0aab452d6b1acb702d577087b1c9fd50b4340 100644 ---- a/src/sbus/interface_dbus/sbus_dbus_client_sync.c -+++ b/src/sbus/interface_dbus/sbus_dbus_client_sync.c -@@ -101,9 +101,9 @@ sbus_method_in_s_out_raw - goto done; - } - -- ret = sbus_message_bound_ref(mem_ctx, reply); -+ ret = sbus_message_bound_steal(mem_ctx, reply); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to bound message [%d]: %s\n", -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", - ret, sss_strerror(ret)); - goto done; - } -@@ -159,9 +159,9 @@ sbus_method_in_ss_out_raw - goto done; - } - -- ret = sbus_message_bound_ref(mem_ctx, reply); -+ ret = sbus_message_bound_steal(mem_ctx, reply); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to bound message [%d]: %s\n", -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", - ret, sss_strerror(ret)); - goto done; - } -diff --git a/src/sbus/request/sbus_message.c b/src/sbus/request/sbus_message.c -index 7314fd724dd3daec520ba0d1fdd2974995446e8c..90c6df40c7882e1f7232d718f8b4a9d1626f755d 100644 ---- a/src/sbus/request/sbus_message.c -+++ b/src/sbus/request/sbus_message.c -@@ -29,8 +29,9 @@ - #include "sbus/interface/sbus_iterator_writers.h" - - /* Data slot that is used for message data. The slot is shared for all -- * messages. */ --dbus_int32_t data_slot = -1; -+ * messages, i.e. when a data slot is allocated all messages have the -+ * slot available. */ -+dbus_int32_t global_data_slot = -1; - - struct sbus_talloc_msg { - DBusMessage *msg; -@@ -48,7 +49,7 @@ static int sbus_talloc_msg_destructor(struct sbus_talloc_msg *talloc_msg) - /* There may exist more references to this message but this talloc - * context is no longer valid. We remove dbus message data to invoke - * dbus destructor now. */ -- dbus_message_set_data(talloc_msg->msg, data_slot, NULL, NULL); -+ dbus_message_set_data(talloc_msg->msg, global_data_slot, NULL, NULL); - dbus_message_unref(talloc_msg->msg); - return 0; - } -@@ -60,7 +61,7 @@ static void sbus_msg_data_destructor(void *ctx) - talloc_msg = talloc_get_type(ctx, struct sbus_talloc_msg); - - /* Decrement ref counter on data slot. */ -- dbus_message_free_data_slot(&data_slot); -+ dbus_message_free_data_slot(&global_data_slot); - - if (!talloc_msg->in_talloc_destructor) { - /* References to this message dropped to zero but through -@@ -100,7 +101,8 @@ sbus_message_bound(TALLOC_CTX *mem_ctx, DBusMessage *msg) - /* Allocate a dbus message data slot that will contain pointer to the - * talloc context so we can pick up cases when the dbus message is - * freed through dbus api. */ -- bret = dbus_message_allocate_data_slot(&data_slot); -+ -+ bret = dbus_message_allocate_data_slot(&global_data_slot); - if (!bret) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to allocate data slot!\n"); - talloc_free(talloc_msg); -@@ -108,11 +110,11 @@ sbus_message_bound(TALLOC_CTX *mem_ctx, DBusMessage *msg) - } - - free_fn = sbus_msg_data_destructor; -- bret = dbus_message_set_data(msg, data_slot, talloc_msg, free_fn); -+ bret = dbus_message_set_data(msg, global_data_slot, talloc_msg, free_fn); - if (!bret) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set message data!\n"); - talloc_free(talloc_msg); -- dbus_message_free_data_slot(&data_slot); -+ dbus_message_free_data_slot(&global_data_slot); - return ENOMEM; - } - -@@ -125,15 +127,44 @@ sbus_message_bound(TALLOC_CTX *mem_ctx, DBusMessage *msg) - } - - errno_t --sbus_message_bound_ref(TALLOC_CTX *mem_ctx, DBusMessage *msg) -+sbus_message_bound_steal(TALLOC_CTX *mem_ctx, DBusMessage *msg) - { -+ struct sbus_talloc_msg *talloc_msg; -+ void *data; -+ -+ if (mem_ctx == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Warning: bounding to NULL context!\n"); -+ return EINVAL; -+ } -+ - if (msg == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Message can not be NULL!\n"); - return EINVAL; - } - -- dbus_message_ref(msg); -- return sbus_message_bound(mem_ctx, msg); -+ if (global_data_slot < 0) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "This message is not talloc-bound! " -+ "(data slot < 0)\n"); -+ return ERR_INTERNAL; -+ } -+ -+ data = dbus_message_get_data(msg, global_data_slot); -+ if (data == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "This message is not talloc-bound! " -+ "(returned data is NULL)\n"); -+ return ERR_INTERNAL; -+ } -+ -+ talloc_msg = talloc_get_type(data, struct sbus_talloc_msg); -+ if (talloc_msg == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "This message is not talloc-bound! " -+ "(invalid data)\n"); -+ return ERR_INTERNAL; -+ } -+ -+ talloc_steal(mem_ctx, talloc_msg); -+ -+ return EOK; - } - - DBusMessage * -diff --git a/src/sbus/request/sbus_request.c b/src/sbus/request/sbus_request.c -index 3d0e2f9e5b0283da7f1d778bf86262db997f12cd..1ccd01e7d571df3c8e196ce7923c8e04523a3b04 100644 ---- a/src/sbus/request/sbus_request.c -+++ b/src/sbus/request/sbus_request.c -@@ -564,10 +564,9 @@ sbus_incoming_request_recv(TALLOC_CTX *mem_ctx, - return EOK; - } - -- /* Create new reference to the reply and bound it with caller mem_ctx. */ -- ret = sbus_message_bound_ref(mem_ctx, state->reply); -+ ret = sbus_message_bound_steal(mem_ctx, state->reply); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to bound message [%d]: %s\n", -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", - ret, sss_strerror(ret)); - return ret; - } -@@ -709,10 +708,9 @@ sbus_outgoing_request_recv(TALLOC_CTX *mem_ctx, - - TEVENT_REQ_RETURN_ON_ERROR(req); - -- /* Create new reference to the reply and bound it with caller mem_ctx. */ -- ret = sbus_message_bound_ref(mem_ctx, state->reply); -+ ret = sbus_message_bound_steal(mem_ctx, state->reply); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to bound message [%d]: %s\n", -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", - ret, sss_strerror(ret)); - return ret; - } -diff --git a/src/sbus/request/sbus_request_call.c b/src/sbus/request/sbus_request_call.c -index 1cf58bdd0aecc5814c24c8f0b87864d91bafd094..cf2a6e5bfb7d403a413b6fc06225b0e7e4b663f3 100644 ---- a/src/sbus/request/sbus_request_call.c -+++ b/src/sbus/request/sbus_request_call.c -@@ -126,10 +126,9 @@ sbus_call_method_recv(TALLOC_CTX *mem_ctx, - - TEVENT_REQ_RETURN_ON_ERROR(req); - -- /* Create new reference to the reply and bound it with caller mem_ctx. */ -- ret = sbus_message_bound_ref(mem_ctx, state->reply); -+ ret = sbus_message_bound_steal(mem_ctx, state->reply); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to bound message [%d]: %s\n", -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", - ret, sss_strerror(ret)); - return ret; - } -diff --git a/src/sbus/sbus_message.h b/src/sbus/sbus_message.h -index 92d5cea83b3c19ac19701849972a82ce67b09849..e7b8fe5942d993fb31740465c6cdbf2797ab0db4 100644 ---- a/src/sbus/sbus_message.h -+++ b/src/sbus/sbus_message.h -@@ -45,11 +45,7 @@ errno_t - sbus_message_bound(TALLOC_CTX *mem_ctx, DBusMessage *msg); - - /** -- * Reference the message and bound it with talloc context. -- * -- * DO NOT USE dbus_message_unref() on such message anymore since it would not -- * release internal data about the bound. The message will be automatically -- * unreferenced when the talloc context is freed. -+ * Steal previously bound D-Bus message to a new talloc parent. - * - * @param mem_ctx Memory context to bound the message with. It can not be NULL. - * @param msg Message to be bound with memory context. -@@ -57,7 +53,7 @@ sbus_message_bound(TALLOC_CTX *mem_ctx, DBusMessage *msg); - * @return EOK on success, other errno code on error. - */ - errno_t --sbus_message_bound_ref(TALLOC_CTX *mem_ctx, DBusMessage *msg); -+sbus_message_bound_steal(TALLOC_CTX *mem_ctx, DBusMessage *msg); - - /** - * Create an empty D-Bus method call. -diff --git a/src/sbus/sync/sbus_sync_call.c b/src/sbus/sync/sbus_sync_call.c -index 8549e5831d4320ffc7831ce8a67f382682d891bb..a4f8a5cc40f4b517fba902ff0dc90d4449d5b3ef 100644 ---- a/src/sbus/sync/sbus_sync_call.c -+++ b/src/sbus/sync/sbus_sync_call.c -@@ -63,10 +63,9 @@ sbus_sync_call_method(TALLOC_CTX *mem_ctx, - goto done; - } - -- /* Create new reference to the reply and bound it with caller mem_ctx. */ -- ret = sbus_message_bound_ref(mem_ctx, reply); -+ ret = sbus_message_bound_steal(mem_ctx, reply); - if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to bound message [%d]: %s\n", -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to steal message [%d]: %s\n", - ret, sss_strerror(ret)); - goto done; - } --- -2.14.4 - diff --git a/SOURCES/0035-BE-Send-refresh-requests-in-batches.patch b/SOURCES/0035-BE-Send-refresh-requests-in-batches.patch new file mode 100644 index 0000000..d15bd97 --- /dev/null +++ b/SOURCES/0035-BE-Send-refresh-requests-in-batches.patch @@ -0,0 +1,297 @@ +From bf3f506d14cf89b9d1d1e3504524b231a6cef2b1 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 8 May 2019 23:16:07 +0200 +Subject: [PATCH 35/48] BE: Send refresh requests in batches + +As we extend the background refresh into larger domains, the amount of +data that SSSD refreshes on the background might be larger. And +refreshing all expired entries in a single request might block sssd_be +for a long time, either triggering the watchdog or starving other +legitimate requests. + +Therefore the background refresh will be done in batches of 200 entries. +The first batch of every type (up to 200 users, up to 200 groups, ...) +will be scheduled imediatelly and subsequent batches with a 0.5 second +delay. + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + src/providers/be_refresh.c | 131 ++++++++++++++++++++++---- + src/tests/cmocka/test_expire_common.c | 6 +- + src/tests/sss_idmap-tests.c | 8 +- + src/util/util.h | 8 ++ + 4 files changed, 128 insertions(+), 25 deletions(-) + +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index c4ff71e1f..5d86509bb 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -204,8 +204,21 @@ struct be_refresh_state { + struct sss_domain_info *domain; + enum be_refresh_type index; + time_t period; ++ ++ char **refresh_values; ++ size_t refresh_val_size; ++ size_t refresh_index; ++ ++ size_t batch_size; ++ char **refresh_batch; + }; + ++static errno_t be_refresh_batch_step(struct tevent_req *req, ++ uint32_t msec_delay); ++static void be_refresh_batch_step_wakeup(struct tevent_context *ev, ++ struct tevent_timer *tt, ++ struct timeval tv, ++ void *pvt); + static errno_t be_refresh_step(struct tevent_req *req); + static void be_refresh_done(struct tevent_req *subreq); + +@@ -236,6 +249,13 @@ struct tevent_req *be_refresh_send(TALLOC_CTX *mem_ctx, + goto immediately; + } + ++ state->batch_size = 200; ++ state->refresh_batch = talloc_zero_array(state, char *, state->batch_size+1); ++ if (state->refresh_batch == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } ++ + ret = be_refresh_step(req); + if (ret == EOK) { + goto immediately; +@@ -261,8 +281,6 @@ immediately: + static errno_t be_refresh_step(struct tevent_req *req) + { + struct be_refresh_state *state = NULL; +- struct tevent_req *subreq = NULL; +- char **values = NULL; + errno_t ret; + + state = tevent_req_data(req, struct be_refresh_state); +@@ -289,42 +307,103 @@ static errno_t be_refresh_step(struct tevent_req *req) + goto done; + } + ++ talloc_zfree(state->refresh_values); + ret = be_refresh_get_values(state, state->index, state->ctx->attr_name, +- state->domain, state->period, &values); ++ state->domain, state->period, ++ &state->refresh_values); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain DN list [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + +- DEBUG(SSSDBG_TRACE_FUNC, "Refreshing %s in domain %s\n", +- state->cb->name, state->domain->name); ++ for (state->refresh_val_size = 0; ++ state->refresh_values[state->refresh_val_size] != NULL; ++ state->refresh_val_size++); ++ ++ DEBUG(SSSDBG_TRACE_FUNC, "Refreshing %zu %s in domain %s\n", ++ state->refresh_val_size, state->cb->name, state->domain->name); + +- subreq = state->cb->send_fn(state, state->ev, state->be_ctx, +- state->domain, values, state->cb->pvt); +- if (subreq == NULL) { +- ret = ENOMEM; ++ ret = be_refresh_batch_step(req, 0); ++ if (ret == EOK) { ++ state->index++; ++ continue; ++ } else if (ret != EAGAIN) { + goto done; + } +- +- /* make the list disappear with subreq */ +- talloc_steal(subreq, values); +- +- tevent_req_set_callback(subreq, be_refresh_done, req); ++ /* EAGAIN only, refreshing something.. */ + + state->index++; +- ret = EAGAIN; + goto done; + } + + ret = EOK; + + done: +- if (ret != EOK && ret != EAGAIN) { +- talloc_free(values); ++ return ret; ++} ++ ++static errno_t be_refresh_batch_step(struct tevent_req *req, ++ uint32_t msec_delay) ++{ ++ struct be_refresh_state *state = tevent_req_data(req, struct be_refresh_state); ++ struct timeval tv; ++ struct tevent_timer *timeout = NULL; ++ ++ size_t remaining; ++ size_t batch_size; ++ ++ memset(state->refresh_batch, 0, sizeof(char *) * state->batch_size); ++ ++ if (state->refresh_index >= state->refresh_val_size) { ++ DEBUG(SSSDBG_FUNC_DATA, "The batch is done\n"); ++ state->refresh_index = 0; ++ return EOK; + } + +- return ret; ++ remaining = state->refresh_val_size - state->refresh_index; ++ batch_size = MIN(remaining, state->batch_size); ++ DEBUG(SSSDBG_FUNC_DATA, ++ "This batch will refresh %zu entries (so far %zu/%zu)\n", ++ batch_size, state->refresh_index, state->refresh_val_size); ++ ++ for (size_t i = 0; i < batch_size; i++) { ++ state->refresh_batch[i] = state->refresh_values[state->refresh_index]; ++ state->refresh_index++; ++ } ++ ++ tv = tevent_timeval_current_ofs(0, msec_delay * 1000); ++ timeout = tevent_add_timer(state->be_ctx->ev, req, tv, ++ be_refresh_batch_step_wakeup, req); ++ if (timeout == NULL) { ++ return ENOMEM; ++ } ++ ++ return EAGAIN; ++} ++ ++static void be_refresh_batch_step_wakeup(struct tevent_context *ev, ++ struct tevent_timer *tt, ++ struct timeval tv, ++ void *pvt) ++{ ++ struct tevent_req *req; ++ struct tevent_req *subreq = NULL; ++ struct be_refresh_state *state = NULL; ++ ++ req = talloc_get_type(pvt, struct tevent_req); ++ state = tevent_req_data(req, struct be_refresh_state); ++ ++ DEBUG(SSSDBG_TRACE_INTERNAL, "Issuing refresh\n"); ++ subreq = state->cb->send_fn(state, state->ev, state->be_ctx, ++ state->domain, ++ state->refresh_batch, ++ state->cb->pvt); ++ if (subreq == NULL) { ++ tevent_req_error(req, ENOMEM); ++ return; ++ } ++ tevent_req_set_callback(subreq, be_refresh_done, req); + } + + static void be_refresh_done(struct tevent_req *subreq) +@@ -342,8 +421,24 @@ static void be_refresh_done(struct tevent_req *subreq) + goto done; + } + ++ ret = be_refresh_batch_step(req, 500); ++ if (ret == EAGAIN) { ++ DEBUG(SSSDBG_TRACE_INTERNAL, ++ "Another batch in this step in progress\n"); ++ return; ++ } else if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "be_refresh_batch_step failed [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ goto done; ++ } ++ ++ DEBUG(SSSDBG_TRACE_INTERNAL, "All batches in this step refreshed\n"); ++ ++ /* Proceed to the next step */ + ret = be_refresh_step(req); + if (ret == EAGAIN) { ++ DEBUG(SSSDBG_TRACE_INTERNAL, "Another step in progress\n"); + return; + } + +diff --git a/src/tests/cmocka/test_expire_common.c b/src/tests/cmocka/test_expire_common.c +index 5d3ea02f3..4f6168190 100644 +--- a/src/tests/cmocka/test_expire_common.c ++++ b/src/tests/cmocka/test_expire_common.c +@@ -32,7 +32,7 @@ + #include "tests/common_check.h" + #include "tests/cmocka/test_expire_common.h" + +-#define MAX 100 ++#define MAX_VAL 100 + + static char *now_str(TALLOC_CTX *mem_ctx, const char* format, int s) + { +@@ -41,10 +41,10 @@ static char *now_str(TALLOC_CTX *mem_ctx, const char* format, int s) + size_t len; + char *timestr; + +- timestr = talloc_array(mem_ctx, char, MAX); ++ timestr = talloc_array(mem_ctx, char, MAX_VAL); + + tm = gmtime(&t); +- len = strftime(timestr, MAX, format, tm); ++ len = strftime(timestr, MAX_VAL, format, tm); + if (len == 0) { + return NULL; + } +diff --git a/src/tests/sss_idmap-tests.c b/src/tests/sss_idmap-tests.c +index 96f0861ac..e5f3f7041 100644 +--- a/src/tests/sss_idmap-tests.c ++++ b/src/tests/sss_idmap-tests.c +@@ -140,8 +140,8 @@ void idmap_add_domain_with_sec_slices_setup_cb_fail(void) + } + + +-#define MAX 1000 +-char data[MAX]; ++#define DATA_MAX 1000 ++char data[DATA_MAX]; + + enum idmap_error_code cb2(const char *dom_name, + const char *dom_sid, +@@ -154,10 +154,10 @@ enum idmap_error_code cb2(const char *dom_name, + char *p = (char*)pvt; + size_t len; + +- len = snprintf(p, MAX, "%s, %s %s, %"PRIu32", %"PRIu32", %" PRIu32, ++ len = snprintf(p, DATA_MAX, "%s, %s %s, %"PRIu32", %"PRIu32", %" PRIu32, + dom_name, dom_sid, range_id, min_id, max_id, first_rid); + +- if (len >= MAX) { ++ if (len >= DATA_MAX) { + return IDMAP_OUT_OF_MEMORY; + } + return IDMAP_SUCCESS; +diff --git a/src/util/util.h b/src/util/util.h +index c5680d89a..13e434b62 100644 +--- a/src/util/util.h ++++ b/src/util/util.h +@@ -67,6 +67,14 @@ + #define NULL 0 + #endif + ++#ifndef MIN ++#define MIN(a, b) (((a) < (b)) ? (a) : (b)) ++#endif ++ ++#ifndef MAX ++#define MAX(a, b) (((a) > (b)) ? (a) : (b)) ++#endif ++ + #define SSSD_MAIN_OPTS SSSD_DEBUG_OPTS + + #define SSSD_SERVER_OPTS(uid, gid) \ +-- +2.20.1 + diff --git a/SOURCES/0035-sbus-add-unit-tests-for-public-sbus_message-module.patch b/SOURCES/0035-sbus-add-unit-tests-for-public-sbus_message-module.patch deleted file mode 100644 index 70e2298..0000000 --- a/SOURCES/0035-sbus-add-unit-tests-for-public-sbus_message-module.patch +++ /dev/null @@ -1,664 +0,0 @@ -From 57af8c95f5639e3ff61d4b1e9864fee8150cd2ba Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Thu, 16 Aug 2018 13:20:55 +0200 -Subject: [PATCH 35/47] sbus: add unit tests for public sbus_message module - -Reviewed-by: Jakub Hrozek -(cherry picked from commit c895fa2449900f4abd1dce6bb62a45c52bbb12cf) ---- - Makefile.am | 14 + - src/tests/cmocka/sbus/test_sbus_message.c | 610 ++++++++++++++++++++++++++++++ - 2 files changed, 624 insertions(+) - create mode 100644 src/tests/cmocka/sbus/test_sbus_message.c - -diff --git a/Makefile.am b/Makefile.am -index 1602ec6236799015fa7fd9f1707cb2bcdb20e07b..c05c9312d74d2adab9dfe6d40987a791785da256 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -270,6 +270,7 @@ if HAVE_CMOCKA - test_copy_keytab \ - test_child_common \ - responder_cache_req-tests \ -+ test_sbus_message \ - test_sbus_opath \ - test_fo_srv \ - pam-srv-tests \ -@@ -2593,6 +2594,19 @@ test_ssh_client_LDADD = \ - $(SSSD_LIBS) \ - $(NULL) - -+test_sbus_message_SOURCES = \ -+ src/tests/cmocka/sbus/test_sbus_message.c \ -+ $(NULL) -+test_sbus_message_CFLAGS = \ -+ $(AM_CFLAGS) -+test_sbus_message_LDADD = \ -+ $(CMOCKA_LIBS) \ -+ $(POPT_LIBS) \ -+ libsss_debug.la \ -+ libsss_test_common.la \ -+ libsss_sbus.la \ -+ $(NULL) -+ - test_sbus_opath_SOURCES = \ - src/tests/cmocka/sbus/test_sbus_opath.c \ - $(NULL) -diff --git a/src/tests/cmocka/sbus/test_sbus_message.c b/src/tests/cmocka/sbus/test_sbus_message.c -new file mode 100644 -index 0000000000000000000000000000000000000000..c01e16823237775f95b772534adb5639e264c057 ---- /dev/null -+++ b/src/tests/cmocka/sbus/test_sbus_message.c -@@ -0,0 +1,610 @@ -+/* -+ Authors: -+ Jakub Hrozek -+ Pavel Březina -+ -+ Copyright (C) 2014 Red Hat -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+#include "util/util.h" -+#include "sbus/sbus_message.h" -+#include "tests/cmocka/common_mock.h" -+#include "tests/common.h" -+ -+#define BASE_PATH "/some/path" -+ -+struct test_ctx { -+ bool msg_removed; -+}; -+ -+static void helper_msg_removed(void *state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(state, struct test_ctx); -+ -+ test_ctx->msg_removed = true; -+} -+ -+static void helper_msg_watch(struct test_ctx *test_ctx, DBusMessage *msg) -+{ -+ DBusFreeFunction free_fn; -+ dbus_int32_t data_slot = -1; -+ dbus_bool_t bret; -+ -+ assert_non_null(msg); -+ -+ bret = dbus_message_allocate_data_slot(&data_slot); -+ assert_true(bret); -+ -+ free_fn = helper_msg_removed; -+ bret = dbus_message_set_data(msg, data_slot, test_ctx, free_fn); -+ assert_true(bret); -+} -+ -+static int test_setup(void **state) -+{ -+ struct test_ctx *test_ctx; -+ -+ assert_true(leak_check_setup()); -+ -+ test_ctx = talloc_zero(global_talloc_context, struct test_ctx); -+ assert_non_null(test_ctx); -+ *state = test_ctx; -+ -+ check_leaks_push(test_ctx); -+ -+ return 0; -+} -+ -+int test_teardown(void **state) -+{ -+ struct test_ctx *test_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ -+ assert_true(check_leaks_pop(test_ctx)); -+ talloc_zfree(test_ctx); -+ assert_true(leak_check_teardown()); -+ -+ return 0; -+} -+ -+void test_sbus_message_bound__null(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ DBusMessage *msg; -+ errno_t ret; -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ -+ ret = sbus_message_bound(NULL, msg); -+ assert_int_equal(ret, EINVAL); -+ -+ ret = sbus_message_bound(test_ctx, NULL); -+ assert_int_equal(ret, EINVAL); -+ -+ dbus_message_unref(msg); -+} -+ -+void test_sbus_message_bound__unref(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ DBusMessage *msg; -+ errno_t ret; -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ ret = sbus_message_bound(test_ctx, msg); -+ assert_int_equal(ret, EOK); -+ -+ /* no memory leak should be detected in teardown */ -+ dbus_message_unref(msg); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_message_bound__free(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ TALLOC_CTX *tmp_ctx; -+ DBusMessage *msg; -+ errno_t ret; -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ ret = sbus_message_bound(tmp_ctx, msg); -+ assert_int_equal(ret, EOK); -+ -+ talloc_free(tmp_ctx); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_message_bound_steal__null(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ DBusMessage *msg; -+ errno_t ret; -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ ret = sbus_message_bound_steal(NULL, msg); -+ assert_int_equal(ret, EINVAL); -+ -+ ret = sbus_message_bound_steal(test_ctx, NULL); -+ assert_int_equal(ret, EINVAL); -+ -+ dbus_message_unref(msg); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_message_bound_steal__invalid(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ DBusMessage *msg; -+ errno_t ret; -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ ret = sbus_message_bound_steal(test_ctx, msg); -+ assert_int_equal(ret, ERR_INTERNAL); -+ -+ dbus_message_unref(msg); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_message_bound_steal__free(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ TALLOC_CTX *tmp_ctx; -+ TALLOC_CTX *tmp_ctx_steal; -+ DBusMessage *msg; -+ errno_t ret; -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ tmp_ctx_steal = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx_steal); -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ ret = sbus_message_bound(tmp_ctx, msg); -+ assert_int_equal(ret, EOK); -+ -+ /* this will increase ref counter of message and add new talloc bound */ -+ ret = sbus_message_bound_steal(tmp_ctx_steal, msg); -+ assert_int_equal(ret, EOK); -+ -+ talloc_free(tmp_ctx); -+ assert_false(test_ctx->msg_removed); -+ talloc_free(tmp_ctx_steal); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_method_create_empty__unref(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ DBusMessage *msg; -+ -+ msg = sbus_method_create_empty(NULL, "bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ assert_int_equal(dbus_message_get_type(msg), DBUS_MESSAGE_TYPE_METHOD_CALL); -+ assert_string_equal(dbus_message_get_destination(msg), "bus.test"); -+ assert_string_equal(dbus_message_get_path(msg), "/"); -+ assert_string_equal(dbus_message_get_interface(msg), "iface.test"); -+ assert_string_equal(dbus_message_get_member(msg), "method"); -+ -+ dbus_message_unref(msg); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_method_create_empty__free(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ TALLOC_CTX *tmp_ctx; -+ DBusMessage *msg; -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ msg = sbus_method_create_empty(tmp_ctx, "bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ assert_int_equal(dbus_message_get_type(msg), DBUS_MESSAGE_TYPE_METHOD_CALL); -+ assert_string_equal(dbus_message_get_destination(msg), "bus.test"); -+ assert_string_equal(dbus_message_get_path(msg), "/"); -+ assert_string_equal(dbus_message_get_interface(msg), "iface.test"); -+ assert_string_equal(dbus_message_get_member(msg), "method"); -+ -+ talloc_free(tmp_ctx); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_method_create__unref(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ DBusMessage *msg; -+ dbus_bool_t dbret; -+ uint32_t in_value = 32; -+ uint32_t out_value; -+ -+ msg = sbus_method_create(NULL, "bus.test", "/", "iface.test", "method", -+ DBUS_TYPE_UINT32, &in_value); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ assert_int_equal(dbus_message_get_type(msg), DBUS_MESSAGE_TYPE_METHOD_CALL); -+ assert_string_equal(dbus_message_get_destination(msg), "bus.test"); -+ assert_string_equal(dbus_message_get_path(msg), "/"); -+ assert_string_equal(dbus_message_get_interface(msg), "iface.test"); -+ assert_string_equal(dbus_message_get_member(msg), "method"); -+ -+ dbret = dbus_message_get_args(msg, NULL, -+ DBUS_TYPE_UINT32, &out_value, -+ DBUS_TYPE_INVALID); -+ assert_true(dbret); -+ assert_int_equal(out_value, 32); -+ -+ dbus_message_unref(msg); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_method_create__free(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ TALLOC_CTX *tmp_ctx; -+ DBusMessage *msg; -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ msg = sbus_method_create_empty(tmp_ctx, "bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ assert_int_equal(dbus_message_get_type(msg), DBUS_MESSAGE_TYPE_METHOD_CALL); -+ assert_string_equal(dbus_message_get_destination(msg), "bus.test"); -+ assert_string_equal(dbus_message_get_path(msg), "/"); -+ assert_string_equal(dbus_message_get_interface(msg), "iface.test"); -+ assert_string_equal(dbus_message_get_member(msg), "method"); -+ -+ talloc_free(tmp_ctx); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_signal_create_empty__unref(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ DBusMessage *msg; -+ -+ msg = sbus_signal_create_empty(NULL, "/", "iface.test", "method"); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ assert_int_equal(dbus_message_get_type(msg), DBUS_MESSAGE_TYPE_SIGNAL); -+ assert_null(dbus_message_get_destination(msg)); -+ assert_string_equal(dbus_message_get_path(msg), "/"); -+ assert_string_equal(dbus_message_get_interface(msg), "iface.test"); -+ assert_string_equal(dbus_message_get_member(msg), "method"); -+ -+ dbus_message_unref(msg); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_signal_create_empty__free(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ TALLOC_CTX *tmp_ctx; -+ DBusMessage *msg; -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ msg = sbus_signal_create_empty(tmp_ctx, "/", "iface.test", "method"); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ assert_int_equal(dbus_message_get_type(msg), DBUS_MESSAGE_TYPE_SIGNAL); -+ assert_null(dbus_message_get_destination(msg)); -+ assert_string_equal(dbus_message_get_path(msg), "/"); -+ assert_string_equal(dbus_message_get_interface(msg), "iface.test"); -+ assert_string_equal(dbus_message_get_member(msg), "method"); -+ -+ talloc_free(tmp_ctx); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_signal_create__unref(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ DBusMessage *msg; -+ dbus_bool_t dbret; -+ uint32_t in_value = 32; -+ uint32_t out_value; -+ -+ msg = sbus_signal_create(NULL, "/", "iface.test", "method", -+ DBUS_TYPE_UINT32, &in_value); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ assert_int_equal(dbus_message_get_type(msg), DBUS_MESSAGE_TYPE_SIGNAL); -+ assert_null(dbus_message_get_destination(msg)); -+ assert_string_equal(dbus_message_get_path(msg), "/"); -+ assert_string_equal(dbus_message_get_interface(msg), "iface.test"); -+ assert_string_equal(dbus_message_get_member(msg), "method"); -+ -+ dbret = dbus_message_get_args(msg, NULL, -+ DBUS_TYPE_UINT32, &out_value, -+ DBUS_TYPE_INVALID); -+ assert_true(dbret); -+ assert_int_equal(out_value, 32); -+ -+ dbus_message_unref(msg); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_signal_create__free(void **state) -+{ -+ struct test_ctx *test_ctx = talloc_get_type_abort(*state, struct test_ctx); -+ TALLOC_CTX *tmp_ctx; -+ DBusMessage *msg; -+ dbus_bool_t dbret; -+ uint32_t in_value = 32; -+ uint32_t out_value; -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ msg = sbus_signal_create(tmp_ctx, "/", "iface.test", "method", -+ DBUS_TYPE_UINT32, &in_value); -+ assert_non_null(msg); -+ helper_msg_watch(test_ctx, msg); -+ -+ assert_int_equal(dbus_message_get_type(msg), DBUS_MESSAGE_TYPE_SIGNAL); -+ assert_null(dbus_message_get_destination(msg)); -+ assert_string_equal(dbus_message_get_path(msg), "/"); -+ assert_string_equal(dbus_message_get_interface(msg), "iface.test"); -+ assert_string_equal(dbus_message_get_member(msg), "method"); -+ -+ dbret = dbus_message_get_args(msg, NULL, -+ DBUS_TYPE_UINT32, &out_value, -+ DBUS_TYPE_INVALID); -+ assert_true(dbret); -+ assert_int_equal(out_value, 32); -+ -+ talloc_free(tmp_ctx); -+ assert_true(test_ctx->msg_removed); -+} -+ -+void test_sbus_reply_parse__ok(void **state) -+{ -+ DBusMessage *msg; -+ DBusMessage *reply; -+ dbus_bool_t dbret; -+ uint32_t in_value1 = 32; -+ uint32_t in_value2 = 64; -+ uint32_t out_value1; -+ uint32_t out_value2; -+ errno_t ret; -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ dbus_message_set_serial(msg, 1); -+ -+ reply = dbus_message_new_method_return(msg); -+ assert_non_null(reply); -+ -+ dbret = dbus_message_append_args(reply, DBUS_TYPE_UINT32, &in_value1, -+ DBUS_TYPE_UINT32, &in_value2, -+ DBUS_TYPE_INVALID); -+ assert_true(dbret); -+ -+ ret = sbus_reply_parse(reply, DBUS_TYPE_UINT32, &out_value1, -+ DBUS_TYPE_UINT32, &out_value2); -+ assert_int_equal(ret, EOK); -+ assert_int_equal(out_value1, in_value1); -+ assert_int_equal(out_value2, in_value2); -+ -+ dbus_message_unref(msg); -+ dbus_message_unref(reply); -+} -+ -+void test_sbus_reply_parse__error(void **state) -+{ -+ DBusMessage *msg; -+ DBusMessage *reply; -+ uint32_t out_value1; -+ uint32_t out_value2; -+ errno_t ret; -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ dbus_message_set_serial(msg, 1); -+ -+ reply = dbus_message_new_error(msg, SBUS_ERROR_KILLED, "Test error!"); -+ assert_non_null(reply); -+ -+ ret = sbus_reply_parse(reply, DBUS_TYPE_UINT32, &out_value1, -+ DBUS_TYPE_UINT32, &out_value2); -+ assert_int_equal(ret, ERR_SBUS_KILL_CONNECTION); -+ -+ dbus_message_unref(msg); -+ dbus_message_unref(reply); -+} -+ -+void test_sbus_reply_parse__wrong_type(void **state) -+{ -+ DBusMessage *msg; -+ errno_t ret; -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ dbus_message_set_serial(msg, 1); -+ -+ ret = sbus_reply_parse(msg); -+ assert_int_not_equal(ret, EOK); -+ -+ dbus_message_unref(msg); -+} -+ -+void test_sbus_reply_check__ok(void **state) -+{ -+ DBusMessage *msg; -+ DBusMessage *reply; -+ errno_t ret; -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ dbus_message_set_serial(msg, 1); -+ -+ reply = dbus_message_new_method_return(msg); -+ assert_non_null(reply); -+ -+ ret = sbus_reply_check(reply); -+ assert_int_equal(ret, EOK); -+ -+ dbus_message_unref(msg); -+ dbus_message_unref(reply); -+} -+ -+void test_sbus_reply_check__error(void **state) -+{ -+ DBusMessage *msg; -+ DBusMessage *reply; -+ errno_t ret; -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ dbus_message_set_serial(msg, 1); -+ -+ reply = dbus_message_new_error(msg, SBUS_ERROR_KILLED, "Test error!"); -+ assert_non_null(reply); -+ -+ ret = sbus_reply_check(reply); -+ assert_int_equal(ret, ERR_SBUS_KILL_CONNECTION); -+ -+ dbus_message_unref(msg); -+ dbus_message_unref(reply); -+} -+ -+void test_sbus_reply_check__wrong_type(void **state) -+{ -+ DBusMessage *msg; -+ errno_t ret; -+ -+ msg = dbus_message_new_method_call("bus.test", "/", "iface.test", "method"); -+ assert_non_null(msg); -+ dbus_message_set_serial(msg, 1); -+ -+ ret = sbus_reply_check(msg); -+ assert_int_not_equal(ret, EOK); -+ -+ dbus_message_unref(msg); -+} -+ -+int main(int argc, const char *argv[]) -+{ -+ poptContext pc; -+ int opt; -+ struct poptOption long_options[] = { -+ POPT_AUTOHELP -+ SSSD_DEBUG_OPTS -+ POPT_TABLEEND -+ }; -+ -+ const struct CMUnitTest tests[] = { -+ cmocka_unit_test_setup_teardown(test_sbus_message_bound__null, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_message_bound__unref, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_message_bound__free, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_message_bound_steal__null, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_message_bound_steal__invalid, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_message_bound_steal__free, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_method_create_empty__unref, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_method_create_empty__free, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_method_create__unref, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_method_create__free, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_signal_create_empty__unref, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_signal_create_empty__free, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_signal_create__unref, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_signal_create__free, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_reply_parse__ok, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_reply_parse__error, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_reply_parse__wrong_type, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_reply_check__ok, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_reply_check__error, -+ test_setup, test_teardown), -+ cmocka_unit_test_setup_teardown(test_sbus_reply_check__wrong_type, -+ test_setup, test_teardown), -+ }; -+ -+ /* Set debug level to invalid value so we can decide if -d 0 was used. */ -+ debug_level = SSSDBG_INVALID; -+ -+ pc = poptGetContext(argv[0], argc, argv, long_options, 0); -+ while((opt = poptGetNextOpt(pc)) != -1) { -+ switch(opt) { -+ default: -+ fprintf(stderr, "\nInvalid option %s: %s\n\n", -+ poptBadOption(pc, 0), poptStrerror(opt)); -+ poptPrintUsage(pc, stderr, 0); -+ return 1; -+ } -+ } -+ poptFreeContext(pc); -+ -+ DEBUG_CLI_INIT(debug_level); -+ -+ return cmocka_run_group_tests(tests, NULL, NULL); -+} --- -2.14.4 - diff --git a/SOURCES/0036-BE-Extend-be_ptask_create-with-control-when-to-sched.patch b/SOURCES/0036-BE-Extend-be_ptask_create-with-control-when-to-sched.patch new file mode 100644 index 0000000..dddaf8d --- /dev/null +++ b/SOURCES/0036-BE-Extend-be_ptask_create-with-control-when-to-sched.patch @@ -0,0 +1,496 @@ +From 25b9f34fb2c7ea493c5e0fe83047703ec65fe60c Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 18 Jun 2019 20:49:00 +0200 +Subject: [PATCH 36/48] BE: Extend be_ptask_create() with control when to + schedule next run after success + +Related: https://pagure.io/SSSD/sssd/issue/4012 + +be_ptask_create() used to always schedule the next periodical run +"period" seconds after the previous run started. This is great for tasks +that are short-lived like DNS updates because we know they will be +executed really with the configured period. + +But the background refresh task can potentially take a very long time in +which case the next run could have been scheduled almost immediately and +as a result sssd_be would always be quite busy. It is better to have the +option to schedule the next task period seconds after the last run has +finished. This can lead to some inconsistency, but we can warn the +admin about that. + +This patch so far does not change any of the existing calls to +be_ptask_create(), just adds BE_PTASK_SCHEDULE_FROM_LAST as an +additional parameter. + +Reviewed-by: Sumit Bose +--- + src/providers/ad/ad_dyndns.c | 3 +- + src/providers/ad/ad_machine_pw_renewal.c | 4 +- + src/providers/ad/ad_subdomains.c | 4 +- + src/providers/be_ptask.c | 10 ++-- + src/providers/be_ptask.h | 24 ++++++++- + src/providers/be_ptask_private.h | 1 + + src/providers/be_refresh.c | 4 +- + src/providers/ipa/ipa_dyndns.c | 5 +- + src/providers/ipa/ipa_subdomains.c | 4 +- + src/providers/ldap/ldap_id_enum.c | 1 + + src/providers/ldap/sdap_sudo_shared.c | 8 ++- + src/tests/cmocka/test_be_ptask.c | 62 ++++++++++++++++-------- + 12 files changed, 95 insertions(+), 35 deletions(-) + +diff --git a/src/providers/ad/ad_dyndns.c b/src/providers/ad/ad_dyndns.c +index 52a4e4d53..02ea7f24b 100644 +--- a/src/providers/ad/ad_dyndns.c ++++ b/src/providers/ad/ad_dyndns.c +@@ -97,8 +97,9 @@ errno_t ad_dyndns_init(struct be_ctx *be_ctx, + "dyndns_refresh_interval is 0\n"); + return EINVAL; + } ++ + ret = be_ptask_create(ad_opts, be_ctx, period, ptask_first_delay, 0, 0, period, +- BE_PTASK_OFFLINE_DISABLE, 0, ++ BE_PTASK_OFFLINE_DISABLE, BE_PTASK_SCHEDULE_FROM_LAST, 0, + ad_dyndns_update_send, ad_dyndns_update_recv, ad_opts, + "Dyndns update", NULL); + +diff --git a/src/providers/ad/ad_machine_pw_renewal.c b/src/providers/ad/ad_machine_pw_renewal.c +index 5b6ba26b7..47941dfbf 100644 +--- a/src/providers/ad/ad_machine_pw_renewal.c ++++ b/src/providers/ad/ad_machine_pw_renewal.c +@@ -382,7 +382,9 @@ errno_t ad_machine_account_password_renewal_init(struct be_ctx *be_ctx, + } + + ret = be_ptask_create(be_ctx, be_ctx, period, initial_delay, 0, 0, 60, +- BE_PTASK_OFFLINE_DISABLE, 0, ++ BE_PTASK_OFFLINE_DISABLE, ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, + ad_machine_account_password_renewal_send, + ad_machine_account_password_renewal_recv, + renewal_data, +diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c +index c4ac23065..2510498da 100644 +--- a/src/providers/ad/ad_subdomains.c ++++ b/src/providers/ad/ad_subdomains.c +@@ -2066,7 +2066,9 @@ errno_t ad_subdomains_init(TALLOC_CTX *mem_ctx, + + period = be_ctx->domain->subdomain_refresh_interval; + ret = be_ptask_create(sd_ctx, be_ctx, period, 0, 0, 0, period, +- BE_PTASK_OFFLINE_DISABLE, 0, ++ BE_PTASK_OFFLINE_DISABLE, ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, + ad_subdomains_ptask_send, ad_subdomains_ptask_recv, sd_ctx, + "Subdomains Refresh", NULL); + if (ret != EOK) { +diff --git a/src/providers/be_ptask.c b/src/providers/be_ptask.c +index c43351755..32d9a03ce 100644 +--- a/src/providers/be_ptask.c ++++ b/src/providers/be_ptask.c +@@ -30,11 +30,6 @@ + + #define backoff_allowed(ptask) (ptask->max_backoff != 0) + +-enum be_ptask_schedule { +- BE_PTASK_SCHEDULE_FROM_NOW, +- BE_PTASK_SCHEDULE_FROM_LAST +-}; +- + enum be_ptask_delay { + BE_PTASK_FIRST_DELAY, + BE_PTASK_ENABLED_DELAY, +@@ -182,7 +177,7 @@ static void be_ptask_done(struct tevent_req *req) + DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: finished successfully\n", + task->name); + +- be_ptask_schedule(task, BE_PTASK_PERIOD, BE_PTASK_SCHEDULE_FROM_LAST); ++ be_ptask_schedule(task, BE_PTASK_PERIOD, task->success_schedule_type); + break; + default: + DEBUG(SSSDBG_OP_FAILURE, "Task [%s]: failed with [%d]: %s\n", +@@ -268,6 +263,7 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + time_t random_offset, + time_t timeout, + enum be_ptask_offline offline, ++ enum be_ptask_schedule success_schedule_type, + time_t max_backoff, + be_ptask_send_t send_fn, + be_ptask_recv_t recv_fn, +@@ -300,6 +296,7 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + task->max_backoff = max_backoff; + task->timeout = timeout; + task->offline = offline; ++ task->success_schedule_type = success_schedule_type; + task->send_fn = send_fn; + task->recv_fn = recv_fn; + task->pvt = pvt; +@@ -470,6 +467,7 @@ errno_t be_ptask_create_sync(TALLOC_CTX *mem_ctx, + + ret = be_ptask_create(mem_ctx, be_ctx, period, first_delay, + enabled_delay, random_offset, timeout, offline, ++ BE_PTASK_SCHEDULE_FROM_LAST, + max_backoff, be_ptask_sync_send, be_ptask_sync_recv, + ctx, name, _task); + if (ret != EOK) { +diff --git a/src/providers/be_ptask.h b/src/providers/be_ptask.h +index 3b9755361..c23278e88 100644 +--- a/src/providers/be_ptask.h ++++ b/src/providers/be_ptask.h +@@ -46,6 +46,19 @@ enum be_ptask_offline { + BE_PTASK_OFFLINE_EXECUTE + }; + ++/** ++ * Defines the starting point for scheduling a task ++ */ ++enum be_ptask_schedule { ++ /* Schedule starting from now, typically this is used when scheduling ++ * relative to the finish time ++ */ ++ BE_PTASK_SCHEDULE_FROM_NOW, ++ /* Schedule relative to the start time of the task ++ */ ++ BE_PTASK_SCHEDULE_FROM_LAST ++}; ++ + typedef struct tevent_req * + (*be_ptask_send_t)(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, +@@ -75,6 +88,14 @@ typedef errno_t + * The first execution is scheduled first_delay seconds after the task is + * created. + * ++ * Subsequent runs will be scheduled depending on the value of the ++ * success_schedule_type parameter: ++ * - BE_PTASK_SCHEDULE_FROM_NOW: period seconds from the finish time ++ * - BE_PTASK_SCHEDULE_FROM_LAST: period seconds from the last start time ++ * ++ * If the test fails, another run is always scheduled period seconds ++ * from the finish time. ++ * + * If request does not complete in timeout seconds, it will be + * cancelled and rescheduled to 'now + period'. + * +@@ -83,7 +104,7 @@ typedef errno_t + * + * The random_offset is maximum number of seconds added to the + * expected delay. Set to 0 if no randomization is needed. +- ++ * + * If max_backoff is not 0 then the period is doubled + * every time the task is scheduled. The maximum value of + * period is max_backoff. The value of period will be reset to +@@ -100,6 +121,7 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + time_t random_offset, + time_t timeout, + enum be_ptask_offline offline, ++ enum be_ptask_schedule success_schedule_type, + time_t max_backoff, + be_ptask_send_t send_fn, + be_ptask_recv_t recv_fn, +diff --git a/src/providers/be_ptask_private.h b/src/providers/be_ptask_private.h +index 4144a3938..e89105f95 100644 +--- a/src/providers/be_ptask_private.h ++++ b/src/providers/be_ptask_private.h +@@ -32,6 +32,7 @@ struct be_ptask { + time_t timeout; + time_t max_backoff; + enum be_ptask_offline offline; ++ enum be_ptask_schedule success_schedule_type; + be_ptask_send_t send_fn; + be_ptask_recv_t recv_fn; + void *pvt; +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index 5d86509bb..50b023c3d 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -156,7 +156,9 @@ errno_t be_refresh_ctx_init(struct be_ctx *be_ctx, + refresh_interval = be_ctx->domain->refresh_expired_interval; + if (refresh_interval > 0) { + ret = be_ptask_create(be_ctx, be_ctx, refresh_interval, 30, 5, 0, +- refresh_interval, BE_PTASK_OFFLINE_SKIP, 0, ++ refresh_interval, BE_PTASK_OFFLINE_SKIP, ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, + be_refresh_send, be_refresh_recv, + ctx, "Refresh Records", NULL); + if (ret != EOK) { +diff --git a/src/providers/ipa/ipa_dyndns.c b/src/providers/ipa/ipa_dyndns.c +index a692b0d19..8e8ff5a4f 100644 +--- a/src/providers/ipa/ipa_dyndns.c ++++ b/src/providers/ipa/ipa_dyndns.c +@@ -72,8 +72,11 @@ errno_t ipa_dyndns_init(struct be_ctx *be_ctx, + "dyndns_refresh_interval is 0\n"); + return EINVAL; + } ++ + ret = be_ptask_create(ctx, be_ctx, period, ptask_first_delay, 0, 0, period, +- BE_PTASK_OFFLINE_DISABLE, 0, ++ BE_PTASK_OFFLINE_DISABLE, ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, + ipa_dyndns_update_send, ipa_dyndns_update_recv, ctx, + "Dyndns update", NULL); + if (ret != EOK) { +diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c +index 94365aaca..3a17c851d 100644 +--- a/src/providers/ipa/ipa_subdomains.c ++++ b/src/providers/ipa/ipa_subdomains.c +@@ -3134,7 +3134,9 @@ errno_t ipa_subdomains_init(TALLOC_CTX *mem_ctx, + + period = be_ctx->domain->subdomain_refresh_interval; + ret = be_ptask_create(sd_ctx, be_ctx, period, ptask_first_delay, 0, 0, period, +- BE_PTASK_OFFLINE_DISABLE, 0, ++ BE_PTASK_OFFLINE_DISABLE, ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, + ipa_subdomains_ptask_send, ipa_subdomains_ptask_recv, sd_ctx, + "Subdomains Refresh", NULL); + if (ret != EOK) { +diff --git a/src/providers/ldap/ldap_id_enum.c b/src/providers/ldap/ldap_id_enum.c +index 8832eb558..062185c55 100644 +--- a/src/providers/ldap/ldap_id_enum.c ++++ b/src/providers/ldap/ldap_id_enum.c +@@ -99,6 +99,7 @@ errno_t ldap_setup_enumeration(struct be_ctx *be_ctx, + 0, /* random offset */ + period, /* timeout */ + BE_PTASK_OFFLINE_SKIP, ++ BE_PTASK_SCHEDULE_FROM_LAST, + 0, /* max_backoff */ + send_fn, recv_fn, + ectx, "enumeration", &sdom->enum_task); +diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c +index d2f24ed6e..a00d8e6a9 100644 +--- a/src/providers/ldap/sdap_sudo_shared.c ++++ b/src/providers/ldap/sdap_sudo_shared.c +@@ -90,7 +90,9 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx, + * when offline. */ + if (full > 0) { + ret = be_ptask_create(be_ctx, be_ctx, full, delay, 0, 0, full, +- BE_PTASK_OFFLINE_DISABLE, 0, ++ BE_PTASK_OFFLINE_DISABLE, ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, + full_send_fn, full_recv_fn, pvt, + "SUDO Full Refresh", NULL); + if (ret != EOK) { +@@ -107,7 +109,9 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx, + * when offline. */ + if (smart > 0) { + ret = be_ptask_create(be_ctx, be_ctx, smart, delay + smart, smart, 0, +- smart, BE_PTASK_OFFLINE_DISABLE, 0, ++ smart, BE_PTASK_OFFLINE_DISABLE, ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, + smart_send_fn, smart_recv_fn, pvt, + "SUDO Smart Refresh", NULL); + if (ret != EOK) { +diff --git a/src/tests/cmocka/test_be_ptask.c b/src/tests/cmocka/test_be_ptask.c +index 356d9f9e2..03b1165bb 100644 +--- a/src/tests/cmocka/test_be_ptask.c ++++ b/src/tests/cmocka/test_be_ptask.c +@@ -304,7 +304,8 @@ void test_be_ptask_create_einval_be(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, NULL, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, NULL, "Test ptask", &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); +@@ -317,7 +318,8 @@ void test_be_ptask_create_einval_period(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, 0, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, NULL, "Test ptask", &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); +@@ -330,7 +332,8 @@ void test_be_ptask_create_einval_send(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, NULL, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, NULL, + test_be_ptask_recv, NULL, "Test ptask", &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); +@@ -343,7 +346,8 @@ void test_be_ptask_create_einval_recv(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + NULL, NULL, "Test ptask", &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); +@@ -356,7 +360,8 @@ void test_be_ptask_create_einval_name(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, NULL, NULL, &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); +@@ -371,7 +376,8 @@ void test_be_ptask_create_no_delay(void **state) + + now = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -398,7 +404,8 @@ void test_be_ptask_create_first_delay(void **state) + + now = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, DELAY, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -423,7 +430,8 @@ void test_be_ptask_disable(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -447,7 +455,8 @@ void test_be_ptask_enable(void **state) + + now = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -479,7 +488,8 @@ void test_be_ptask_enable_delay(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, DELAY, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -518,7 +528,8 @@ void test_be_ptask_offline_skip(void **state) + + now = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -551,7 +562,9 @@ void test_be_ptask_offline_disable(void **state) + will_return(be_add_offline_cb, test_ctx); + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_DISABLE, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_DISABLE, ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -581,7 +594,9 @@ void test_be_ptask_offline_execute(void **state) + mark_offline(test_ctx); + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_EXECUTE, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_EXECUTE, ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -608,7 +623,8 @@ void test_be_ptask_reschedule_ok(void **state) + + now = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -639,7 +655,8 @@ void test_be_ptask_reschedule_null(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_null_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_null_send, + test_be_ptask_recv, test_ctx, "Test ptask", + &ptask); + assert_int_equal(ret, ERR_OK); +@@ -666,7 +683,8 @@ void test_be_ptask_reschedule_error(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_error_recv, test_ctx, "Test ptask", + &ptask); + assert_int_equal(ret, ERR_OK); +@@ -693,7 +711,8 @@ void test_be_ptask_reschedule_timeout(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 1, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_timeout_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_timeout_send, + test_be_ptask_error_recv, test_ctx, "Test ptask", + &ptask); + assert_int_equal(ret, ERR_OK); +@@ -730,7 +749,8 @@ void test_be_ptask_reschedule_backoff(void **state) + + now_first = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, PERIOD*2, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ PERIOD*2, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -784,7 +804,8 @@ void test_be_ptask_get_period(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -804,7 +825,8 @@ void test_be_ptask_get_timeout(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, TIMEOUT, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +-- +2.20.1 + diff --git a/SOURCES/0036-p11-handle-multiple-certs-during-auth-with-OpenSSL.patch b/SOURCES/0036-p11-handle-multiple-certs-during-auth-with-OpenSSL.patch deleted file mode 100644 index 945601d..0000000 --- a/SOURCES/0036-p11-handle-multiple-certs-during-auth-with-OpenSSL.patch +++ /dev/null @@ -1,147 +0,0 @@ -From 8fbdd8b692be1dc63be4dd18c79d9647aeb2d74d Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 2 Oct 2018 12:13:29 +0200 -Subject: [PATCH 36/47] p11: handle multiple certs during auth with OpenSSL - -This patch adds missing code already available in the NSS version to -select a certificate for authentication if multiple certificates are -available on the Smartcard. A unit test to check this feature is added -as well. - -Related to https://pagure.io/SSSD/sssd/issue/3489 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit e29b82077a78157a1e4d90e2308c1272d7612f3d) ---- - src/p11_child/p11_child_openssl.c | 46 ++++++++++++++++++++++++++++++++++++++- - src/tests/cmocka/test_pam_srv.c | 36 ++++++++++++++++++++++++++++++ - 2 files changed, 81 insertions(+), 1 deletion(-) - -diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c -index be5872626e248ad8acc042300a2ee2eee526cdaf..bf4418f8603eac4d77d20f464e8b56fb82285f0a 100644 ---- a/src/p11_child/p11_child_openssl.c -+++ b/src/p11_child/p11_child_openssl.c -@@ -572,8 +572,10 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - char *slot_name = NULL; - char *token_name = NULL; - CK_SESSION_HANDLE session = 0; -+ struct cert_list *all_cert_list = NULL; - struct cert_list *cert_list = NULL; - struct cert_list *item = NULL; -+ struct cert_list *tmp_cert = NULL; - char *multi = NULL; - bool pkcs11_session = false; - bool pkcs11_login = false; -@@ -691,12 +693,54 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - DEBUG(SSSDBG_TRACE_ALL, "Login NOT required.\n"); - } - -- ret = read_certs(mem_ctx, module, session, p11_ctx, &cert_list); -+ ret = read_certs(mem_ctx, module, session, p11_ctx, &all_cert_list); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "read_certs failed.\n"); - goto done; - } - -+ DLIST_FOR_EACH(item, all_cert_list) { -+ /* 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_file_name, token_name_in, token_name, -+ key_id_in, item->id); -+ -+ if ((mode == OP_AUTH -+ && module_name_in != NULL -+ && token_name_in != NULL -+ && key_id_in != NULL -+ && item->id != NULL -+ && strcmp(key_id_in, item->id) == 0 -+ && strcmp(token_name_in, token_name) == 0 -+ && strcmp(module_name_in, module_file_name) == 0) -+ || (mode == OP_PREAUTH -+ && (module_name_in == NULL -+ || (module_name_in != NULL -+ && strcmp(module_name_in, module_file_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 && item->id != NULL -+ && strcmp(key_id_in, item->id) == 0)))) { -+ -+ tmp_cert = talloc_memdup(mem_ctx, item, sizeof(struct cert_list)); -+ if (tmp_cert == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_memdup failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ tmp_cert->prev = NULL; -+ tmp_cert->next = NULL; -+ -+ DLIST_ADD(cert_list, tmp_cert); -+ -+ } -+ } -+ - /* TODO: check module_name_in, token_name_in, key_id_in */ - - if (cert_list == NULL) { -diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c -index 446985d5d2462f58a28c702fd5eaa5de7b20ed27..2b02ac27b7356c5bce9e11dae785ecdbddd31aa3 100644 ---- a/src/tests/cmocka/test_pam_srv.c -+++ b/src/tests/cmocka/test_pam_srv.c -@@ -2443,6 +2443,40 @@ void test_pam_cert_preauth_2certs_two_mappings(void **state) - assert_int_equal(ret, EOK); - } - -+void test_pam_cert_auth_2certs_one_mapping(void **state) -+{ -+ int ret; -+ -+#ifdef HAVE_NSS -+ set_cert_auth_param(pam_test_ctx->pctx, NSS_DB_2CERTS); -+#else -+ set_cert_auth_param(pam_test_ctx->pctx, CA_DB); -+ putenv(discard_const("SOFTHSM2_CONF=" ABS_BUILD_DIR "/src/tests/test_CA/softhsm2_two.conf")); -+#endif -+ -+ mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", "SSSD Test Token", -+ TEST_MODULE_NAME, -+ "C554C9F82C2A9D58B70921C143304153A8A42F17", NULL, -+ test_lookup_by_cert_double_cb, SSSD_TEST_CERT_0001, -+ true); -+ -+ 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_simple_check_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_filter_response(void **state) - { - int ret; -@@ -2875,6 +2909,8 @@ int main(int argc, const char *argv[]) - pam_test_setup, pam_test_teardown), - cmocka_unit_test_setup_teardown(test_pam_cert_preauth_2certs_two_mappings, - pam_test_setup, pam_test_teardown), -+ cmocka_unit_test_setup_teardown(test_pam_cert_auth_2certs_one_mapping, -+ 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, --- -2.14.4 - diff --git a/SOURCES/0037-BE-Schedule-the-refresh-interval-from-the-finish-tim.patch b/SOURCES/0037-BE-Schedule-the-refresh-interval-from-the-finish-tim.patch new file mode 100644 index 0000000..664c6fe --- /dev/null +++ b/SOURCES/0037-BE-Schedule-the-refresh-interval-from-the-finish-tim.patch @@ -0,0 +1,34 @@ +From 6b068dec9ac5b2f22a9c20b5554a6e45af6dc8bb Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 19 Jun 2019 22:03:16 +0200 +Subject: [PATCH 37/48] BE: Schedule the refresh interval from the finish time + of the last run + +Related: https://pagure.io/SSSD/sssd/issue/4012 + +Changes scheduling the periodical task so that the next run is started +relative to the previous run finish time, not start time to protect +against cases where the refresh would take too long and run practically +all the time. + +Reviewed-by: Sumit Bose +--- + src/providers/be_refresh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index 50b023c3d..a9d4295ec 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -157,7 +157,7 @@ errno_t be_refresh_ctx_init(struct be_ctx *be_ctx, + if (refresh_interval > 0) { + ret = be_ptask_create(be_ctx, be_ctx, refresh_interval, 30, 5, 0, + refresh_interval, BE_PTASK_OFFLINE_SKIP, +- BE_PTASK_SCHEDULE_FROM_LAST, ++ BE_PTASK_SCHEDULE_FROM_NOW, + 0, + be_refresh_send, be_refresh_recv, + ctx, "Refresh Records", NULL); +-- +2.20.1 + diff --git a/SOURCES/0037-p11_child-add-wait_for_card-option.patch b/SOURCES/0037-p11_child-add-wait_for_card-option.patch deleted file mode 100644 index 6cf433d..0000000 --- a/SOURCES/0037-p11_child-add-wait_for_card-option.patch +++ /dev/null @@ -1,476 +0,0 @@ -From 8070497ccd404438712711f1317e800df0c774e3 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 14 Sep 2018 12:47:00 +0200 -Subject: [PATCH 37/47] p11_child: add --wait_for_card option - -The --wait_for_card option will let the p11_child wait until a -Smartcard/token is available in a slot with the removable flag. - -Related to https://pagure.io/SSSD/sssd/issue/3650 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 42f69e26e5b858dd03492cc2a148d02c2ccc2161) ---- - src/p11_child/p11_child.h | 5 +- - src/p11_child/p11_child_common.c | 12 +++- - src/p11_child/p11_child_nss.c | 105 +++++++++++++++++++-------- - src/p11_child/p11_child_openssl.c | 146 +++++++++++++++++++++++++++++--------- - 4 files changed, 201 insertions(+), 67 deletions(-) - -diff --git a/src/p11_child/p11_child.h b/src/p11_child/p11_child.h -index 1e9fc3d1c9d0a05f50080f1ef37771448deb162f..dd8fdeafbf947aad930e61ae694bc99df6d8212a 100644 ---- a/src/p11_child/p11_child.h -+++ b/src/p11_child/p11_child.h -@@ -25,6 +25,9 @@ - #ifndef __P11_CHILD_H__ - #define __P11_CHILD_H__ - -+/* Time to wait during a C_Finalize C_Initialize cycle to discover -+ * new slots. */ -+#define PKCS11_FINIALIZE_INITIALIZE_WAIT_TIME 3 - struct p11_ctx; - - enum op_mode { -@@ -41,7 +44,7 @@ enum pin_mode { - }; - - errno_t init_p11_ctx(TALLOC_CTX *mem_ctx, const char *nss_db, -- struct p11_ctx **p11_ctx); -+ bool wait_for_card, struct p11_ctx **p11_ctx); - - errno_t init_verification(struct p11_ctx *p11_ctx, - struct cert_verify_opts *cert_verify_opts); -diff --git a/src/p11_child/p11_child_common.c b/src/p11_child/p11_child_common.c -index 125430d13d0807bc30018b49715367cabb028696..bc5f6b09b191f0ea853f45d8a78bc6e4a69c3da7 100644 ---- a/src/p11_child/p11_child_common.c -+++ b/src/p11_child/p11_child_common.c -@@ -57,6 +57,7 @@ static const char *op_mode_str(enum op_mode mode) - - static int do_work(TALLOC_CTX *mem_ctx, enum op_mode mode, const char *ca_db, - struct cert_verify_opts *cert_verify_opts, -+ bool wait_for_card, - const char *cert_b64, const char *pin, - const char *module_name, const char *token_name, - const char *key_id, char **multi) -@@ -64,7 +65,7 @@ static int do_work(TALLOC_CTX *mem_ctx, enum op_mode mode, const char *ca_db, - int ret; - struct p11_ctx *p11_ctx; - -- ret = init_p11_ctx(mem_ctx, ca_db, &p11_ctx); -+ ret = init_p11_ctx(mem_ctx, ca_db, wait_for_card, &p11_ctx); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "init_p11_ctx failed.\n"); - return ret; -@@ -157,6 +158,7 @@ int main(int argc, const char *argv[]) - char *token_name = NULL; - char *key_id = NULL; - char *cert_b64 = NULL; -+ bool wait_for_card = false; - - struct poptOption long_options[] = { - POPT_AUTOHELP -@@ -174,6 +176,7 @@ int main(int argc, const char *argv[]) - 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}, -+ {"wait_for_card", 0, POPT_ARG_NONE, NULL, 'w', _("Wait until card is available"), NULL}, - {"verification", 0, POPT_ARG_NONE, NULL, 'v', _("Run in verification mode"), - NULL}, - {"pin", 0, POPT_ARG_NONE, NULL, 'i', _("Expect PIN on stdin"), NULL}, -@@ -258,6 +261,9 @@ int main(int argc, const char *argv[]) - } - pin_mode = PIN_KEYPAD; - break; -+ case 'w': -+ wait_for_card = true; -+ break; - default: - fprintf(stderr, "\nInvalid option %s: %s\n\n", - poptBadOption(pc, 0), poptStrerror(opt)); -@@ -360,8 +366,8 @@ int main(int argc, const char *argv[]) - } - } - -- ret = do_work(main_ctx, mode, nss_db, cert_verify_opts, cert_b64, -- pin, module_name, token_name, key_id, &multi); -+ ret = do_work(main_ctx, mode, nss_db, cert_verify_opts, wait_for_card, -+ cert_b64, pin, module_name, token_name, key_id, &multi); - if (ret != 0) { - DEBUG(SSSDBG_OP_FAILURE, "do_work failed.\n"); - goto fail; -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index d6a0b804a23a02389d1f764488cda6924dc0b41e..b2777d1d245d4942263ebf0610eef5cf6a528bd1 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -51,6 +51,7 @@ struct p11_ctx { - CERTCertDBHandle *handle; - struct cert_verify_opts *cert_verify_opts; - const char *nss_db; -+ bool wait_for_card; - }; - - #define EXP_USAGES ( certificateUsageSSLClient \ -@@ -141,6 +142,19 @@ static int talloc_free_handle(struct p11_ctx *p11_ctx) - return 0; - } - -+static NSSInitContext *get_nss_ctx(const char *nss_db) -+{ -+ uint32_t flags = NSS_INIT_READONLY -+ | NSS_INIT_FORCEOPEN -+ | NSS_INIT_NOROOTINIT -+ | NSS_INIT_OPTIMIZESPACE -+ | NSS_INIT_PK11RELOAD; -+ NSSInitParameters parameters = { 0 }; -+ parameters.length = sizeof (parameters); -+ -+ return NSS_InitContext(nss_db, "", "", SECMOD_DB, ¶meters, flags); -+} -+ - errno_t init_verification(struct p11_ctx *p11_ctx, - struct cert_verify_opts *cert_verify_opts) - { -@@ -256,14 +270,15 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - SECItem signed_random_value = {0}; - SECKEYPublicKey *pub_key; - CERTCertificate *found_cert = NULL; -- PK11SlotList *list = NULL; -- PK11SlotListElement *le; - const char *label; - char *key_id_str = NULL; - CERTCertList *valid_certs = NULL; - char *cert_b64 = NULL; - char *multi = NULL; - PRCList *node; -+ CK_SLOT_INFO slInfo; -+ PK11TokenStatus token_status; -+ size_t s; - - PK11_SetPasswordFunc(password_passthrough); - -@@ -297,28 +312,50 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - mod_list_item->module->dllName); - } - -- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, -- NULL); -- if (list == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "PK11_GetAllTokens failed.\n"); -- ret = EIO; -- goto done; -- } -+ for (;;) { -+ mod_list = SECMOD_GetDefaultModuleList(); -+ for (mod_list_item = mod_list; mod_list_item != NULL; -+ mod_list_item = mod_list_item->next) { -+ for (s = 0; s < mod_list_item->module->slotCount; s++) { -+ slInfo.flags = 0; -+ rv = PK11_GetSlotInfo(mod_list_item->module->slots[s], &slInfo); -+ DEBUG(SSSDBG_TRACE_ALL, -+ "Description [%s] Manufacturer [%s] flags [%lu] " -+ "removable [%s] token present [%s].\n", -+ slInfo.slotDescription, slInfo.manufacturerID, -+ slInfo.flags, -+ (slInfo.flags & CKF_REMOVABLE_DEVICE) ? "true": "false", -+ (slInfo.flags & CKF_TOKEN_PRESENT) ? "true": "false"); - -- for (le = list->head; le; le = le->next) { -- CK_SLOT_INFO slInfo; -+ if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) { -+ slot = PK11_ReferenceSlot(mod_list_item->module->slots[s]); -+ break; -+ } -+ } -+ } - -- 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); -+ /* When e.g. using Yubikeys the slot isn't present until the device is -+ * inserted, so we should wait for a slot as well. */ -+ if (p11_ctx->wait_for_card && slot == NULL) { -+ rv = NSS_ShutdownContext(p11_ctx->nss_ctx); -+ if (rv != SECSuccess) { -+ DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); -+ } -+ -+ sleep(PKCS11_FINIALIZE_INITIALIZE_WAIT_TIME); -+ -+ p11_ctx->nss_ctx = get_nss_ctx(p11_ctx->nss_db); -+ if (p11_ctx->nss_ctx == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "NSS_InitContext failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); -+ return EIO; -+ } -+ } else { - break; - } - } -- PK11_FreeSlotList(list); -+ - if (slot == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "No removable slots found.\n"); - ret = EIO; -@@ -332,6 +369,22 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - module = PK11_GetModule(slot); - module_name = module->dllName == NULL ? "NSS-Internal" : module->dllName; - -+ if (!(slInfo.flags & CKF_TOKEN_PRESENT)) { -+ DEBUG(SSSDBG_TRACE_ALL, "Token not present.\n"); -+ if (p11_ctx->wait_for_card) { -+ token_status = PK11_WaitForTokenEvent(slot, PK11TokenPresentEvent, -+ PR_INTERVAL_NO_TIMEOUT, 0, 0); -+ if (token_status != PK11TokenPresent) { -+ DEBUG(SSSDBG_OP_FAILURE, "PK11_WaitForTokenEvent failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ } else { -+ ret = EIO; -+ goto done; -+ } -+ } -+ - DEBUG(SSSDBG_TRACE_ALL, "Found [%s] in slot [%s][%d] of module [%d][%s].\n", - token_name, slot_name, (int) slot_id, (int) module_id, module_name); - -@@ -651,26 +704,18 @@ static int talloc_nss_shutdown(struct p11_ctx *p11_ctx) - } - - errno_t init_p11_ctx(TALLOC_CTX *mem_ctx, const char *nss_db, -- struct p11_ctx **p11_ctx) -+ bool wait_for_card, struct p11_ctx **p11_ctx) - { - struct p11_ctx *ctx; -- uint32_t flags = NSS_INIT_READONLY -- | NSS_INIT_FORCEOPEN -- | NSS_INIT_NOROOTINIT -- | NSS_INIT_OPTIMIZESPACE -- | NSS_INIT_PK11RELOAD; -- NSSInitParameters parameters = { 0 }; -- parameters.length = sizeof (parameters); -- - ctx = talloc_zero(mem_ctx, struct p11_ctx); - if (ctx == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); - return ENOMEM; - } - ctx->nss_db = nss_db; -+ ctx->wait_for_card = wait_for_card; - -- ctx->nss_ctx = NSS_InitContext(nss_db, "", "", SECMOD_DB, ¶meters, -- flags); -+ ctx->nss_ctx = get_nss_ctx(nss_db); - if (ctx->nss_ctx == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "NSS_InitContext failed [%d][%s].\n", - PR_GetError(), PORT_ErrorToString(PR_GetError())); -diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c -index bf4418f8603eac4d77d20f464e8b56fb82285f0a..d4572d99cd3a3186128b46cc4a9453d716bd7979 100644 ---- a/src/p11_child/p11_child_openssl.c -+++ b/src/p11_child/p11_child_openssl.c -@@ -40,6 +40,7 @@ - struct p11_ctx { - X509_STORE *x509_store; - const char *ca_db; -+ bool wait_for_card; - }; - - static int talloc_cleanup_openssl(struct p11_ctx *p11_ctx) -@@ -48,8 +49,9 @@ static int talloc_cleanup_openssl(struct p11_ctx *p11_ctx) - - return 0; - } -+ - errno_t init_p11_ctx(TALLOC_CTX *mem_ctx, const char *ca_db, -- struct p11_ctx **p11_ctx) -+ bool wait_for_card, struct p11_ctx **p11_ctx) - { - int ret; - struct p11_ctx *ctx; -@@ -73,6 +75,7 @@ errno_t init_p11_ctx(TALLOC_CTX *mem_ctx, const char *ca_db, - } - - ctx->ca_db = ca_db; -+ ctx->wait_for_card = wait_for_card; - talloc_set_destructor(ctx, talloc_cleanup_openssl); - - *p11_ctx = ctx; -@@ -547,6 +550,45 @@ done: - return ret; - } - -+static errno_t wait_for_card(CK_FUNCTION_LIST *module, CK_SLOT_ID *slot_id) -+{ -+ CK_FLAGS wait_flags = 0; -+ CK_RV rv; -+ CK_SLOT_INFO info; -+ -+ rv = module->C_WaitForSlotEvent(wait_flags, slot_id, NULL); -+ if (rv != CKR_OK) { -+ if (rv != CKR_FUNCTION_NOT_SUPPORTED) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "C_WaitForSlotEvent failed [%lu][%s].\n", -+ rv, p11_kit_strerror(rv)); -+ return EIO; -+ } -+ -+ /* Poor man's wait */ -+ do { -+ sleep(10); -+ rv = module->C_GetSlotInfo(*slot_id, &info); -+ if (rv != CKR_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, "C_GetSlotInfo failed\n"); -+ return EIO; -+ } -+ DEBUG(SSSDBG_TRACE_ALL, -+ "Description [%s] Manufacturer [%s] flags [%lu] " -+ "removable [%s] token present [%s].\n", -+ info.slotDescription, info.manufacturerID, info.flags, -+ (info.flags & CKF_REMOVABLE_DEVICE) ? "true": "false", -+ (info.flags & CKF_TOKEN_PRESENT) ? "true": "false"); -+ if ((info.flags & CKF_REMOVABLE_DEVICE) -+ && (info.flags & CKF_TOKEN_PRESENT)) { -+ break; -+ } -+ } while (true); -+ } -+ -+ return EOK; -+} -+ - #define MAX_SLOTS 64 - - errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, -@@ -588,39 +630,62 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - return EIO; - } - -- DEBUG(SSSDBG_TRACE_ALL, "Module List:\n"); -- for (c = 0; modules[c] != NULL; c++) { -- mod_name = p11_kit_module_get_name(modules[c]); -- mod_file_name = p11_kit_module_get_filename(modules[c]); -- DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n", mod_name); -- DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n", mod_file_name); -- free(mod_name); -- free(mod_file_name); -+ for (;;) { -+ DEBUG(SSSDBG_TRACE_ALL, "Module List:\n"); -+ for (c = 0; modules[c] != NULL; c++) { -+ mod_name = p11_kit_module_get_name(modules[c]); -+ mod_file_name = p11_kit_module_get_filename(modules[c]); -+ DEBUG(SSSDBG_TRACE_ALL, "common name: [%s].\n", mod_name); -+ DEBUG(SSSDBG_TRACE_ALL, "dll name: [%s].\n", mod_file_name); -+ free(mod_name); -+ free(mod_file_name); - -- num_slots = MAX_SLOTS; -- rv = modules[c]->C_GetSlotList(CK_TRUE, slots, &num_slots); -- if (rv != CKR_OK) { -- DEBUG(SSSDBG_OP_FAILURE, "C_GetSlotList failed.\n"); -- ret = EIO; -- goto done; -- } -- -- for (s = 0; s < num_slots; s++) { -- rv = modules[c]->C_GetSlotInfo(slots[s], &info); -+ num_slots = MAX_SLOTS; -+ rv = modules[c]->C_GetSlotList(CK_FALSE, slots, &num_slots); - if (rv != CKR_OK) { -- DEBUG(SSSDBG_OP_FAILURE, "C_GetSlotInfo failed\n"); -+ DEBUG(SSSDBG_OP_FAILURE, "C_GetSlotList failed.\n"); - ret = EIO; - goto done; - } -- DEBUG(SSSDBG_TRACE_ALL, -- "Description [%s] Manufacturer [%s] flags [%lu] removable [%s].\n", -- info.slotDescription, info.manufacturerID, info.flags, -- (info.flags & CKF_REMOVABLE_DEVICE) ? "true": "false"); -- if ((info.flags & CKF_REMOVABLE_DEVICE)) { -+ -+ for (s = 0; s < num_slots; s++) { -+ rv = modules[c]->C_GetSlotInfo(slots[s], &info); -+ if (rv != CKR_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, "C_GetSlotInfo failed\n"); -+ ret = EIO; -+ goto done; -+ } -+ DEBUG(SSSDBG_TRACE_ALL, -+ "Description [%s] Manufacturer [%s] flags [%lu] " -+ "removable [%s] token present [%s].\n", -+ info.slotDescription, info.manufacturerID, info.flags, -+ (info.flags & CKF_REMOVABLE_DEVICE) ? "true": "false", -+ (info.flags & CKF_TOKEN_PRESENT) ? "true": "false"); -+ if ((info.flags & CKF_REMOVABLE_DEVICE)) { -+ break; -+ } -+ } -+ if (s != num_slots) { - break; - } - } -- if (s != num_slots) { -+ -+ /* When e.g. using Yubikeys the slot isn't present until the device is -+ * inserted, so we should wait for a slot as well. */ -+ if (p11_ctx->wait_for_card && modules[c] == NULL) { -+ p11_kit_modules_finalize_and_release(modules); -+ -+ sleep(PKCS11_FINIALIZE_INITIALIZE_WAIT_TIME); -+ -+ modules = p11_kit_modules_load_and_initialize(0); -+ if (modules == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "p11_kit_modules_load_and_initialize failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ } else { - break; - } - } -@@ -631,14 +696,29 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - goto done; - } - -- rv = modules[c]->C_GetTokenInfo(slots[s], &token_info); -- if (rv != CKR_OK) { -- DEBUG(SSSDBG_OP_FAILURE, "C_GetTokenInfo failed.\n"); -- ret = EIO; -- goto done; -- } -- - slot_id = slots[s]; -+ -+ if (!(info.flags & CKF_TOKEN_PRESENT)) { -+ DEBUG(SSSDBG_TRACE_ALL, "Token not present.\n"); -+ if (p11_ctx->wait_for_card) { -+ ret = wait_for_card(modules[c], &slot_id); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "wait_for_card failed.\n"); -+ goto done; -+ } -+ } else { -+ ret = EIO; -+ goto done; -+ } -+ } -+ -+ rv = modules[c]->C_GetTokenInfo(slot_id, &token_info); -+ if (rv != CKR_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, "C_GetTokenInfo failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ - module_id = c; - slot_name = p11_kit_space_strdup(info.slotDescription, - sizeof(info.slotDescription)); --- -2.14.4 - diff --git a/SOURCES/0038-AD-Implement-background-refresh-for-AD-domains.patch b/SOURCES/0038-AD-Implement-background-refresh-for-AD-domains.patch new file mode 100644 index 0000000..6a80ec6 --- /dev/null +++ b/SOURCES/0038-AD-Implement-background-refresh-for-AD-domains.patch @@ -0,0 +1,589 @@ +From 10e3f8bddc8dd4799c0da68aebf09aa3435950f5 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 24 Apr 2019 20:52:11 +0200 +Subject: [PATCH 38/48] AD: Implement background refresh for AD domains + +Split out the actual useful functionality from the AD account handler +into a tevent request. This tevent request is then subsequently used by +a new ad_refresh module. + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + Makefile.am | 5 +- + src/providers/ad/ad_common.h | 4 + + src/providers/ad/ad_id.c | 140 +++++++++++++---- + src/providers/ad/ad_id.h | 10 ++ + src/providers/ad/ad_init.c | 2 +- + src/providers/ad/ad_refresh.c | 283 ++++++++++++++++++++++++++++++++++ + 6 files changed, 412 insertions(+), 32 deletions(-) + create mode 100644 src/providers/ad/ad_refresh.c + +diff --git a/Makefile.am b/Makefile.am +index 043a7ebb4..f9f17904e 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -4502,7 +4502,10 @@ libsss_ad_la_SOURCES = \ + src/providers/ad/ad_gpo_ndr.c \ + src/providers/ad/ad_srv.c \ + src/providers/ad/ad_subdomains.c \ +- src/providers/ad/ad_domain_info.c ++ src/providers/ad/ad_domain_info.c \ ++ src/providers/ad/ad_refresh.c \ ++ $(NULL) ++ + + if BUILD_SUDO + libsss_ad_la_SOURCES += \ +diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h +index e224254e1..75f11de2e 100644 +--- a/src/providers/ad/ad_common.h ++++ b/src/providers/ad/ad_common.h +@@ -224,4 +224,8 @@ errno_t ad_inherit_opts_if_needed(struct dp_option *parent_opts, + struct confdb_ctx *cdb, + const char *subdom_conf_path, + int opt_id); ++ ++errno_t ad_refresh_init(struct be_ctx *be_ctx, ++ struct ad_id_ctx *id_ctx); ++ + #endif /* AD_COMMON_H_ */ +diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c +index c3bda1662..eb6e36824 100644 +--- a/src/providers/ad/ad_id.c ++++ b/src/providers/ad/ad_id.c +@@ -360,44 +360,36 @@ get_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx, + return clist; + } + +-struct ad_account_info_handler_state { +- struct sss_domain_info *domain; +- struct dp_reply_std reply; ++struct ad_account_info_state { ++ const char *err_msg; ++ int dp_error; + }; + +-static void ad_account_info_handler_done(struct tevent_req *subreq); ++static void ad_account_info_done(struct tevent_req *subreq); + + struct tevent_req * +-ad_account_info_handler_send(TALLOC_CTX *mem_ctx, +- struct ad_id_ctx *id_ctx, +- struct dp_id_data *data, +- struct dp_req_params *params) ++ad_account_info_send(TALLOC_CTX *mem_ctx, ++ struct be_ctx *be_ctx, ++ struct ad_id_ctx *id_ctx, ++ struct dp_id_data *data) + { +- struct ad_account_info_handler_state *state; +- struct sdap_id_conn_ctx **clist; +- struct sdap_id_ctx *sdap_id_ctx; +- struct sss_domain_info *domain; ++ struct sss_domain_info *domain = NULL; ++ struct ad_account_info_state *state = NULL; ++ struct tevent_req *req = NULL; ++ struct tevent_req *subreq = NULL; ++ struct sdap_id_conn_ctx **clist = NULL; ++ struct sdap_id_ctx *sdap_id_ctx = NULL; + struct sdap_domain *sdom; +- struct tevent_req *subreq; +- struct tevent_req *req; +- struct be_ctx *be_ctx; + errno_t ret; + +- sdap_id_ctx = id_ctx->sdap_id_ctx; +- be_ctx = params->be_ctx; +- + req = tevent_req_create(mem_ctx, &state, +- struct ad_account_info_handler_state); ++ struct ad_account_info_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); + return NULL; + } + +- if (sdap_is_enum_request(data)) { +- DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n"); +- ret = EOK; +- goto immediately; +- } ++ sdap_id_ctx = id_ctx->sdap_id_ctx; + + domain = be_ctx->domain; + if (strcasecmp(data->domain, be_ctx->domain->name) != 0) { +@@ -406,6 +398,7 @@ ad_account_info_handler_send(TALLOC_CTX *mem_ctx, + } + + if (domain == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unknown domain\n"); + ret = EINVAL; + goto immediately; + } +@@ -413,6 +406,7 @@ ad_account_info_handler_send(TALLOC_CTX *mem_ctx, + /* Determine whether to connect to GC, LDAP or try both. */ + clist = get_conn_list(state, id_ctx, domain, data); + if (clist == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create conn list\n"); + ret = EIO; + goto immediately; + } +@@ -423,14 +417,100 @@ ad_account_info_handler_send(TALLOC_CTX *mem_ctx, + goto immediately; + } + +- state->domain = sdom->dom; +- + subreq = ad_handle_acct_info_send(state, data, sdap_id_ctx, + id_ctx->ad_options, sdom, clist); + if (subreq == NULL) { + ret = ENOMEM; + goto immediately; + } ++ tevent_req_set_callback(subreq, ad_account_info_done, req); ++ return req; ++ ++immediately: ++ tevent_req_error(req, ret); ++ tevent_req_post(req, be_ctx->ev); ++ return req; ++} ++ ++static void ad_account_info_done(struct tevent_req *subreq) ++{ ++ struct ad_account_info_state *state = NULL; ++ struct tevent_req *req = NULL; ++ errno_t ret; ++ ++ req = tevent_req_callback_data(subreq, struct tevent_req); ++ state = tevent_req_data(req, struct ad_account_info_state); ++ ++ ret = ad_handle_acct_info_recv(subreq, &state->dp_error, &state->err_msg); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "ad_handle_acct_info_recv failed [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ /* The caller wouldn't fail either, just report the error up */ ++ } ++ talloc_zfree(subreq); ++ tevent_req_done(req); ++} ++ ++errno_t ad_account_info_recv(struct tevent_req *req, ++ int *_dp_error, ++ const char **_err_msg) ++{ ++ struct ad_account_info_state *state = NULL; ++ ++ state = tevent_req_data(req, struct ad_account_info_state); ++ ++ if (_err_msg != NULL) { ++ *_err_msg = state->err_msg; ++ } ++ ++ if (_dp_error) { ++ *_dp_error = state->dp_error; ++ } ++ ++ ++ TEVENT_REQ_RETURN_ON_ERROR(req); ++ ++ return EOK; ++} ++ ++struct ad_account_info_handler_state { ++ struct sss_domain_info *domain; ++ struct dp_reply_std reply; ++}; ++ ++static void ad_account_info_handler_done(struct tevent_req *subreq); ++ ++struct tevent_req * ++ad_account_info_handler_send(TALLOC_CTX *mem_ctx, ++ struct ad_id_ctx *id_ctx, ++ struct dp_id_data *data, ++ struct dp_req_params *params) ++{ ++ struct ad_account_info_handler_state *state; ++ struct tevent_req *subreq; ++ struct tevent_req *req; ++ errno_t ret; ++ ++ ++ req = tevent_req_create(mem_ctx, &state, ++ struct ad_account_info_handler_state); ++ if (req == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); ++ return NULL; ++ } ++ ++ if (sdap_is_enum_request(data)) { ++ DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n"); ++ ret = EOK; ++ goto immediately; ++ } ++ ++ subreq = ad_account_info_send(state, params->be_ctx, id_ctx, data); ++ if (subreq == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } + + tevent_req_set_callback(subreq, ad_account_info_handler_done, req); + +@@ -451,13 +531,13 @@ static void ad_account_info_handler_done(struct tevent_req *subreq) + struct ad_account_info_handler_state *state; + struct tevent_req *req; + const char *err_msg; +- int dp_error; ++ int dp_error = DP_ERR_FATAL; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ad_account_info_handler_state); + +- ret = ad_handle_acct_info_recv(subreq, &dp_error, &err_msg); ++ ret = ad_account_info_recv(subreq, &dp_error, &err_msg); + talloc_zfree(subreq); + + /* TODO For backward compatibility we always return EOK to DP now. */ +@@ -466,8 +546,8 @@ static void ad_account_info_handler_done(struct tevent_req *subreq) + } + + errno_t ad_account_info_handler_recv(TALLOC_CTX *mem_ctx, +- struct tevent_req *req, +- struct dp_reply_std *data) ++ struct tevent_req *req, ++ struct dp_reply_std *data) + { + struct ad_account_info_handler_state *state = NULL; + +diff --git a/src/providers/ad/ad_id.h b/src/providers/ad/ad_id.h +index 5154393c5..19cc54eec 100644 +--- a/src/providers/ad/ad_id.h ++++ b/src/providers/ad/ad_id.h +@@ -33,6 +33,16 @@ errno_t ad_account_info_handler_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + struct dp_reply_std *data); + ++struct tevent_req * ++ad_account_info_send(TALLOC_CTX *mem_ctx, ++ struct be_ctx *be_ctx, ++ struct ad_id_ctx *id_ctx, ++ struct dp_id_data *data); ++ ++errno_t ad_account_info_recv(struct tevent_req *req, ++ int *_dp_error, ++ const char **_err_msg); ++ + struct tevent_req * + ad_handle_acct_info_send(TALLOC_CTX *mem_ctx, + struct dp_id_data *ar, +diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c +index b8ebaea2f..42c17de00 100644 +--- a/src/providers/ad/ad_init.c ++++ b/src/providers/ad/ad_init.c +@@ -408,7 +408,7 @@ static errno_t ad_init_misc(struct be_ctx *be_ctx, + return ret; + } + +- ret = sdap_refresh_init(be_ctx, sdap_id_ctx); ++ ret = ad_refresh_init(be_ctx, ad_id_ctx); + if (ret != EOK && ret != EEXIST) { + DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh " + "will not work [%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/providers/ad/ad_refresh.c b/src/providers/ad/ad_refresh.c +new file mode 100644 +index 000000000..ee541056f +--- /dev/null ++++ b/src/providers/ad/ad_refresh.c +@@ -0,0 +1,283 @@ ++/* ++ Copyright (C) 2019 Red Hat ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++*/ ++ ++#include ++#include ++ ++#include "providers/ad/ad_common.h" ++#include "providers/ad/ad_id.h" ++ ++struct ad_refresh_state { ++ struct tevent_context *ev; ++ struct be_ctx *be_ctx; ++ struct dp_id_data *account_req; ++ struct ad_id_ctx *id_ctx; ++ char **names; ++ size_t index; ++}; ++ ++static errno_t ad_refresh_step(struct tevent_req *req); ++static void ad_refresh_done(struct tevent_req *subreq); ++ ++static struct tevent_req *ad_refresh_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ int entry_type, ++ char **names, ++ void *pvt) ++{ ++ struct ad_refresh_state *state = NULL; ++ struct tevent_req *req = NULL; ++ errno_t ret; ++ uint32_t filter_type; ++ ++ req = tevent_req_create(mem_ctx, &state, ++ struct ad_refresh_state); ++ if (req == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); ++ return NULL; ++ } ++ ++ if (names == NULL) { ++ ret = EOK; ++ goto immediately; ++ } ++ ++ state->ev = ev; ++ state->be_ctx = be_ctx; ++ state->id_ctx = talloc_get_type(pvt, struct ad_id_ctx); ++ state->names = names; ++ state->index = 0; ++ ++ switch (entry_type) { ++ case BE_REQ_NETGROUP: ++ filter_type = BE_FILTER_NAME; ++ break; ++ case BE_REQ_USER: ++ case BE_REQ_GROUP: ++ filter_type = BE_FILTER_SECID; ++ break; ++ default: ++ ret = EINVAL; ++ goto immediately; ++ } ++ ++ state->account_req = be_refresh_acct_req(state, entry_type, ++ filter_type, domain); ++ if (state->account_req == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } ++ ++ ret = ad_refresh_step(req); ++ if (ret == EOK) { ++ DEBUG(SSSDBG_TRACE_FUNC, "Nothing to refresh\n"); ++ goto immediately; ++ } else if (ret != EAGAIN) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "ad_refresh_step() failed " ++ "[%d]: %s\n", ret, sss_strerror(ret)); ++ goto immediately; ++ } ++ ++ return req; ++ ++immediately: ++ if (ret == EOK) { ++ tevent_req_done(req); ++ } else { ++ tevent_req_error(req, ret); ++ } ++ tevent_req_post(req, ev); ++ ++ return req; ++} ++ ++static errno_t ad_refresh_step(struct tevent_req *req) ++{ ++ struct ad_refresh_state *state = NULL; ++ struct tevent_req *subreq = NULL; ++ errno_t ret; ++ ++ state = tevent_req_data(req, struct ad_refresh_state); ++ ++ if (state->names == NULL) { ++ ret = EOK; ++ goto done; ++ } ++ ++ state->account_req->filter_value = state->names[state->index]; ++ if (state->account_req->filter_value == NULL) { ++ ret = EOK; ++ goto done; ++ } ++ ++ DEBUG(SSSDBG_TRACE_FUNC, "Issuing refresh of %s %s\n", ++ be_req2str(state->account_req->entry_type), ++ state->account_req->filter_value); ++ ++ subreq = ad_account_info_send(state, state->be_ctx, state->id_ctx, ++ state->account_req); ++ if (subreq == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ tevent_req_set_callback(subreq, ad_refresh_done, req); ++ ++ state->index++; ++ ret = EAGAIN; ++ ++done: ++ return ret; ++} ++ ++static void ad_refresh_done(struct tevent_req *subreq) ++{ ++ struct ad_refresh_state *state = NULL; ++ struct tevent_req *req = NULL; ++ const char *err_msg = NULL; ++ errno_t dp_error; ++ errno_t ret; ++ ++ req = tevent_req_callback_data(subreq, struct tevent_req); ++ state = tevent_req_data(req, struct ad_refresh_state); ++ ++ ret = ad_account_info_recv(subreq, &dp_error, &err_msg); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to refresh %s [dp_error: %d, " ++ "errno: %d]: %s\n", be_req2str(state->account_req->entry_type), ++ dp_error, ret, err_msg); ++ goto done; ++ } ++ ++ ret = ad_refresh_step(req); ++ if (ret == EAGAIN) { ++ return; ++ } ++ ++done: ++ if (ret != EOK) { ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ tevent_req_done(req); ++} ++ ++static errno_t ad_refresh_recv(struct tevent_req *req) ++{ ++ TEVENT_REQ_RETURN_ON_ERROR(req); ++ ++ return EOK; ++} ++ ++static struct tevent_req * ++ad_refresh_users_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return ad_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_USER, names, pvt); ++} ++ ++static errno_t ad_refresh_users_recv(struct tevent_req *req) ++{ ++ return ad_refresh_recv(req); ++} ++ ++static struct tevent_req * ++ad_refresh_groups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return ad_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_GROUP, names, pvt); ++} ++ ++static errno_t ad_refresh_groups_recv(struct tevent_req *req) ++{ ++ return ad_refresh_recv(req); ++} ++ ++static struct tevent_req * ++ad_refresh_netgroups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return ad_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_NETGROUP, names, pvt); ++} ++ ++static errno_t ad_refresh_netgroups_recv(struct tevent_req *req) ++{ ++ return ad_refresh_recv(req); ++} ++ ++errno_t ad_refresh_init(struct be_ctx *be_ctx, ++ struct ad_id_ctx *id_ctx) ++{ ++ errno_t ret; ++ ++ ret = be_refresh_ctx_init(be_ctx, SYSDB_SID_STR); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n"); ++ return ret; ++ } ++ ++ ret = be_refresh_add_cb(be_ctx->refresh_ctx, ++ BE_REFRESH_TYPE_USERS, ++ ad_refresh_users_send, ++ ad_refresh_users_recv, ++ id_ctx); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ ++ ret = be_refresh_add_cb(be_ctx->refresh_ctx, ++ BE_REFRESH_TYPE_GROUPS, ++ ad_refresh_groups_send, ++ ad_refresh_groups_recv, ++ id_ctx); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of groups " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ ++ ret = be_refresh_add_cb(be_ctx->refresh_ctx, ++ BE_REFRESH_TYPE_NETGROUPS, ++ ad_refresh_netgroups_send, ++ ad_refresh_netgroups_recv, ++ id_ctx); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ ++ return ret; ++} +-- +2.20.1 + diff --git a/SOURCES/0038-PAM-add-p11_wait_for_card_timeout-option.patch b/SOURCES/0038-PAM-add-p11_wait_for_card_timeout-option.patch deleted file mode 100644 index d3931d1..0000000 --- a/SOURCES/0038-PAM-add-p11_wait_for_card_timeout-option.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 8ec8702a9f06f7c4fe2f4bbfed33a0b3b73f1961 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 18 Sep 2018 18:15:02 +0200 -Subject: [PATCH 38/47] PAM: add p11_wait_for_card_timeout option - -If the --wait_for_card is used to call p11_child the PAM responder -should be prepared to wait longer until p11_child can return -successfully. - -Related to https://pagure.io/SSSD/sssd/issue/3650 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 2e4ecf5a866b212bef44e262fd90c67a88dc616a) ---- - src/confdb/confdb.h | 1 + - src/config/SSSDConfig/__init__.py.in | 1 + - src/config/cfg_rules.ini | 1 + - src/config/etc/sssd.api.conf | 1 + - src/man/sssd.conf.5.xml | 14 ++++++++++++++ - src/responder/pam/pamsrv_cmd.c | 15 +++++++++++++++ - src/util/util.h | 1 + - 7 files changed, 34 insertions(+) - -diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h -index 625d156267ebf5f59e3974663256acfbb5f3b027..87904c2146b33b57106ac3799c5a67ee02387e9b 100644 ---- a/src/confdb/confdb.h -+++ b/src/confdb/confdb.h -@@ -130,6 +130,7 @@ - #define CONFDB_PAM_CERT_AUTH "pam_cert_auth" - #define CONFDB_PAM_CERT_DB_PATH "pam_cert_db_path" - #define CONFDB_PAM_P11_CHILD_TIMEOUT "p11_child_timeout" -+#define CONFDB_PAM_WAIT_FOR_CARD_TIMEOUT "p11_wait_for_card_timeout" - #define CONFDB_PAM_APP_SERVICES "pam_app_services" - #define CONFDB_PAM_P11_ALLOWED_SERVICES "pam_p11_allowed_services" - -diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in -index 81a03adfe91120233afbaed4d2522788b56bea94..4d1dba2d22eae4716fbabe3a3957952f7cd17751 100644 ---- a/src/config/SSSDConfig/__init__.py.in -+++ b/src/config/SSSDConfig/__init__.py.in -@@ -104,6 +104,7 @@ option_strings = { - 'p11_child_timeout' : _('How many seconds will pam_sss wait for p11_child to finish'), - 'pam_app_services' : _('Which PAM services are permitted to contact application domains'), - 'pam_p11_allowed_services' : _('Allowed services for using smartcards'), -+ 'p11_wait_for_card_timeout' : _('Additional timeout to wait for a card if requested'), - - # [sudo] - 'sudo_timed' : _('Whether to evaluate the time-based attributes in sudo rules'), -diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini -index 36e83a932d6b66cae129a03fb137ba5e4e3092b2..717ccfa3f382b92800bf00ed79f68641a5a83d5c 100644 ---- a/src/config/cfg_rules.ini -+++ b/src/config/cfg_rules.ini -@@ -127,6 +127,7 @@ option = pam_cert_db_path - option = p11_child_timeout - option = pam_app_services - option = pam_p11_allowed_services -+option = p11_wait_for_card_timeout - - [rule/allowed_sudo_options] - validator = ini_allowed_options -diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf -index 52494c0e6d50efc2d31c56c0fe023dc9c07e35ba..bb686c34480be27d0829b57a853fa05921730630 100644 ---- a/src/config/etc/sssd.api.conf -+++ b/src/config/etc/sssd.api.conf -@@ -76,6 +76,7 @@ pam_cert_db_path = str, None, false - p11_child_timeout = int, None, false - pam_app_services = str, None, false - pam_p11_allowed_services = str, None, false -+p11_wait_for_card_timeout = int, None, false - - [sudo] - # sudo service -diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml -index c1e38950f99cb8df4c59fe10866632030d3c6f25..4df0163311fb3845e6a027be7d0b500cb5d2f0b6 100644 ---- a/src/man/sssd.conf.5.xml -+++ b/src/man/sssd.conf.5.xml -@@ -1464,6 +1464,20 @@ pam_p11_allowed_services = +my_pam_service, -login - - - -+ -+ p11_wait_for_card_timeout (integer) -+ -+ -+ If Smartcard authentication is required how many -+ extra seconds in addition to p11_child_timeout -+ should the PAM responder wait until a Smartcard is -+ inserted. -+ -+ -+ Default: 60 -+ -+ -+ - - - -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index 817f3c5134ba4c7358ffb4fbf3c6008fa23ffe0e..c8df32de9e72e9f5ce33e26f0a13101a99f01d5f 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -1297,6 +1297,7 @@ static errno_t check_cert(TALLOC_CTX *mctx, - struct pam_data *pd) - { - int p11_child_timeout; -+ int wait_for_card_timeout; - char *cert_verification_opts; - errno_t ret; - struct tevent_req *req; -@@ -1311,6 +1312,20 @@ static errno_t check_cert(TALLOC_CTX *mctx, - ret, sss_strerror(ret)); - return ret; - } -+ if ((pd->cli_flags & PAM_CLI_FLAGS_REQUIRE_CERT_AUTH) && pd->priv == 1) { -+ ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, -+ CONFDB_PAM_WAIT_FOR_CARD_TIMEOUT, -+ P11_WAIT_FOR_CARD_TIMEOUT_DEFAULT, -+ &wait_for_card_timeout); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to read wait_for_card_timeout from confdb: [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ return ret; -+ } -+ -+ p11_child_timeout += wait_for_card_timeout; -+ } - - ret = confdb_get_string(pctx->rctx->cdb, mctx, CONFDB_MONITOR_CONF_ENTRY, - CONFDB_MONITOR_CERT_VERIFICATION, NULL, -diff --git a/src/util/util.h b/src/util/util.h -index 59e7a96ba58aa9400166514064922d25fb713deb..e3e91009728cd8a5a92701220c06e8c378f47431 100644 ---- a/src/util/util.h -+++ b/src/util/util.h -@@ -724,6 +724,7 @@ errno_t create_preauth_indicator(void); - #define P11_CHILD_LOG_FILE "p11_child" - #define P11_CHILD_PATH SSSD_LIBEXEC_PATH"/p11_child" - #define P11_CHILD_TIMEOUT_DEFAULT 10 -+#define P11_WAIT_FOR_CARD_TIMEOUT_DEFAULT 60 - #endif /* SSSD_LIBEXEC_PATH */ - - #endif /* __SSSD_UTIL_H__ */ --- -2.14.4 - diff --git a/SOURCES/0039-IPA-Implement-background-refresh-for-IPA-domains.patch b/SOURCES/0039-IPA-Implement-background-refresh-for-IPA-domains.patch new file mode 100644 index 0000000..1dfa06b --- /dev/null +++ b/SOURCES/0039-IPA-Implement-background-refresh-for-IPA-domains.patch @@ -0,0 +1,547 @@ +From 3847082fe85520ab86cefcf78d9ffe6c6df0a04f Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 8 May 2019 14:39:23 +0200 +Subject: [PATCH 39/48] IPA: Implement background refresh for IPA domains + +Split out the actual useful functionality from the IPA account lookup +handler into a tevent request. This tevent request is then used in a new +ipa_refresh module. + +Related: +https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + Makefile.am | 1 + + src/providers/ipa/ipa_common.h | 3 + + src/providers/ipa/ipa_id.c | 140 +++++++++++++---- + src/providers/ipa/ipa_id.h | 8 + + src/providers/ipa/ipa_init.c | 2 +- + src/providers/ipa/ipa_refresh.c | 264 ++++++++++++++++++++++++++++++++ + 6 files changed, 386 insertions(+), 32 deletions(-) + create mode 100644 src/providers/ipa/ipa_refresh.c + +diff --git a/Makefile.am b/Makefile.am +index f9f17904e..cbd6bbfdb 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -4430,6 +4430,7 @@ libsss_ipa_la_SOURCES = \ + src/providers/ipa/ipa_srv.c \ + src/providers/ipa/ipa_idmap.c \ + src/providers/ipa/ipa_dn.c \ ++ src/providers/ipa/ipa_refresh.c \ + src/providers/ad/ad_opts.c \ + src/providers/ad/ad_common.c \ + src/providers/ad/ad_dyndns.c \ +diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h +index 31e671eb5..6bb1739ef 100644 +--- a/src/providers/ipa/ipa_common.h ++++ b/src/providers/ipa/ipa_common.h +@@ -301,4 +301,7 @@ errno_t ipa_get_host_attrs(struct dp_option *ipa_options, + struct sysdb_attrs **hosts, + struct sysdb_attrs **_ipa_host); + ++errno_t ipa_refresh_init(struct be_ctx *be_ctx, ++ struct ipa_id_ctx *id_ctx); ++ + #endif /* _IPA_COMMON_H_ */ +diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c +index e644af5ff..9abee34cb 100644 +--- a/src/providers/ipa/ipa_id.c ++++ b/src/providers/ipa/ipa_id.c +@@ -1344,43 +1344,39 @@ ipa_decide_account_info_type(struct dp_id_data *data, struct be_ctx *be_ctx) + return IPA_ACCOUNT_INFO_OTHER; + } + +-struct ipa_account_info_handler_state { ++struct ipa_account_info_state { + enum ipa_account_info_type type; +- struct dp_reply_std reply; ++ ++ const char *err_msg; ++ int dp_error; + }; + +-static void ipa_account_info_handler_done(struct tevent_req *subreq); ++static void ipa_account_info_done(struct tevent_req *subreq); + + struct tevent_req * +-ipa_account_info_handler_send(TALLOC_CTX *mem_ctx, +- struct ipa_id_ctx *id_ctx, +- struct dp_id_data *data, +- struct dp_req_params *params) ++ipa_account_info_send(TALLOC_CTX *mem_ctx, ++ struct be_ctx *be_ctx, ++ struct ipa_id_ctx *id_ctx, ++ struct dp_id_data *data) + { +- struct ipa_account_info_handler_state *state; ++ struct ipa_account_info_state *state = NULL; ++ struct tevent_req *req = NULL; + struct tevent_req *subreq = NULL; +- struct tevent_req *req; + errno_t ret; + + req = tevent_req_create(mem_ctx, &state, +- struct ipa_account_info_handler_state); ++ struct ipa_account_info_state); + if (req == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); + return NULL; + } + +- state->type = ipa_decide_account_info_type(data, params->be_ctx); +- +- if (sdap_is_enum_request(data)) { +- DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n"); +- ret = EOK; +- goto immediately; +- } ++ state->type = ipa_decide_account_info_type(data, be_ctx); + + switch (state->type) { + case IPA_ACCOUNT_INFO_SUBDOMAIN: + /* Subdomain lookups are handled differently on server and client. */ +- subreq = ipa_subdomain_account_send(state, params->ev, id_ctx, data); ++ subreq = ipa_subdomain_account_send(state, be_ctx->ev, id_ctx, data); + break; + case IPA_ACCOUNT_INFO_NETGROUP: + if (data->filter_type != BE_FILTER_NAME) { +@@ -1388,11 +1384,11 @@ ipa_account_info_handler_send(TALLOC_CTX *mem_ctx, + goto immediately; + } + +- subreq = ipa_id_get_netgroup_send(state, params->ev, id_ctx, ++ subreq = ipa_id_get_netgroup_send(state, be_ctx->ev, id_ctx, + data->filter_value); + break; + case IPA_ACCOUNT_INFO_OTHER: +- subreq = ipa_id_get_account_info_send(state, params->ev, id_ctx, data); ++ subreq = ipa_id_get_account_info_send(state, be_ctx->ev, id_ctx, data); + break; + } + +@@ -1400,7 +1396,99 @@ ipa_account_info_handler_send(TALLOC_CTX *mem_ctx, + ret = ENOMEM; + goto immediately; + } ++ tevent_req_set_callback(subreq, ipa_account_info_done, req); ++ return req; ++ ++immediately: ++ tevent_req_error(req, ret); ++ tevent_req_post(req, be_ctx->ev); ++ return req; ++} ++ ++static void ipa_account_info_done(struct tevent_req *subreq) ++{ ++ struct ipa_account_info_state *state = NULL; ++ struct tevent_req *req = NULL; ++ errno_t ret; ++ ++ req = tevent_req_callback_data(subreq, struct tevent_req); ++ state = tevent_req_data(req, struct ipa_account_info_state); ++ ++ switch (state->type) { ++ case IPA_ACCOUNT_INFO_SUBDOMAIN: ++ ret = ipa_subdomain_account_recv(subreq, &state->dp_error); ++ break; ++ case IPA_ACCOUNT_INFO_NETGROUP: ++ ret = ipa_id_get_netgroup_recv(subreq, &state->dp_error); ++ break; ++ case IPA_ACCOUNT_INFO_OTHER: ++ ret = ipa_id_get_account_info_recv(subreq, &state->dp_error); ++ break; ++ default: ++ ret = EINVAL; ++ break; ++ } ++ talloc_zfree(subreq); ++ ++ if (ret != EOK) { ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ tevent_req_done(req); ++} + ++errno_t ipa_account_info_recv(struct tevent_req *req, ++ int *_dp_error) ++{ ++ struct ipa_account_info_state *state = NULL; ++ ++ state = tevent_req_data(req, struct ipa_account_info_state); ++ ++ /* Fail the request after collecting the dp_error */ ++ if (_dp_error) { ++ *_dp_error = state->dp_error; ++ } ++ ++ TEVENT_REQ_RETURN_ON_ERROR(req); ++ return EOK; ++} ++ ++struct ipa_account_info_handler_state { ++ struct dp_reply_std reply; ++}; ++ ++static void ipa_account_info_handler_done(struct tevent_req *subreq); ++ ++struct tevent_req * ++ipa_account_info_handler_send(TALLOC_CTX *mem_ctx, ++ struct ipa_id_ctx *id_ctx, ++ struct dp_id_data *data, ++ struct dp_req_params *params) ++{ ++ struct ipa_account_info_handler_state *state; ++ struct tevent_req *subreq = NULL; ++ struct tevent_req *req; ++ errno_t ret; ++ ++ req = tevent_req_create(mem_ctx, &state, ++ struct ipa_account_info_handler_state); ++ if (req == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); ++ return NULL; ++ } ++ ++ if (sdap_is_enum_request(data)) { ++ DEBUG(SSSDBG_TRACE_LIBS, "Skipping enumeration on demand\n"); ++ ret = EOK; ++ goto immediately; ++ } ++ ++ subreq = ipa_account_info_send(state, params->be_ctx, id_ctx, data); ++ if (subreq == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } + tevent_req_set_callback(subreq, ipa_account_info_handler_done, req); + + return req; +@@ -1425,17 +1513,7 @@ static void ipa_account_info_handler_done(struct tevent_req *subreq) + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ipa_account_info_handler_state); + +- switch (state->type) { +- case IPA_ACCOUNT_INFO_SUBDOMAIN: +- ret = ipa_subdomain_account_recv(subreq, &dp_error); +- break; +- case IPA_ACCOUNT_INFO_NETGROUP: +- ret = ipa_id_get_netgroup_recv(subreq, &dp_error); +- break; +- case IPA_ACCOUNT_INFO_OTHER: +- ret = ipa_id_get_account_info_recv(subreq, &dp_error); +- break; +- } ++ ret = ipa_account_info_recv(subreq, &dp_error); + talloc_zfree(subreq); + + /* TODO For backward compatibility we always return EOK to DP now. */ +diff --git a/src/providers/ipa/ipa_id.h b/src/providers/ipa/ipa_id.h +index 4b2549882..fe9acfeef 100644 +--- a/src/providers/ipa/ipa_id.h ++++ b/src/providers/ipa/ipa_id.h +@@ -33,6 +33,14 @@ + + #define IPA_DEFAULT_VIEW_NAME "Default Trust View" + ++struct tevent_req * ++ipa_account_info_send(TALLOC_CTX *mem_ctx, ++ struct be_ctx *be_ctx, ++ struct ipa_id_ctx *id_ctx, ++ struct dp_id_data *data); ++errno_t ipa_account_info_recv(struct tevent_req *req, ++ int *_dp_error); ++ + struct tevent_req * + ipa_account_info_handler_send(TALLOC_CTX *mem_ctx, + struct ipa_id_ctx *id_ctx, +diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c +index b3060e228..cdfd11d7a 100644 +--- a/src/providers/ipa/ipa_init.c ++++ b/src/providers/ipa/ipa_init.c +@@ -594,7 +594,7 @@ static errno_t ipa_init_misc(struct be_ctx *be_ctx, + } + } + +- ret = sdap_refresh_init(be_ctx, sdap_id_ctx); ++ ret = ipa_refresh_init(be_ctx, ipa_id_ctx); + if (ret != EOK && ret != EEXIST) { + DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh " + "will not work [%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/providers/ipa/ipa_refresh.c b/src/providers/ipa/ipa_refresh.c +new file mode 100644 +index 000000000..72051cfdd +--- /dev/null ++++ b/src/providers/ipa/ipa_refresh.c +@@ -0,0 +1,264 @@ ++/* ++ Copyright (C) 2019 Red Hat ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see . ++*/ ++ ++#include ++#include ++ ++#include "providers/ipa/ipa_common.h" ++#include "providers/ipa/ipa_id.h" ++ ++struct ipa_refresh_state { ++ struct tevent_context *ev; ++ struct be_ctx *be_ctx; ++ struct dp_id_data *account_req; ++ struct ipa_id_ctx *id_ctx; ++ char **names; ++ size_t index; ++}; ++ ++static errno_t ipa_refresh_step(struct tevent_req *req); ++static void ipa_refresh_done(struct tevent_req *subreq); ++ ++static struct tevent_req *ipa_refresh_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ int entry_type, ++ char **names, ++ void *pvt) ++{ ++ struct ipa_refresh_state *state = NULL; ++ struct tevent_req *req = NULL; ++ errno_t ret; ++ ++ req = tevent_req_create(mem_ctx, &state, ++ struct ipa_refresh_state); ++ if (req == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); ++ return NULL; ++ } ++ ++ if (names == NULL) { ++ ret = EOK; ++ goto immediately; ++ } ++ ++ state->ev = ev; ++ state->be_ctx = be_ctx; ++ state->id_ctx = talloc_get_type(pvt, struct ipa_id_ctx); ++ state->names = names; ++ state->index = 0; ++ ++ state->account_req = be_refresh_acct_req(state, entry_type, ++ BE_FILTER_NAME, domain); ++ if (state->account_req == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } ++ ++ ret = ipa_refresh_step(req); ++ if (ret == EOK) { ++ DEBUG(SSSDBG_TRACE_FUNC, "Nothing to refresh\n"); ++ goto immediately; ++ } else if (ret != EAGAIN) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "ipa_refresh_step() failed " ++ "[%d]: %s\n", ret, sss_strerror(ret)); ++ goto immediately; ++ } ++ ++ return req; ++ ++immediately: ++ if (ret == EOK) { ++ tevent_req_done(req); ++ } else { ++ tevent_req_error(req, ret); ++ } ++ tevent_req_post(req, ev); ++ ++ return req; ++} ++ ++static errno_t ipa_refresh_step(struct tevent_req *req) ++{ ++ struct ipa_refresh_state *state = NULL; ++ struct tevent_req *subreq = NULL; ++ errno_t ret; ++ ++ state = tevent_req_data(req, struct ipa_refresh_state); ++ ++ if (state->names == NULL) { ++ ret = EOK; ++ goto done; ++ } ++ ++ state->account_req->filter_value = state->names[state->index]; ++ if (state->account_req->filter_value == NULL) { ++ ret = EOK; ++ goto done; ++ } ++ ++ subreq = ipa_account_info_send(state, state->be_ctx, state->id_ctx, ++ state->account_req); ++ if (subreq == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ tevent_req_set_callback(subreq, ipa_refresh_done, req); ++ ++ state->index++; ++ ret = EAGAIN; ++ ++done: ++ return ret; ++} ++ ++static void ipa_refresh_done(struct tevent_req *subreq) ++{ ++ struct ipa_refresh_state *state = NULL; ++ struct tevent_req *req = NULL; ++ errno_t dp_error; ++ errno_t ret; ++ ++ req = tevent_req_callback_data(subreq, struct tevent_req); ++ state = tevent_req_data(req, struct ipa_refresh_state); ++ ++ ret = ipa_account_info_recv(subreq, &dp_error); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to refresh %s [dp_error: %d, " ++ "errno: %d]\n", be_req2str(state->account_req->entry_type), ++ dp_error, ret); ++ goto done; ++ } ++ ++ ret = ipa_refresh_step(req); ++ if (ret == EAGAIN) { ++ return; ++ } ++ ++done: ++ if (ret != EOK) { ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ tevent_req_done(req); ++} ++ ++static errno_t ipa_refresh_recv(struct tevent_req *req) ++{ ++ TEVENT_REQ_RETURN_ON_ERROR(req); ++ ++ return EOK; ++} ++ ++static struct tevent_req * ++ipa_refresh_users_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return ipa_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_USER, names, pvt); ++} ++ ++static errno_t ipa_refresh_users_recv(struct tevent_req *req) ++{ ++ return ipa_refresh_recv(req); ++} ++ ++static struct tevent_req * ++ipa_refresh_groups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return ipa_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_GROUP, names, pvt); ++} ++ ++static errno_t ipa_refresh_groups_recv(struct tevent_req *req) ++{ ++ return ipa_refresh_recv(req); ++} ++ ++static struct tevent_req * ++ipa_refresh_netgroups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return ipa_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_NETGROUP, names, pvt); ++} ++ ++static errno_t ipa_refresh_netgroups_recv(struct tevent_req *req) ++{ ++ return ipa_refresh_recv(req); ++} ++ ++errno_t ipa_refresh_init(struct be_ctx *be_ctx, ++ struct ipa_id_ctx *id_ctx) ++{ ++ errno_t ret; ++ ++ ret = be_refresh_ctx_init(be_ctx, SYSDB_NAME); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n"); ++ return ENOMEM; ++ } ++ ++ ret = be_refresh_add_cb(be_ctx->refresh_ctx, ++ BE_REFRESH_TYPE_USERS, ++ ipa_refresh_users_send, ++ ipa_refresh_users_recv, ++ id_ctx); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ ++ ret = be_refresh_add_cb(be_ctx->refresh_ctx, ++ BE_REFRESH_TYPE_GROUPS, ++ ipa_refresh_groups_send, ++ ipa_refresh_groups_recv, ++ id_ctx); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of groups " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ ++ ret = be_refresh_add_cb(be_ctx->refresh_ctx, ++ BE_REFRESH_TYPE_NETGROUPS, ++ ipa_refresh_netgroups_send, ++ ipa_refresh_netgroups_recv, ++ id_ctx); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ ++ return ret; ++} +-- +2.20.1 + diff --git a/SOURCES/0039-pam_sss-make-flags-public.patch b/SOURCES/0039-pam_sss-make-flags-public.patch deleted file mode 100644 index b690e75..0000000 --- a/SOURCES/0039-pam_sss-make-flags-public.patch +++ /dev/null @@ -1,245 +0,0 @@ -From b01e1a5e2c27d6c642c72e79a326d37803827a78 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 18 Sep 2018 10:11:02 +0200 -Subject: [PATCH 39/47] pam_sss: make flags public - -To allow the PAM responder to act on the config flags set for pam_sss -the flags have to be made public first. - -Related to https://pagure.io/SSSD/sssd/issue/3650 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit d33a8bed5aad9135426c9ebdf101cf600685ab81) ---- - src/sss_client/pam_sss.c | 71 +++++++++++++++++++++--------------------------- - src/sss_client/sss_cli.h | 9 ++++++ - 2 files changed, 40 insertions(+), 40 deletions(-) - -diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c -index 59081cc675e5f466de42872ea9ce539c6df7ff79..b336d1f6197b09c062dd4ece836e088e52fe7393 100644 ---- a/src/sss_client/pam_sss.c -+++ b/src/sss_client/pam_sss.c -@@ -52,15 +52,6 @@ - #include - #define _(STRING) dgettext (PACKAGE, STRING) - --#define FLAGS_USE_FIRST_PASS (1 << 0) --#define FLAGS_FORWARD_PASS (1 << 1) --#define FLAGS_USE_AUTHTOK (1 << 2) --#define FLAGS_IGNORE_UNKNOWN_USER (1 << 3) --#define FLAGS_IGNORE_AUTHINFO_UNAVAIL (1 << 4) --#define FLAGS_USE_2FA (1 << 5) --#define FLAGS_ALLOW_MISSING_NAME (1 << 6) --#define FLAGS_PROMPT_ALWAYS (1 << 7) -- - #define PWEXP_FLAG "pam_sss:password_expired_flag" - #define FD_DESTRUCTOR "pam_sss:fd_destructor" - #define PAM_SSS_AUTHOK_TYPE "pam_sss:authtok_type" -@@ -1193,13 +1184,13 @@ static int get_pam_items(pam_handle_t *pamh, uint32_t flags, - pi->pam_service_size=strlen(pi->pam_service)+1; - - ret = pam_get_item(pamh, PAM_USER, (const void **) &(pi->pam_user)); -- if (ret == PAM_PERM_DENIED && (flags & FLAGS_ALLOW_MISSING_NAME)) { -+ if (ret == PAM_PERM_DENIED && (flags & PAM_CLI_FLAGS_ALLOW_MISSING_NAME)) { - pi->pam_user = ""; - ret = PAM_SUCCESS; - } - if (ret != PAM_SUCCESS) return ret; - if (pi->pam_user == NULL) { -- if (flags & FLAGS_ALLOW_MISSING_NAME) { -+ if (flags & PAM_CLI_FLAGS_ALLOW_MISSING_NAME) { - pi->pam_user = ""; - } else { - D(("No user found, aborting.")); -@@ -1959,11 +1950,11 @@ static void eval_argv(pam_handle_t *pamh, int argc, const char **argv, - - for (; argc-- > 0; ++argv) { - if (strcmp(*argv, "forward_pass") == 0) { -- *flags |= FLAGS_FORWARD_PASS; -+ *flags |= PAM_CLI_FLAGS_FORWARD_PASS; - } else if (strcmp(*argv, "use_first_pass") == 0) { -- *flags |= FLAGS_USE_FIRST_PASS; -+ *flags |= PAM_CLI_FLAGS_USE_FIRST_PASS; - } else if (strcmp(*argv, "use_authtok") == 0) { -- *flags |= FLAGS_USE_AUTHTOK; -+ *flags |= PAM_CLI_FLAGS_USE_AUTHTOK; - } else if (strncmp(*argv, OPT_DOMAINS_KEY, strlen(OPT_DOMAINS_KEY)) == 0) { - if (*(*argv+strlen(OPT_DOMAINS_KEY)) == '\0') { - logger(pamh, LOG_ERR, "Missing argument to option domains."); -@@ -1997,15 +1988,15 @@ static void eval_argv(pam_handle_t *pamh, int argc, const char **argv, - } else if (strcmp(*argv, "quiet") == 0) { - *quiet_mode = true; - } else if (strcmp(*argv, "ignore_unknown_user") == 0) { -- *flags |= FLAGS_IGNORE_UNKNOWN_USER; -+ *flags |= PAM_CLI_FLAGS_IGNORE_UNKNOWN_USER; - } else if (strcmp(*argv, "ignore_authinfo_unavail") == 0) { -- *flags |= FLAGS_IGNORE_AUTHINFO_UNAVAIL; -+ *flags |= PAM_CLI_FLAGS_IGNORE_AUTHINFO_UNAVAIL; - } else if (strcmp(*argv, "use_2fa") == 0) { -- *flags |= FLAGS_USE_2FA; -+ *flags |= PAM_CLI_FLAGS_USE_2FA; - } else if (strcmp(*argv, "allow_missing_name") == 0) { -- *flags |= FLAGS_ALLOW_MISSING_NAME; -+ *flags |= PAM_CLI_FLAGS_ALLOW_MISSING_NAME; - } else if (strcmp(*argv, "prompt_always") == 0) { -- *flags |= FLAGS_PROMPT_ALWAYS; -+ *flags |= PAM_CLI_FLAGS_PROMPT_ALWAYS; - } else { - logger(pamh, LOG_WARNING, "unknown option: %s", *argv); - } -@@ -2020,10 +2011,10 @@ static int get_authtok_for_authentication(pam_handle_t *pamh, - { - int ret; - -- if ((flags & FLAGS_USE_FIRST_PASS) -+ if ((flags & PAM_CLI_FLAGS_USE_FIRST_PASS) - || ( pi->pamstack_authtok != NULL - && *(pi->pamstack_authtok) != '\0' -- && !(flags & FLAGS_PROMPT_ALWAYS))) { -+ && !(flags & PAM_CLI_FLAGS_PROMPT_ALWAYS))) { - pi->pam_authtok_type = SSS_AUTHTOK_TYPE_PASSWORD; - pi->pam_authtok = strdup(pi->pamstack_authtok); - if (pi->pam_authtok == NULL) { -@@ -2032,7 +2023,7 @@ static int get_authtok_for_authentication(pam_handle_t *pamh, - } - pi->pam_authtok_size = strlen(pi->pam_authtok); - } else { -- if (flags & FLAGS_USE_2FA -+ if (flags & PAM_CLI_FLAGS_USE_2FA - || (pi->otp_vendor != NULL && pi->otp_token_id != NULL - && pi->otp_challenge != NULL)) { - if (pi->password_prompting) { -@@ -2062,7 +2053,7 @@ static int get_authtok_for_authentication(pam_handle_t *pamh, - return ret; - } - -- if (flags & FLAGS_FORWARD_PASS) { -+ if (flags & PAM_CLI_FLAGS_FORWARD_PASS) { - if (pi->pam_authtok_type == SSS_AUTHTOK_TYPE_PASSWORD) { - ret = pam_set_item(pamh, PAM_AUTHTOK, pi->pam_authtok); - } else if (pi->pam_authtok_type == SSS_AUTHTOK_TYPE_2FA -@@ -2193,8 +2184,8 @@ static int get_authtok_for_password_change(pam_handle_t *pamh, - /* we query for the old password during PAM_PRELIM_CHECK to make - * pam_sss work e.g. with pam_cracklib */ - if (pam_flags & PAM_PRELIM_CHECK) { -- if ( (getuid() != 0 || exp_data ) && !(flags & FLAGS_USE_FIRST_PASS)) { -- if (flags & FLAGS_USE_2FA -+ if ( (getuid() != 0 || exp_data ) && !(flags & PAM_CLI_FLAGS_USE_FIRST_PASS)) { -+ if (flags & PAM_CLI_FLAGS_USE_2FA - || (pi->otp_vendor != NULL && pi->otp_token_id != NULL - && pi->otp_challenge != NULL)) { - if (pi->password_prompting) { -@@ -2253,7 +2244,7 @@ static int get_authtok_for_password_change(pam_handle_t *pamh, - } - } - -- if (flags & FLAGS_USE_AUTHTOK) { -+ if (flags & PAM_CLI_FLAGS_USE_AUTHTOK) { - pi->pam_newauthtok_type = SSS_AUTHTOK_TYPE_PASSWORD; - pi->pam_newauthtok = strdup(pi->pamstack_authtok); - if (pi->pam_newauthtok == NULL) { -@@ -2268,7 +2259,7 @@ static int get_authtok_for_password_change(pam_handle_t *pamh, - return ret; - } - -- if (flags & FLAGS_FORWARD_PASS) { -+ if (flags & PAM_CLI_FLAGS_FORWARD_PASS) { - ret = pam_set_item(pamh, PAM_AUTHTOK, pi->pam_newauthtok); - if (ret != PAM_SUCCESS) { - D(("Failed to set PAM_AUTHTOK [%s], " -@@ -2376,10 +2367,10 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, - ret = get_pam_items(pamh, flags, &pi); - if (ret != PAM_SUCCESS) { - D(("get items returned error: %s", pam_strerror(pamh,ret))); -- if (flags & FLAGS_IGNORE_UNKNOWN_USER && ret == PAM_USER_UNKNOWN) { -+ if (flags & PAM_CLI_FLAGS_IGNORE_UNKNOWN_USER && ret == PAM_USER_UNKNOWN) { - ret = PAM_IGNORE; - } -- if (flags & FLAGS_IGNORE_AUTHINFO_UNAVAIL -+ if (flags & PAM_CLI_FLAGS_IGNORE_AUTHINFO_UNAVAIL - && ret == PAM_AUTHINFO_UNAVAIL) { - ret = PAM_IGNORE; - } -@@ -2393,13 +2384,13 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, - case SSS_PAM_AUTHENTICATE: - /* - * Only do preauth if -- * - FLAGS_USE_FIRST_PASS is not set -- * - no password is on the stack or FLAGS_PROMPT_ALWAYS is set -+ * - PAM_CLI_FLAGS_USE_FIRST_PASS is not set -+ * - no password is on the stack or PAM_CLI_FLAGS_PROMPT_ALWAYS is set - * - preauth indicator file exists. - */ -- if ( !(flags & FLAGS_USE_FIRST_PASS) -+ if ( !(flags & PAM_CLI_FLAGS_USE_FIRST_PASS) - && (pi.pam_authtok == NULL -- || (flags & FLAGS_PROMPT_ALWAYS)) -+ || (flags & PAM_CLI_FLAGS_PROMPT_ALWAYS)) - && access(PAM_PREAUTH_INDICATOR, F_OK) == 0) { - pam_status = send_and_receive(pamh, &pi, SSS_PAM_PREAUTH, - quiet_mode); -@@ -2443,14 +2434,14 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, - * The means the preauth step has to be done here as well but - * only if - * - PAM_PRELIM_CHECK is set -- * - FLAGS_USE_FIRST_PASS is not set -- * - no password is on the stack or FLAGS_PROMPT_ALWAYS is set -+ * - PAM_CLI_FLAGS_USE_FIRST_PASS is not set -+ * - no password is on the stack or PAM_CLI_FLAGS_PROMPT_ALWAYS is set - * - preauth indicator file exists. - */ - if ( (pam_flags & PAM_PRELIM_CHECK) -- && !(flags & FLAGS_USE_FIRST_PASS) -+ && !(flags & PAM_CLI_FLAGS_USE_FIRST_PASS) - && (pi.pam_authtok == NULL -- || (flags & FLAGS_PROMPT_ALWAYS)) -+ || (flags & PAM_CLI_FLAGS_PROMPT_ALWAYS)) - && access(PAM_PREAUTH_INDICATOR, F_OK) == 0) { - pam_status = send_and_receive(pamh, &pi, SSS_PAM_PREAUTH, - quiet_mode); -@@ -2497,11 +2488,11 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, - - pam_status = send_and_receive(pamh, &pi, task, quiet_mode); - -- if (flags & FLAGS_IGNORE_UNKNOWN_USER -+ if (flags & PAM_CLI_FLAGS_IGNORE_UNKNOWN_USER - && pam_status == PAM_USER_UNKNOWN) { - pam_status = PAM_IGNORE; - } -- if (flags & FLAGS_IGNORE_AUTHINFO_UNAVAIL -+ if (flags & PAM_CLI_FLAGS_IGNORE_AUTHINFO_UNAVAIL - && pam_status == PAM_AUTHINFO_UNAVAIL) { - pam_status = PAM_IGNORE; - } -@@ -2581,7 +2572,7 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, - retry = true; - retries--; - -- flags &= ~FLAGS_USE_FIRST_PASS; -+ flags &= ~PAM_CLI_FLAGS_USE_FIRST_PASS; - ret = pam_set_item(pamh, PAM_AUTHTOK, NULL); - if (ret != PAM_SUCCESS) { - D(("Failed to unset PAM_AUTHTOK [%s]", -diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h -index 24d28ed4b0acdd627067250970d91a0cb5cb05a0..3404715d811332e9013f3f88cb733c62147fb502 100644 ---- a/src/sss_client/sss_cli.h -+++ b/src/sss_client/sss_cli.h -@@ -365,6 +365,15 @@ enum pam_item_type { - SSS_PAM_ITEM_REQUESTED_DOMAINS, - }; - -+#define PAM_CLI_FLAGS_USE_FIRST_PASS (1 << 0) -+#define PAM_CLI_FLAGS_FORWARD_PASS (1 << 1) -+#define PAM_CLI_FLAGS_USE_AUTHTOK (1 << 2) -+#define PAM_CLI_FLAGS_IGNORE_UNKNOWN_USER (1 << 3) -+#define PAM_CLI_FLAGS_IGNORE_AUTHINFO_UNAVAIL (1 << 4) -+#define PAM_CLI_FLAGS_USE_2FA (1 << 5) -+#define PAM_CLI_FLAGS_ALLOW_MISSING_NAME (1 << 6) -+#define PAM_CLI_FLAGS_PROMPT_ALWAYS (1 << 7) -+ - #define SSS_NSS_MAX_ENTRIES 256 - #define SSS_NSS_HEADER_SIZE (sizeof(uint32_t) * 4) - struct sss_cli_req_data { --- -2.14.4 - diff --git a/SOURCES/0040-BE-IPA-AD-LDAP-Add-inigroups-refresh-support.patch b/SOURCES/0040-BE-IPA-AD-LDAP-Add-inigroups-refresh-support.patch new file mode 100644 index 0000000..7001f09 --- /dev/null +++ b/SOURCES/0040-BE-IPA-AD-LDAP-Add-inigroups-refresh-support.patch @@ -0,0 +1,291 @@ +From 141738f80a615ed57c7b49dc619a899b617dd62a Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 25 Jun 2019 14:16:31 +0200 +Subject: [PATCH 40/48] BE/IPA/AD/LDAP: Add inigroups refresh support + +Related: https://pagure.io/SSSD/sssd/issue/4012 + +In addition to refreshing users, groups and netgroups, this patch adds +the ability to also refresh initgroups. The refresh is ran for any users +that have the initgrExpireTimestamp attribute close to expiration. + +This request is ran as the first one, because the initgroups operation +refreshes the user entry and can touch groups as well. + +Reviewed-by: Sumit Bose +--- + src/providers/ad/ad_refresh.c | 28 +++++++++++++++++++++++ + src/providers/be_refresh.c | 37 +++++++++++++++++++++++-------- + src/providers/be_refresh.h | 1 + + src/providers/ipa/ipa_refresh.c | 27 ++++++++++++++++++++++ + src/providers/ldap/sdap_refresh.c | 17 ++++++++++++++ + 5 files changed, 101 insertions(+), 9 deletions(-) + +diff --git a/src/providers/ad/ad_refresh.c b/src/providers/ad/ad_refresh.c +index ee541056f..f0130cbaf 100644 +--- a/src/providers/ad/ad_refresh.c ++++ b/src/providers/ad/ad_refresh.c +@@ -65,6 +65,7 @@ static struct tevent_req *ad_refresh_send(TALLOC_CTX *mem_ctx, + state->index = 0; + + switch (entry_type) { ++ case BE_REQ_INITGROUPS: + case BE_REQ_NETGROUP: + filter_type = BE_FILTER_NAME; + break; +@@ -187,6 +188,23 @@ static errno_t ad_refresh_recv(struct tevent_req *req) + return EOK; + } + ++static struct tevent_req * ++ad_refresh_initgroups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return ad_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_INITGROUPS, names, pvt); ++} ++ ++static errno_t ad_refresh_initgroups_recv(struct tevent_req *req) ++{ ++ return ad_refresh_recv(req); ++} ++ + static struct tevent_req * + ad_refresh_users_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, +@@ -249,6 +267,16 @@ errno_t ad_refresh_init(struct be_ctx *be_ctx, + return ret; + } + ++ ret = be_refresh_add_cb(be_ctx->refresh_ctx, ++ BE_REFRESH_TYPE_INITGROUPS, ++ ad_refresh_initgroups_send, ++ ad_refresh_initgroups_recv, ++ id_ctx); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ + ret = be_refresh_add_cb(be_ctx->refresh_ctx, + BE_REFRESH_TYPE_USERS, + ad_refresh_users_send, +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index a9d4295ec..6945ca9e3 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -33,11 +33,12 @@ static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + time_t period, + struct ldb_dn *base_dn, +- const char *attr, ++ const char *key_attr, ++ const char *value_attr, + char ***_values) + { + TALLOC_CTX *tmp_ctx = NULL; +- const char *attrs[] = {attr, NULL}; ++ const char *attrs[] = {value_attr, NULL}; + const char *filter = NULL; + char **values = NULL; + struct sysdb_attrs **records = NULL; +@@ -45,13 +46,17 @@ static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx, + time_t now = time(NULL); + errno_t ret; + ++ if (key_attr == NULL || domain == NULL || base_dn == NULL) { ++ return EINVAL; ++ } ++ + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + filter = talloc_asprintf(tmp_ctx, "(&(%s<=%lld))", +- SYSDB_CACHE_EXPIRE, (long long) now + period); ++ key_attr, (long long) now + period); + if (filter == NULL) { + ret = ENOMEM; + goto done; +@@ -73,7 +78,7 @@ static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx, + goto done; + } + +- ret = sysdb_attrs_to_list(tmp_ctx, records, res->count, attr, &values); ++ ret = sysdb_attrs_to_list(tmp_ctx, records, res->count, value_attr, &values); + if (ret != EOK) { + goto done; + } +@@ -96,18 +101,27 @@ static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx, + { + struct ldb_dn *base_dn = NULL; + errno_t ret; ++ const char *key_attr; + + switch (type) { ++ case BE_REFRESH_TYPE_INITGROUPS: ++ key_attr = SYSDB_INITGR_EXPIRE; ++ base_dn = sysdb_user_base_dn(mem_ctx, domain); ++ break; + case BE_REFRESH_TYPE_USERS: ++ key_attr = SYSDB_CACHE_EXPIRE; + base_dn = sysdb_user_base_dn(mem_ctx, domain); + break; + case BE_REFRESH_TYPE_GROUPS: ++ key_attr = SYSDB_CACHE_EXPIRE; + base_dn = sysdb_group_base_dn(mem_ctx, domain); + break; + case BE_REFRESH_TYPE_NETGROUPS: ++ key_attr = SYSDB_CACHE_EXPIRE; + base_dn = sysdb_netgroup_base_dn(mem_ctx, domain); + break; +- case BE_REFRESH_TYPE_SENTINEL: ++ default: ++ DEBUG(SSSDBG_CRIT_FAILURE, "Uknown or unsupported refresh type\n"); + return ERR_INTERNAL; + break; + } +@@ -117,7 +131,8 @@ static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx, + } + + ret = be_refresh_get_values_ex(mem_ctx, domain, period, +- base_dn, attr_name, _values); ++ base_dn, key_attr, ++ attr_name, _values); + + talloc_free(base_dn); + return ret; +@@ -125,6 +140,7 @@ static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx, + + struct be_refresh_cb { + const char *name; ++ const char *attr_name; + bool enabled; + be_refresh_send_t send_fn; + be_refresh_recv_t recv_fn; +@@ -132,7 +148,6 @@ struct be_refresh_cb { + }; + + struct be_refresh_ctx { +- const char *attr_name; + struct be_refresh_cb callbacks[BE_REFRESH_TYPE_SENTINEL]; + }; + +@@ -148,10 +163,14 @@ errno_t be_refresh_ctx_init(struct be_ctx *be_ctx, + return ENOMEM; + } + +- ctx->attr_name = attr_name; ++ ctx->callbacks[BE_REFRESH_TYPE_INITGROUPS].name = "initgroups"; ++ ctx->callbacks[BE_REFRESH_TYPE_INITGROUPS].attr_name = SYSDB_NAME; + ctx->callbacks[BE_REFRESH_TYPE_USERS].name = "users"; ++ ctx->callbacks[BE_REFRESH_TYPE_USERS].attr_name = attr_name; + ctx->callbacks[BE_REFRESH_TYPE_GROUPS].name = "groups"; ++ ctx->callbacks[BE_REFRESH_TYPE_GROUPS].attr_name = attr_name; + ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].name = "netgroups"; ++ ctx->callbacks[BE_REFRESH_TYPE_NETGROUPS].attr_name = SYSDB_NAME; + + refresh_interval = be_ctx->domain->refresh_expired_interval; + if (refresh_interval > 0) { +@@ -310,7 +329,7 @@ static errno_t be_refresh_step(struct tevent_req *req) + } + + talloc_zfree(state->refresh_values); +- ret = be_refresh_get_values(state, state->index, state->ctx->attr_name, ++ ret = be_refresh_get_values(state, state->index, state->cb->attr_name, + state->domain, state->period, + &state->refresh_values); + if (ret != EOK) { +diff --git a/src/providers/be_refresh.h b/src/providers/be_refresh.h +index c7b4872df..4ac5b70c2 100644 +--- a/src/providers/be_refresh.h ++++ b/src/providers/be_refresh.h +@@ -44,6 +44,7 @@ typedef errno_t + (*be_refresh_recv_t)(struct tevent_req *req); + + enum be_refresh_type { ++ BE_REFRESH_TYPE_INITGROUPS, + BE_REFRESH_TYPE_USERS, + BE_REFRESH_TYPE_GROUPS, + BE_REFRESH_TYPE_NETGROUPS, +diff --git a/src/providers/ipa/ipa_refresh.c b/src/providers/ipa/ipa_refresh.c +index 72051cfdd..bb47b0edf 100644 +--- a/src/providers/ipa/ipa_refresh.c ++++ b/src/providers/ipa/ipa_refresh.c +@@ -168,6 +168,23 @@ static errno_t ipa_refresh_recv(struct tevent_req *req) + return EOK; + } + ++static struct tevent_req * ++ipa_refresh_initgroups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return ipa_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_INITGROUPS, names, pvt); ++} ++ ++static errno_t ipa_refresh_initgroups_recv(struct tevent_req *req) ++{ ++ return ipa_refresh_recv(req); ++} ++ + static struct tevent_req * + ipa_refresh_users_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, +@@ -230,6 +247,16 @@ errno_t ipa_refresh_init(struct be_ctx *be_ctx, + return ENOMEM; + } + ++ ret = be_refresh_add_cb(be_ctx->refresh_ctx, ++ BE_REFRESH_TYPE_USERS, ++ ipa_refresh_initgroups_send, ++ ipa_refresh_initgroups_recv, ++ id_ctx); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of initgroups " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ + ret = be_refresh_add_cb(be_ctx->refresh_ctx, + BE_REFRESH_TYPE_USERS, + ipa_refresh_users_send, +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index 2206d6670..3ceddb61e 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -186,6 +186,23 @@ static errno_t sdap_refresh_recv(struct tevent_req *req) + return EOK; + } + ++static struct tevent_req * ++sdap_refresh_initgroups_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_ctx *be_ctx, ++ struct sss_domain_info *domain, ++ char **names, ++ void *pvt) ++{ ++ return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, ++ BE_REQ_INITGROUPS, names, pvt); ++} ++ ++static errno_t sdap_refresh_initgroups_recv(struct tevent_req *req) ++{ ++ return sdap_refresh_recv(req); ++} ++ + static struct tevent_req * + sdap_refresh_users_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, +-- +2.20.1 + diff --git a/SOURCES/0040-pam_sss-add-try_cert_auth-option.patch b/SOURCES/0040-pam_sss-add-try_cert_auth-option.patch deleted file mode 100644 index 89129f6..0000000 --- a/SOURCES/0040-pam_sss-add-try_cert_auth-option.patch +++ /dev/null @@ -1,101 +0,0 @@ -From caf7ff9935ce26fa3aba404d9003b8fbcfeb391b Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 17 Sep 2018 17:54:26 +0200 -Subject: [PATCH 40/47] pam_sss: add try_cert_auth option - -With this new option pam_sss can be configured to only do Smartcard -authentication or return an error if this is not possible. - -Related to https://pagure.io/SSSD/sssd/issue/3650 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit d3a18f06162b9585d2db936472b75fdbff37162d) ---- - src/man/pam_sss.8.xml | 23 +++++++++++++++++++++++ - src/sss_client/pam_sss.c | 9 +++++++++ - src/sss_client/sss_cli.h | 1 + - 3 files changed, 33 insertions(+) - -diff --git a/src/man/pam_sss.8.xml b/src/man/pam_sss.8.xml -index d8e6a2041a17814b0ad506170645a5983cc05704..ca2e8e20678d102525a9252678dd83459c3338ac 100644 ---- a/src/man/pam_sss.8.xml -+++ b/src/man/pam_sss.8.xml -@@ -50,6 +50,9 @@ - - prompt_always - -+ -+ try_cert_auth -+ - - - -@@ -200,6 +203,26 @@ auth sufficient pam_sss.so allow_missing_name - - - -+ -+ -+ -+ -+ -+ -+ Try to use certificate based authentication, i.e. -+ authentication with a Smartcard or similar devices. If a -+ Smartcard is available and the service is allowed for -+ Smartcard authentication the use will be prompted for a -+ PIN and the certificate based authentication will -+ continue -+ -+ -+ If no Smartcard is available or certificate based -+ authentication is not allowed for the current service -+ PAM_AUTHINFO_UNAVAIL is returned. -+ -+ -+ - - - -diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c -index b336d1f6197b09c062dd4ece836e088e52fe7393..96ff15adad867aceae17431cd5256ae52e4b9306 100644 ---- a/src/sss_client/pam_sss.c -+++ b/src/sss_client/pam_sss.c -@@ -1997,6 +1997,8 @@ static void eval_argv(pam_handle_t *pamh, int argc, const char **argv, - *flags |= PAM_CLI_FLAGS_ALLOW_MISSING_NAME; - } else if (strcmp(*argv, "prompt_always") == 0) { - *flags |= PAM_CLI_FLAGS_PROMPT_ALWAYS; -+ } else if (strcmp(*argv, "try_cert_auth") == 0) { -+ *flags |= PAM_CLI_FLAGS_TRY_CERT_AUTH; - } else { - logger(pamh, LOG_WARNING, "unknown option: %s", *argv); - } -@@ -2405,6 +2407,13 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, - } - } - -+ if (flags & PAM_CLI_FLAGS_TRY_CERT_AUTH -+ && pi.cert_list == NULL) { -+ D(("No certificates for authentication available.")); -+ overwrite_and_free_pam_items(&pi); -+ return PAM_AUTHINFO_UNAVAIL; -+ } -+ - if (strcmp(pi.pam_service, "gdm-smartcard") == 0) { - ret = check_login_token_name(pamh, &pi, quiet_mode); - if (ret != PAM_SUCCESS) { -diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h -index 3404715d811332e9013f3f88cb733c62147fb502..38e3f999d799556a56ac08f0f3a6b538b8cde9f3 100644 ---- a/src/sss_client/sss_cli.h -+++ b/src/sss_client/sss_cli.h -@@ -373,6 +373,7 @@ enum pam_item_type { - #define PAM_CLI_FLAGS_USE_2FA (1 << 5) - #define PAM_CLI_FLAGS_ALLOW_MISSING_NAME (1 << 6) - #define PAM_CLI_FLAGS_PROMPT_ALWAYS (1 << 7) -+#define PAM_CLI_FLAGS_TRY_CERT_AUTH (1 << 8) - - #define SSS_NSS_MAX_ENTRIES 256 - #define SSS_NSS_HEADER_SIZE (sizeof(uint32_t) * 4) --- -2.14.4 - diff --git a/SOURCES/0041-BE-IPA-AD-LDAP-Initialize-the-refresh-callback-from-.patch b/SOURCES/0041-BE-IPA-AD-LDAP-Initialize-the-refresh-callback-from-.patch new file mode 100644 index 0000000..7bb9535 --- /dev/null +++ b/SOURCES/0041-BE-IPA-AD-LDAP-Initialize-the-refresh-callback-from-.patch @@ -0,0 +1,495 @@ +From 330507ab3146e877391ff85d4bf6be9ce069e2bd Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 25 Jun 2019 15:05:59 +0200 +Subject: [PATCH 41/48] BE/IPA/AD/LDAP: Initialize the refresh callback from a + list to reduce logic duplication + +Related: https://pagure.io/SSSD/sssd/issue/4012 + +This patch slightly increases the line count, but on the other hand the +code is now more declarative and contains less logic, which should +hopefully decrease the maintenance cost in the future. + +Reviewed-by: Sumit Bose +--- + src/providers/ad/ad_refresh.c | 66 ++++++---------- + src/providers/be_refresh.c | 126 +++++++++++++++++++++++------- + src/providers/be_refresh.h | 17 ++-- + src/providers/ipa/ipa_refresh.c | 70 ++++++----------- + src/providers/ldap/sdap_refresh.c | 58 ++++++-------- + 5 files changed, 179 insertions(+), 158 deletions(-) + +diff --git a/src/providers/ad/ad_refresh.c b/src/providers/ad/ad_refresh.c +index f0130cbaf..ed51b305a 100644 +--- a/src/providers/ad/ad_refresh.c ++++ b/src/providers/ad/ad_refresh.c +@@ -260,52 +260,32 @@ errno_t ad_refresh_init(struct be_ctx *be_ctx, + struct ad_id_ctx *id_ctx) + { + errno_t ret; +- +- ret = be_refresh_ctx_init(be_ctx, SYSDB_SID_STR); ++ struct be_refresh_cb ad_refresh_callbacks[] = { ++ { .send_fn = ad_refresh_initgroups_send, ++ .recv_fn = ad_refresh_initgroups_recv, ++ .pvt = id_ctx, ++ }, ++ { .send_fn = ad_refresh_users_send, ++ .recv_fn = ad_refresh_users_recv, ++ .pvt = id_ctx, ++ }, ++ { .send_fn = ad_refresh_groups_send, ++ .recv_fn = ad_refresh_groups_recv, ++ .pvt = id_ctx, ++ }, ++ { .send_fn = ad_refresh_netgroups_send, ++ .recv_fn = ad_refresh_netgroups_recv, ++ .pvt = id_ctx, ++ }, ++ }; ++ ++ ret = be_refresh_ctx_init_with_callbacks(be_ctx, ++ SYSDB_SID_STR, ++ ad_refresh_callbacks); + if (ret != EOK) { +- DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n"); ++ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize background refresh\n"); + return ret; + } + +- ret = be_refresh_add_cb(be_ctx->refresh_ctx, +- BE_REFRESH_TYPE_INITGROUPS, +- ad_refresh_initgroups_send, +- ad_refresh_initgroups_recv, +- id_ctx); +- if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users " +- "will not work [%d]: %s\n", ret, strerror(ret)); +- } +- +- ret = be_refresh_add_cb(be_ctx->refresh_ctx, +- BE_REFRESH_TYPE_USERS, +- ad_refresh_users_send, +- ad_refresh_users_recv, +- id_ctx); +- if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users " +- "will not work [%d]: %s\n", ret, strerror(ret)); +- } +- +- ret = be_refresh_add_cb(be_ctx->refresh_ctx, +- BE_REFRESH_TYPE_GROUPS, +- ad_refresh_groups_send, +- ad_refresh_groups_recv, +- id_ctx); +- if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of groups " +- "will not work [%d]: %s\n", ret, strerror(ret)); +- } +- +- ret = be_refresh_add_cb(be_ctx->refresh_ctx, +- BE_REFRESH_TYPE_NETGROUPS, +- ad_refresh_netgroups_send, +- ad_refresh_netgroups_recv, +- id_ctx); +- if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups " +- "will not work [%d]: %s\n", ret, strerror(ret)); +- } +- + return ret; + } +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index 6945ca9e3..8f50e231d 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -138,21 +138,19 @@ static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx, + return ret; + } + +-struct be_refresh_cb { ++struct be_refresh_cb_ctx { + const char *name; + const char *attr_name; + bool enabled; +- be_refresh_send_t send_fn; +- be_refresh_recv_t recv_fn; +- void *pvt; ++ struct be_refresh_cb cb; + }; + + struct be_refresh_ctx { +- struct be_refresh_cb callbacks[BE_REFRESH_TYPE_SENTINEL]; ++ struct be_refresh_cb_ctx callbacks[BE_REFRESH_TYPE_SENTINEL]; + }; + +-errno_t be_refresh_ctx_init(struct be_ctx *be_ctx, +- const char *attr_name) ++static errno_t be_refresh_ctx_init(struct be_ctx *be_ctx, ++ const char *attr_name) + { + struct be_refresh_ctx *ctx = NULL; + uint32_t refresh_interval; +@@ -193,13 +191,11 @@ errno_t be_refresh_ctx_init(struct be_ctx *be_ctx, + return EOK; + } + +-errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, +- enum be_refresh_type type, +- be_refresh_send_t send_fn, +- be_refresh_recv_t recv_fn, +- void *pvt) ++static errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, ++ enum be_refresh_type type, ++ struct be_refresh_cb *cb) + { +- if (ctx == NULL || send_fn == NULL || recv_fn == NULL ++ if (ctx == NULL || cb->send_fn == NULL || cb->recv_fn == NULL + || type >= BE_REFRESH_TYPE_SENTINEL) { + return EINVAL; + } +@@ -209,9 +205,78 @@ errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, + } + + ctx->callbacks[type].enabled = true; +- ctx->callbacks[type].send_fn = send_fn; +- ctx->callbacks[type].recv_fn = recv_fn; +- ctx->callbacks[type].pvt = pvt; ++ ctx->callbacks[type].cb.send_fn = cb->send_fn; ++ ctx->callbacks[type].cb.recv_fn = cb->recv_fn; ++ ctx->callbacks[type].cb.pvt = cb->pvt; ++ ++ return EOK; ++} ++ ++static errno_t be_refresh_set_callbacks(struct be_refresh_ctx *refresh_ctx, ++ struct be_refresh_cb *callbacks) ++{ ++ errno_t ret; ++ ++ if (callbacks == NULL || refresh_ctx == NULL) { ++ return EINVAL; ++ } ++ ++ ret = be_refresh_add_cb(refresh_ctx, ++ BE_REFRESH_TYPE_INITGROUPS, ++ &callbacks[BE_REFRESH_TYPE_INITGROUPS]); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of initgroups " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ ++ ret = be_refresh_add_cb(refresh_ctx, ++ BE_REFRESH_TYPE_USERS, ++ &callbacks[BE_REFRESH_TYPE_USERS]); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ ++ ret = be_refresh_add_cb(refresh_ctx, ++ BE_REFRESH_TYPE_GROUPS, ++ &callbacks[BE_REFRESH_TYPE_GROUPS]); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of groups " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ ++ ret = be_refresh_add_cb(refresh_ctx, ++ BE_REFRESH_TYPE_NETGROUPS, ++ &callbacks[BE_REFRESH_TYPE_NETGROUPS]); ++ if (ret != EOK && ret != EEXIST) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups " ++ "will not work [%d]: %s\n", ret, strerror(ret)); ++ } ++ ++ return EOK; ++} ++ ++errno_t be_refresh_ctx_init_with_callbacks(struct be_ctx *be_ctx, ++ const char *attr_name, ++ struct be_refresh_cb *callbacks) ++{ ++ errno_t ret; ++ ++ if (be_ctx == NULL || attr_name == NULL || callbacks == NULL) { ++ return EINVAL; ++ } ++ ++ ret = be_refresh_ctx_init(be_ctx, attr_name); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n"); ++ return ret; ++ } ++ ++ ret = be_refresh_set_callbacks(be_ctx->refresh_ctx, callbacks); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh callbacks\n"); ++ return ENOMEM; ++ } + + return EOK; + } +@@ -220,7 +285,7 @@ struct be_refresh_state { + struct tevent_context *ev; + struct be_ctx *be_ctx; + struct be_refresh_ctx *ctx; +- struct be_refresh_cb *cb; ++ struct be_refresh_cb_ctx *cb_ctx; + + struct sss_domain_info *domain; + enum be_refresh_type index; +@@ -308,10 +373,11 @@ static errno_t be_refresh_step(struct tevent_req *req) + + while (state->domain != NULL) { + /* find first enabled callback */ +- state->cb = &state->ctx->callbacks[state->index]; +- while (state->index != BE_REFRESH_TYPE_SENTINEL && !state->cb->enabled) { ++ state->cb_ctx = &state->ctx->callbacks[state->index]; ++ while (state->index != BE_REFRESH_TYPE_SENTINEL ++ && !state->cb_ctx->enabled) { + state->index++; +- state->cb = &state->ctx->callbacks[state->index]; ++ state->cb_ctx = &state->ctx->callbacks[state->index]; + } + + /* if not found than continue with next domain */ +@@ -322,14 +388,16 @@ static errno_t be_refresh_step(struct tevent_req *req) + continue; + } + +- if (state->cb->send_fn == NULL || state->cb->recv_fn == NULL) { ++ if (state->cb_ctx->cb.send_fn == NULL ++ || state->cb_ctx->cb.recv_fn == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Invalid parameters!\n"); + ret = ERR_INTERNAL; + goto done; + } + + talloc_zfree(state->refresh_values); +- ret = be_refresh_get_values(state, state->index, state->cb->attr_name, ++ ret = be_refresh_get_values(state, state->index, ++ state->cb_ctx->attr_name, + state->domain, state->period, + &state->refresh_values); + if (ret != EOK) { +@@ -343,7 +411,9 @@ static errno_t be_refresh_step(struct tevent_req *req) + state->refresh_val_size++); + + DEBUG(SSSDBG_TRACE_FUNC, "Refreshing %zu %s in domain %s\n", +- state->refresh_val_size, state->cb->name, state->domain->name); ++ state->refresh_val_size, ++ state->cb_ctx->name, ++ state->domain->name); + + ret = be_refresh_batch_step(req, 0); + if (ret == EOK) { +@@ -416,10 +486,10 @@ static void be_refresh_batch_step_wakeup(struct tevent_context *ev, + state = tevent_req_data(req, struct be_refresh_state); + + DEBUG(SSSDBG_TRACE_INTERNAL, "Issuing refresh\n"); +- subreq = state->cb->send_fn(state, state->ev, state->be_ctx, +- state->domain, +- state->refresh_batch, +- state->cb->pvt); ++ subreq = state->cb_ctx->cb.send_fn(state, state->ev, state->be_ctx, ++ state->domain, ++ state->refresh_batch, ++ state->cb_ctx->cb.pvt); + if (subreq == NULL) { + tevent_req_error(req, ENOMEM); + return; +@@ -436,7 +506,7 @@ static void be_refresh_done(struct tevent_req *subreq) + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct be_refresh_state); + +- ret = state->cb->recv_fn(subreq); ++ ret = state->cb_ctx->cb.recv_fn(subreq); + talloc_zfree(subreq); + if (ret != EOK) { + goto done; +diff --git a/src/providers/be_refresh.h b/src/providers/be_refresh.h +index 4ac5b70c2..42d73d938 100644 +--- a/src/providers/be_refresh.h ++++ b/src/providers/be_refresh.h +@@ -51,16 +51,17 @@ enum be_refresh_type { + BE_REFRESH_TYPE_SENTINEL + }; + +-struct be_refresh_ctx; ++struct be_refresh_cb { ++ be_refresh_send_t send_fn; ++ be_refresh_recv_t recv_fn; ++ void *pvt; ++}; + +-errno_t be_refresh_ctx_init(struct be_ctx *be_ctx, +- const char *attr_name); ++struct be_refresh_ctx; + +-errno_t be_refresh_add_cb(struct be_refresh_ctx *ctx, +- enum be_refresh_type type, +- be_refresh_send_t send_fn, +- be_refresh_recv_t recv_fn, +- void *pvt); ++errno_t be_refresh_ctx_init_with_callbacks(struct be_ctx *be_ctx, ++ const char *attr_name, ++ struct be_refresh_cb *callbacks); + + struct tevent_req *be_refresh_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, +diff --git a/src/providers/ipa/ipa_refresh.c b/src/providers/ipa/ipa_refresh.c +index bb47b0edf..7b05cf9e4 100644 +--- a/src/providers/ipa/ipa_refresh.c ++++ b/src/providers/ipa/ipa_refresh.c +@@ -240,52 +240,32 @@ errno_t ipa_refresh_init(struct be_ctx *be_ctx, + struct ipa_id_ctx *id_ctx) + { + errno_t ret; +- +- ret = be_refresh_ctx_init(be_ctx, SYSDB_NAME); ++ struct be_refresh_cb ipa_refresh_callbacks[] = { ++ { .send_fn = ipa_refresh_initgroups_send, ++ .recv_fn = ipa_refresh_initgroups_recv, ++ .pvt = id_ctx, ++ }, ++ { .send_fn = ipa_refresh_users_send, ++ .recv_fn = ipa_refresh_users_recv, ++ .pvt = id_ctx, ++ }, ++ { .send_fn = ipa_refresh_groups_send, ++ .recv_fn = ipa_refresh_groups_recv, ++ .pvt = id_ctx, ++ }, ++ { .send_fn = ipa_refresh_netgroups_send, ++ .recv_fn = ipa_refresh_netgroups_recv, ++ .pvt = id_ctx, ++ }, ++ }; ++ ++ ret = be_refresh_ctx_init_with_callbacks(be_ctx, ++ SYSDB_NAME, ++ ipa_refresh_callbacks); + if (ret != EOK) { +- DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n"); +- return ENOMEM; +- } +- +- ret = be_refresh_add_cb(be_ctx->refresh_ctx, +- BE_REFRESH_TYPE_USERS, +- ipa_refresh_initgroups_send, +- ipa_refresh_initgroups_recv, +- id_ctx); +- if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of initgroups " +- "will not work [%d]: %s\n", ret, strerror(ret)); ++ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize background refresh\n"); ++ return ret; + } + +- ret = be_refresh_add_cb(be_ctx->refresh_ctx, +- BE_REFRESH_TYPE_USERS, +- ipa_refresh_users_send, +- ipa_refresh_users_recv, +- id_ctx); +- if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users " +- "will not work [%d]: %s\n", ret, strerror(ret)); +- } +- +- ret = be_refresh_add_cb(be_ctx->refresh_ctx, +- BE_REFRESH_TYPE_GROUPS, +- ipa_refresh_groups_send, +- ipa_refresh_groups_recv, +- id_ctx); +- if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of groups " +- "will not work [%d]: %s\n", ret, strerror(ret)); +- } +- +- ret = be_refresh_add_cb(be_ctx->refresh_ctx, +- BE_REFRESH_TYPE_NETGROUPS, +- ipa_refresh_netgroups_send, +- ipa_refresh_netgroups_recv, +- id_ctx); +- if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups " +- "will not work [%d]: %s\n", ret, strerror(ret)); +- } +- +- return ret; ++ return EOK; + } +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index 3ceddb61e..ff4d2116d 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -258,41 +258,31 @@ errno_t sdap_refresh_init(struct be_ctx *be_ctx, + struct sdap_id_ctx *id_ctx) + { + errno_t ret; +- +- ret = be_refresh_ctx_init(be_ctx, SYSDB_NAME); ++ struct be_refresh_cb sdap_refresh_callbacks[] = { ++ { .send_fn = sdap_refresh_initgroups_send, ++ .recv_fn = sdap_refresh_initgroups_recv, ++ .pvt = id_ctx, ++ }, ++ { .send_fn = sdap_refresh_users_send, ++ .recv_fn = sdap_refresh_users_recv, ++ .pvt = id_ctx, ++ }, ++ { .send_fn = sdap_refresh_groups_send, ++ .recv_fn = sdap_refresh_groups_recv, ++ .pvt = id_ctx, ++ }, ++ { .send_fn = sdap_refresh_netgroups_send, ++ .recv_fn = sdap_refresh_netgroups_recv, ++ .pvt = id_ctx, ++ }, ++ }; ++ ++ ret = be_refresh_ctx_init_with_callbacks(be_ctx, ++ SYSDB_NAME, ++ sdap_refresh_callbacks); + if (ret != EOK) { +- DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize refresh_ctx\n"); +- return ENOMEM; +- } +- +- ret = be_refresh_add_cb(be_ctx->refresh_ctx, +- BE_REFRESH_TYPE_USERS, +- sdap_refresh_users_send, +- sdap_refresh_users_recv, +- id_ctx); +- if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of users " +- "will not work [%d]: %s\n", ret, strerror(ret)); +- } +- +- ret = be_refresh_add_cb(be_ctx->refresh_ctx, +- BE_REFRESH_TYPE_USERS, +- sdap_refresh_groups_send, +- sdap_refresh_groups_recv, +- id_ctx); +- if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of groups " +- "will not work [%d]: %s\n", ret, strerror(ret)); +- } +- +- ret = be_refresh_add_cb(be_ctx->refresh_ctx, +- BE_REFRESH_TYPE_USERS, +- sdap_refresh_netgroups_send, +- sdap_refresh_netgroups_recv, +- id_ctx); +- if (ret != EOK && ret != EEXIST) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Periodical refresh of netgroups " +- "will not work [%d]: %s\n", ret, strerror(ret)); ++ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize background refresh\n"); ++ return ret; + } + + return ret; +-- +2.20.1 + diff --git a/SOURCES/0041-pam_sss-add-option-require_cert_auth.patch b/SOURCES/0041-pam_sss-add-option-require_cert_auth.patch deleted file mode 100644 index 7dc8826..0000000 --- a/SOURCES/0041-pam_sss-add-option-require_cert_auth.patch +++ /dev/null @@ -1,372 +0,0 @@ -From f724123e20f8d4a1c85473d917da6c65a10d6d62 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 18 Sep 2018 09:53:37 +0200 -Subject: [PATCH 41/47] pam_sss: add option require_cert_auth - -With this new option pam_sss will wait until a Smartcard is available -and then try to authenticate with the help of the Smartcard. - -Related https://pagure.io/SSSD/sssd/issue/3650 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 49be8974b490c368d349752f3196af0c9ed28dd5) ---- - src/man/pam_sss.8.xml | 25 ++++++++++++ - src/responder/pam/pamsrv_cmd.c | 12 ++++++ - src/responder/pam/pamsrv_p11.c | 5 ++- - src/sss_client/pam_message.c | 4 ++ - src/sss_client/pam_message.h | 1 + - src/sss_client/pam_sss.c | 92 ++++++++++++++++++++++++++---------------- - src/sss_client/sss_cli.h | 2 + - src/util/sss_pam_data.c | 1 + - src/util/sss_pam_data.h | 1 + - 9 files changed, 107 insertions(+), 36 deletions(-) - -diff --git a/src/man/pam_sss.8.xml b/src/man/pam_sss.8.xml -index ca2e8e20678d102525a9252678dd83459c3338ac..9998519f16c934e0d578760a57cc0908db760bfb 100644 ---- a/src/man/pam_sss.8.xml -+++ b/src/man/pam_sss.8.xml -@@ -53,6 +53,9 @@ - - try_cert_auth - -+ -+ require_cert_auth -+ - - - -@@ -223,6 +226,28 @@ auth sufficient pam_sss.so allow_missing_name - - - -+ -+ -+ -+ -+ -+ -+ Do certificate based authentication, i.e. -+ authentication with a Smartcard or similar devices. If a -+ Smartcard is not available the user will be prompted to -+ insert one. SSSD will wait for a Smartcard until the -+ timeout defined by p11_wait_for_card_timeout passed, -+ please see -+ sssd.conf -+ 5 for details. -+ -+ -+ If no Smartcard is available after the timeout or -+ certificate based authentication is not allowed for the -+ current service PAM_AUTHINFO_UNAVAIL is returned. -+ -+ -+ - - - -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index c8df32de9e72e9f5ce33e26f0a13101a99f01d5f..6e37f831602e4c367176cc14126dbbec72c858cd 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -317,6 +317,11 @@ static int pam_parse_in_data_v2(struct pam_data *pd, - size, body, blen, &c); - if (ret != EOK) return ret; - break; -+ case SSS_PAM_ITEM_FLAGS: -+ ret = extract_uint32_t(&pd->cli_flags, size, -+ body, blen, &c); -+ if (ret != EOK) return ret; -+ break; - default: - DEBUG(SSSDBG_CRIT_FAILURE, - "Ignoring unknown data type [%d].\n", type); -@@ -1447,6 +1452,13 @@ static void pam_forwarder_cert_cb(struct tevent_req *req) - "No certificate found and no logon name given, " \ - "authentication not possible.\n"); - ret = ENOENT; -+ } else if (pd->cli_flags & PAM_CLI_FLAGS_TRY_CERT_AUTH) { -+ DEBUG(SSSDBG_TRACE_ALL, -+ "try_cert_auth flag set but no certificate available, " -+ "request finished.\n"); -+ preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL; -+ pam_reply(preq); -+ return; - } else { - if (pd->cmd == SSS_PAM_AUTHENTICATE) { - DEBUG(SSSDBG_CRIT_FAILURE, -diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c -index ffa6787e967488ac408ce0f0a11b96066c29b630..8b8859d9d335aec6d310201256522fa8afdd3694 100644 ---- a/src/responder/pam/pamsrv_p11.c -+++ b/src/responder/pam/pamsrv_p11.c -@@ -721,7 +721,7 @@ 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[13] = { NULL }; -+ const char *extra_args[14] = { NULL }; - uint8_t *write_buf = NULL; - size_t write_buf_len = 0; - size_t arg_c; -@@ -748,6 +748,9 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - - /* extra_args are added in revers order */ - arg_c = 0; -+ if ((pd->cli_flags & PAM_CLI_FLAGS_REQUIRE_CERT_AUTH) && pd->priv == 1) { -+ extra_args[arg_c++] = "--wait_for_card"; -+ } - extra_args[arg_c++] = nss_db; - extra_args[arg_c++] = "--nssdb"; - if (verify_opts != NULL) { -diff --git a/src/sss_client/pam_message.c b/src/sss_client/pam_message.c -index b239f6f53da54054c52e484bdd076193709cb003..036ae2ad17742c123ba59e39a122ea605b7b95a6 100644 ---- a/src/sss_client/pam_message.c -+++ b/src/sss_client/pam_message.c -@@ -126,6 +126,7 @@ int pack_message_v3(struct pam_items *pi, size_t *size, uint8_t **buffer) - len += 3*sizeof(uint32_t); /* cli_pid */ - len += *pi->requested_domains != '\0' ? - 2*sizeof(uint32_t) + pi->requested_domains_size : 0; -+ len += 3*sizeof(uint32_t); /* flags */ - - buf = malloc(len); - if (buf == NULL) { -@@ -164,6 +165,9 @@ int pack_message_v3(struct pam_items *pi, size_t *size, uint8_t **buffer) - pi->pam_newauthtok, pi->pam_newauthtok_size, - &buf[rp]); - -+ rp += add_uint32_t_item(SSS_PAM_ITEM_FLAGS, (uint32_t) pi->flags, -+ &buf[rp]); -+ - SAFEALIGN_SETMEM_UINT32(buf + rp, SSS_END_OF_PAM_REQUEST, &rp); - - if (rp != len) { -diff --git a/src/sss_client/pam_message.h b/src/sss_client/pam_message.h -index 11526a80a767ff5602b194d14765ff261e8f9707..50fedcd82d8ace520d0360d85d163f91df0cb100 100644 ---- a/src/sss_client/pam_message.h -+++ b/src/sss_client/pam_message.h -@@ -51,6 +51,7 @@ struct pam_items { - enum sss_authtok_type pam_newauthtok_type; - size_t pam_newauthtok_size; - pid_t cli_pid; -+ uint32_t flags; - const char *login_name; - char *domain_name; - const char *requested_domains; -diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c -index 96ff15adad867aceae17431cd5256ae52e4b9306..b4c1036ad68a97821f5d0aee873fa18fe5e72683 100644 ---- a/src/sss_client/pam_sss.c -+++ b/src/sss_client/pam_sss.c -@@ -134,6 +134,7 @@ static void free_cai(struct cert_auth_info *cai) - free(cai->cert_user); - free(cai->cert); - free(cai->token_name); -+ free(cai->module_name); - free(cai->key_id); - free(cai->prompt_str); - free(cai); -@@ -1247,6 +1248,8 @@ static int get_pam_items(pam_handle_t *pamh, uint32_t flags, - pi->cert_list = NULL; - pi->selected_cert = NULL; - -+ pi->flags = flags; -+ - return PAM_SUCCESS; - } - -@@ -1267,6 +1270,7 @@ static void print_pam_items(struct pam_items *pi) - D(("Newauthtok: %s", CHECK_AND_RETURN_PI_STRING(pi->pam_newauthtok))); - D(("Cli_PID: %d", pi->cli_pid)); - D(("Requested domains: %s", pi->requested_domains)); -+ D(("Flags: %d", pi->flags)); - } - - static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi, -@@ -1999,6 +2003,8 @@ static void eval_argv(pam_handle_t *pamh, int argc, const char **argv, - *flags |= PAM_CLI_FLAGS_PROMPT_ALWAYS; - } else if (strcmp(*argv, "try_cert_auth") == 0) { - *flags |= PAM_CLI_FLAGS_TRY_CERT_AUTH; -+ } else if (strcmp(*argv, "require_cert_auth") == 0) { -+ *flags |= PAM_CLI_FLAGS_REQUIRE_CERT_AUTH; - } else { - logger(pamh, LOG_WARNING, "unknown option: %s", *argv); - } -@@ -2274,55 +2280,51 @@ static int get_authtok_for_password_change(pam_handle_t *pamh, - return PAM_SUCCESS; - } - --#define SC_ENTER_FMT "Please enter smart card labeled\n %s\nand press enter" -+#define SC_ENTER_LABEL_FMT "Please enter smart card labeled\n %s" -+#define SC_ENTER_FMT "Please enter smart card" - - static int check_login_token_name(pam_handle_t *pamh, struct pam_items *pi, -- bool quiet_mode) -+ int retries, bool quiet_mode) - { - int ret; - int pam_status; - char *login_token_name; - 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; -- } -+ uint32_t orig_flags = pi->flags; - - login_token_name = getenv("PKCS11_LOGIN_TOKEN_NAME"); -+ if (login_token_name == NULL -+ && !(pi->flags & PAM_CLI_FLAGS_REQUIRE_CERT_AUTH)) { -+ return PAM_SUCCESS; -+ } -+ - if (login_token_name == NULL) { -- return PAM_SUCCESS; -+ ret = asprintf(&prompt, SC_ENTER_FMT); -+ } else { -+ ret = asprintf(&prompt, SC_ENTER_LABEL_FMT, login_token_name); -+ } -+ if (ret == -1) { -+ return ENOMEM; - } - -- 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) { -- D(("malloc failed.")); -- return ENOMEM; -- } -+ pi->flags |= PAM_CLI_FLAGS_REQUIRE_CERT_AUTH; -+ -+ /* TODO: check multiple cert case */ -+ while (pi->cert_list == NULL || pi->cert_list->token_name == NULL -+ || (login_token_name != NULL -+ && strcmp(login_token_name, -+ pi->cert_list->token_name) != 0)) { - -- ret = snprintf(prompt, size, SC_ENTER_FMT, -- login_token_name); -- if (ret < 0 || ret >= size) { -- D(("snprintf failed.")); -- free(prompt); -- return EFAULT; -+ if (retries < 0) { -+ ret = PAM_AUTHINFO_UNAVAIL; -+ goto done; - } -+ retries--; - -- ret = do_pam_conversation(pamh, PAM_PROMPT_ECHO_OFF, prompt, -- NULL, &answer); -- free(prompt); -+ ret = do_pam_conversation(pamh, PAM_TEXT_INFO, prompt, NULL, NULL); - if (ret != PAM_SUCCESS) { - D(("do_pam_conversation failed.")); -- return ret; -- } else { -- free(answer); -+ goto done; - } - - pam_status = send_and_receive(pamh, pi, SSS_PAM_PREAUTH, quiet_mode); -@@ -2335,7 +2337,14 @@ static int check_login_token_name(pam_handle_t *pamh, struct pam_items *pi, - } - } - -- return PAM_SUCCESS; -+ ret = PAM_SUCCESS; -+ -+done: -+ -+ pi->flags = orig_flags; -+ free(prompt); -+ -+ return ret; - } - - static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, -@@ -2394,8 +2403,19 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, - && (pi.pam_authtok == NULL - || (flags & PAM_CLI_FLAGS_PROMPT_ALWAYS)) - && access(PAM_PREAUTH_INDICATOR, F_OK) == 0) { -+ -+ if (flags & PAM_CLI_FLAGS_REQUIRE_CERT_AUTH) { -+ /* Do not use PAM_CLI_FLAGS_REQUIRE_CERT_AUTH in the first -+ * SSS_PAM_PREAUTH run. In case a card is already inserted -+ * we do not have to prompt to insert a card. */ -+ pi.flags &= ~PAM_CLI_FLAGS_REQUIRE_CERT_AUTH; -+ pi.flags |= PAM_CLI_FLAGS_TRY_CERT_AUTH; -+ } -+ - pam_status = send_and_receive(pamh, &pi, SSS_PAM_PREAUTH, - quiet_mode); -+ -+ pi.flags = flags; - if (pam_status != PAM_SUCCESS) { - D(("send_and_receive returned [%d] during pre-auth", - pam_status)); -@@ -2414,8 +2434,10 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, - return PAM_AUTHINFO_UNAVAIL; - } - -- if (strcmp(pi.pam_service, "gdm-smartcard") == 0) { -- ret = check_login_token_name(pamh, &pi, quiet_mode); -+ if (strcmp(pi.pam_service, "gdm-smartcard") == 0 -+ || (flags & PAM_CLI_FLAGS_REQUIRE_CERT_AUTH)) { -+ ret = check_login_token_name(pamh, &pi, retries, -+ quiet_mode); - if (ret != PAM_SUCCESS) { - D(("check_login_token_name failed.\n")); - return ret; -diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h -index 38e3f999d799556a56ac08f0f3a6b538b8cde9f3..af8a43916d43b631092941fed13c520273a1acc5 100644 ---- a/src/sss_client/sss_cli.h -+++ b/src/sss_client/sss_cli.h -@@ -363,6 +363,7 @@ enum pam_item_type { - SSS_PAM_ITEM_CLI_LOCALE, - SSS_PAM_ITEM_CLI_PID, - SSS_PAM_ITEM_REQUESTED_DOMAINS, -+ SSS_PAM_ITEM_FLAGS, - }; - - #define PAM_CLI_FLAGS_USE_FIRST_PASS (1 << 0) -@@ -374,6 +375,7 @@ enum pam_item_type { - #define PAM_CLI_FLAGS_ALLOW_MISSING_NAME (1 << 6) - #define PAM_CLI_FLAGS_PROMPT_ALWAYS (1 << 7) - #define PAM_CLI_FLAGS_TRY_CERT_AUTH (1 << 8) -+#define PAM_CLI_FLAGS_REQUIRE_CERT_AUTH (1 << 9) - - #define SSS_NSS_MAX_ENTRIES 256 - #define SSS_NSS_HEADER_SIZE (sizeof(uint32_t) * 4) -diff --git a/src/util/sss_pam_data.c b/src/util/sss_pam_data.c -index 5e41349b9e98974563bf55c41ce36c26b897ac99..cb8779c1dff04832f623eb518d2b010107d4b045 100644 ---- a/src/util/sss_pam_data.c -+++ b/src/util/sss_pam_data.c -@@ -176,6 +176,7 @@ void pam_print_data(int l, struct pam_data *pd) - DEBUG(l, "priv: %d\n", pd->priv); - DEBUG(l, "cli_pid: %d\n", pd->cli_pid); - DEBUG(l, "logon name: %s\n", PAM_SAFE_ITEM(pd->logon_name)); -+ DEBUG(l, "flags: %d\n", pd->cli_flags); - } - - int pam_add_response(struct pam_data *pd, enum response_type type, -diff --git a/src/util/sss_pam_data.h b/src/util/sss_pam_data.h -index 7d74fa6a0026d3964f33c8529063b1dceae45688..c9898105418fc76b45d78883a0520f37d0ae1c05 100644 ---- a/src/util/sss_pam_data.h -+++ b/src/util/sss_pam_data.h -@@ -58,6 +58,7 @@ struct pam_data { - struct sss_auth_token *newauthtok; - uint32_t cli_pid; - char *logon_name; -+ uint32_t cli_flags; - - int pam_status; - int response_delay; --- -2.14.4 - diff --git a/SOURCES/0042-IPA-AD-SDAP-BE-Generate-refresh-callbacks-with-a-mac.patch b/SOURCES/0042-IPA-AD-SDAP-BE-Generate-refresh-callbacks-with-a-mac.patch new file mode 100644 index 0000000..4540691 --- /dev/null +++ b/SOURCES/0042-IPA-AD-SDAP-BE-Generate-refresh-callbacks-with-a-mac.patch @@ -0,0 +1,300 @@ +From 01572f3d8c18dcbd4836522ee5e24bd0739e0255 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 25 Jun 2019 15:01:15 +0200 +Subject: [PATCH 42/48] IPA/AD/SDAP/BE: Generate refresh callbacks with a macro + +Related: https://pagure.io/SSSD/sssd/issue/4012 + +The per-object type refresh functions are more or less boilerplate code. +Even though macro-generated code should be used very rarely, here the +generated code does not contain any logic at all so it makese sense to +generate it with macros. + +Reviewed-by: Sumit Bose +--- + src/providers/ad/ad_refresh.c | 71 ++----------------------------- + src/providers/be_refresh.h | 20 +++++++++ + src/providers/ipa/ipa_refresh.c | 71 ++----------------------------- + src/providers/ldap/sdap_refresh.c | 71 ++----------------------------- + 4 files changed, 32 insertions(+), 201 deletions(-) + +diff --git a/src/providers/ad/ad_refresh.c b/src/providers/ad/ad_refresh.c +index ed51b305a..0c2ebce5e 100644 +--- a/src/providers/ad/ad_refresh.c ++++ b/src/providers/ad/ad_refresh.c +@@ -188,73 +188,10 @@ static errno_t ad_refresh_recv(struct tevent_req *req) + return EOK; + } + +-static struct tevent_req * +-ad_refresh_initgroups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return ad_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_INITGROUPS, names, pvt); +-} +- +-static errno_t ad_refresh_initgroups_recv(struct tevent_req *req) +-{ +- return ad_refresh_recv(req); +-} +- +-static struct tevent_req * +-ad_refresh_users_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return ad_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_USER, names, pvt); +-} +- +-static errno_t ad_refresh_users_recv(struct tevent_req *req) +-{ +- return ad_refresh_recv(req); +-} +- +-static struct tevent_req * +-ad_refresh_groups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return ad_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_GROUP, names, pvt); +-} +- +-static errno_t ad_refresh_groups_recv(struct tevent_req *req) +-{ +- return ad_refresh_recv(req); +-} +- +-static struct tevent_req * +-ad_refresh_netgroups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return ad_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_NETGROUP, names, pvt); +-} +- +-static errno_t ad_refresh_netgroups_recv(struct tevent_req *req) +-{ +- return ad_refresh_recv(req); +-} ++REFRESH_SEND_RECV_FNS(ad_refresh_initgroups, ad_refresh, BE_REQ_INITGROUPS); ++REFRESH_SEND_RECV_FNS(ad_refresh_users, ad_refresh, BE_REQ_USER); ++REFRESH_SEND_RECV_FNS(ad_refresh_groups, ad_refresh, BE_REQ_GROUP); ++REFRESH_SEND_RECV_FNS(ad_refresh_netgroups, ad_refresh, BE_REQ_NETGROUP); + + errno_t ad_refresh_init(struct be_ctx *be_ctx, + struct ad_id_ctx *id_ctx) +diff --git a/src/providers/be_refresh.h b/src/providers/be_refresh.h +index 42d73d938..68be40118 100644 +--- a/src/providers/be_refresh.h ++++ b/src/providers/be_refresh.h +@@ -29,6 +29,26 @@ + /* solve circular dependency */ + struct be_ctx; + ++#define REFRESH_SEND_RECV_FNS(outer_base, inner_base, req_type) \ ++ \ ++static struct tevent_req * \ ++outer_base ##_send(TALLOC_CTX *mem_ctx, \ ++ struct tevent_context *ev, \ ++ struct be_ctx *be_ctx, \ ++ struct sss_domain_info *domain, \ ++ char **names, \ ++ void *pvt) \ ++{ \ ++ return inner_base ##_send(mem_ctx, ev, \ ++ be_ctx, domain, \ ++ req_type, names, pvt); \ ++} \ ++ \ ++static errno_t outer_base ##_recv(struct tevent_req *req) \ ++{ \ ++ return inner_base ##_recv(req); \ ++} \ ++ + /** + * name_list contains SYSDB_NAME of all expired records. + */ +diff --git a/src/providers/ipa/ipa_refresh.c b/src/providers/ipa/ipa_refresh.c +index 7b05cf9e4..13c38dff9 100644 +--- a/src/providers/ipa/ipa_refresh.c ++++ b/src/providers/ipa/ipa_refresh.c +@@ -168,73 +168,10 @@ static errno_t ipa_refresh_recv(struct tevent_req *req) + return EOK; + } + +-static struct tevent_req * +-ipa_refresh_initgroups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return ipa_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_INITGROUPS, names, pvt); +-} +- +-static errno_t ipa_refresh_initgroups_recv(struct tevent_req *req) +-{ +- return ipa_refresh_recv(req); +-} +- +-static struct tevent_req * +-ipa_refresh_users_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return ipa_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_USER, names, pvt); +-} +- +-static errno_t ipa_refresh_users_recv(struct tevent_req *req) +-{ +- return ipa_refresh_recv(req); +-} +- +-static struct tevent_req * +-ipa_refresh_groups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return ipa_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_GROUP, names, pvt); +-} +- +-static errno_t ipa_refresh_groups_recv(struct tevent_req *req) +-{ +- return ipa_refresh_recv(req); +-} +- +-static struct tevent_req * +-ipa_refresh_netgroups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return ipa_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_NETGROUP, names, pvt); +-} +- +-static errno_t ipa_refresh_netgroups_recv(struct tevent_req *req) +-{ +- return ipa_refresh_recv(req); +-} ++REFRESH_SEND_RECV_FNS(ipa_refresh_initgroups, ipa_refresh, BE_REQ_INITGROUPS); ++REFRESH_SEND_RECV_FNS(ipa_refresh_users, ipa_refresh, BE_REQ_USER); ++REFRESH_SEND_RECV_FNS(ipa_refresh_groups, ipa_refresh, BE_REQ_GROUP); ++REFRESH_SEND_RECV_FNS(ipa_refresh_netgroups, ipa_refresh, BE_REQ_NETGROUP); + + errno_t ipa_refresh_init(struct be_ctx *be_ctx, + struct ipa_id_ctx *id_ctx) +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index ff4d2116d..4e464b2f6 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -186,73 +186,10 @@ static errno_t sdap_refresh_recv(struct tevent_req *req) + return EOK; + } + +-static struct tevent_req * +-sdap_refresh_initgroups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_INITGROUPS, names, pvt); +-} +- +-static errno_t sdap_refresh_initgroups_recv(struct tevent_req *req) +-{ +- return sdap_refresh_recv(req); +-} +- +-static struct tevent_req * +-sdap_refresh_users_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_USER, names, pvt); +-} +- +-static errno_t sdap_refresh_users_recv(struct tevent_req *req) +-{ +- return sdap_refresh_recv(req); +-} +- +-static struct tevent_req * +-sdap_refresh_groups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_GROUP, names, pvt); +-} +- +-static errno_t sdap_refresh_groups_recv(struct tevent_req *req) +-{ +- return sdap_refresh_recv(req); +-} +- +-static struct tevent_req * +-sdap_refresh_netgroups_send(TALLOC_CTX *mem_ctx, +- struct tevent_context *ev, +- struct be_ctx *be_ctx, +- struct sss_domain_info *domain, +- char **names, +- void *pvt) +-{ +- return sdap_refresh_send(mem_ctx, ev, be_ctx, domain, +- BE_REQ_NETGROUP, names, pvt); +-} +- +-static errno_t sdap_refresh_netgroups_recv(struct tevent_req *req) +-{ +- return sdap_refresh_recv(req); +-} ++REFRESH_SEND_RECV_FNS(sdap_refresh_initgroups, sdap_refresh, BE_REQ_INITGROUPS); ++REFRESH_SEND_RECV_FNS(sdap_refresh_users, sdap_refresh, BE_REQ_USER); ++REFRESH_SEND_RECV_FNS(sdap_refresh_groups, sdap_refresh, BE_REQ_GROUP); ++REFRESH_SEND_RECV_FNS(sdap_refresh_netgroups, sdap_refresh, BE_REQ_NETGROUP); + + errno_t sdap_refresh_init(struct be_ctx *be_ctx, + struct sdap_id_ctx *id_ctx) +-- +2.20.1 + diff --git a/SOURCES/0042-intg-require-SC-tests.patch b/SOURCES/0042-intg-require-SC-tests.patch deleted file mode 100644 index a8c7e18..0000000 --- a/SOURCES/0042-intg-require-SC-tests.patch +++ /dev/null @@ -1,310 +0,0 @@ -From 0c56f4aee8115081cf0ee32cceb8c1dc56945e6f Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 26 Sep 2018 11:48:37 +0200 -Subject: [PATCH 42/47] intg: require SC tests - -Integration test for the new try_cert_auth and require_cert_auth option -for pam_sss. - -Related to https://pagure.io/SSSD/sssd/issue/3650 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 5cdb6968f407c7bcaba69f4892f51fd6426dddb2) ---- - src/tests/intg/Makefile.am | 16 ++- - src/tests/intg/test_pam_responder.py | 188 +++++++++++++++++++++++++++++++---- - 2 files changed, 182 insertions(+), 22 deletions(-) - -diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am -index bb3a7f01ae4f79fa05cd661993e8f9872ecd0450..44fb6353ad031fc9edac291ce70aa7557999509d 100644 ---- a/src/tests/intg/Makefile.am -+++ b/src/tests/intg/Makefile.am -@@ -113,6 +113,20 @@ pam_sss_service: - echo "password required $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@ - echo "session required $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@ - -+pam_sss_sc_required: -+ $(MKDIR_P) $(PAM_SERVICE_DIR) -+ echo "auth required $(DESTDIR)$(pammoddir)/pam_sss.so require_cert_auth retry=1" > $(PAM_SERVICE_DIR)/$@ -+ echo "account required $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@ -+ echo "password required $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@ -+ echo "session required $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@ -+ -+pam_sss_try_sc: -+ $(MKDIR_P) $(PAM_SERVICE_DIR) -+ echo "auth required $(DESTDIR)$(pammoddir)/pam_sss.so try_cert_auth" > $(PAM_SERVICE_DIR)/$@ -+ echo "account required $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@ -+ echo "password required $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@ -+ echo "session required $(DESTDIR)$(pammoddir)/pam_sss.so" >> $(PAM_SERVICE_DIR)/$@ -+ - CLEANFILES=config.py config.pyc passwd group - - clean-local: -@@ -127,7 +141,7 @@ PAM_CERT_DB_PATH="$(abs_builddir)/../test_CA/SSSD_test_CA.pem" - SOFTHSM2_CONF="$(abs_builddir)/../test_CA/softhsm2_one.conf" - endif - --intgcheck-installed: config.py passwd group pam_sss_service -+intgcheck-installed: config.py passwd group pam_sss_service pam_sss_sc_required pam_sss_try_sc - pipepath="$(DESTDIR)$(pipepath)"; \ - if test $${#pipepath} -gt 80; then \ - echo "error: Pipe directory path too long," \ -diff --git a/src/tests/intg/test_pam_responder.py b/src/tests/intg/test_pam_responder.py -index c6d048cd342838fe312287eaffff734e30ba9e1c..06f69a3d82f5502fd5ae1928d81db0287e582e88 100644 ---- a/src/tests/intg/test_pam_responder.py -+++ b/src/tests/intg/test_pam_responder.py -@@ -41,6 +41,11 @@ USER1 = dict(name='user1', passwd='x', uid=10001, gid=20001, - dir='/home/user1', - shell='/bin/bash') - -+USER2 = dict(name='user2', passwd='x', uid=10002, gid=20002, -+ gecos='User with no Smartcard mapping', -+ dir='/home/user2', -+ shell='/bin/bash') -+ - - def format_pam_cert_auth_conf(config): - """Format a basic SSSD configuration""" -@@ -55,8 +60,11 @@ def format_pam_cert_auth_conf(config): - - [pam] - pam_cert_auth = True -- pam_p11_allowed_services = +pam_sss_service -+ pam_p11_allowed_services = +pam_sss_service, +pam_sss_sc_required, \ -+ +pam_sss_try_sc - pam_cert_db_path = {config.PAM_CERT_DB_PATH} -+ p11_child_timeout = 5 -+ p11_wait_for_card_timeout = 5 - debug_level = 10 - - [domain/auth_only] -@@ -149,6 +157,15 @@ def create_nssdb(): - pkcs11_txt.close() - - -+def create_nssdb_no_cert(): -+ os.mkdir(config.SYSCONFDIR + "/pki") -+ os.mkdir(config.SYSCONFDIR + "/pki/nssdb") -+ if subprocess.call(["certutil", "-N", "-d", -+ "sql:" + config.SYSCONFDIR + "/pki/nssdb/", -+ "--empty-password"]) != 0: -+ raise Exception("certutil failed") -+ -+ - def cleanup_nssdb(): - shutil.rmtree(config.SYSCONFDIR + "/pki") - -@@ -158,14 +175,42 @@ def create_nssdb_fixture(request): - request.addfinalizer(cleanup_nssdb) - - -+def create_nssdb_no_cert_fixture(request): -+ create_nssdb_no_cert() -+ request.addfinalizer(cleanup_nssdb) -+ -+ - @pytest.fixture --def simple_pam_cert_auth(request): -+def simple_pam_cert_auth(request, passwd_ops_setup): - """Setup SSSD with pam_cert_auth=True""" - config.PAM_CERT_DB_PATH = os.environ['PAM_CERT_DB_PATH'] - conf = format_pam_cert_auth_conf(config) - create_conf_fixture(request, conf) - create_sssd_fixture(request) - create_nssdb_fixture(request) -+ passwd_ops_setup.useradd(**USER1) -+ passwd_ops_setup.useradd(**USER2) -+ return None -+ -+ -+@pytest.fixture -+def simple_pam_cert_auth_no_cert(request, passwd_ops_setup): -+ """Setup SSSD with pam_cert_auth=True""" -+ config.PAM_CERT_DB_PATH = os.environ['PAM_CERT_DB_PATH'] -+ -+ old_softhsm2_conf = os.environ['SOFTHSM2_CONF'] -+ del os.environ['SOFTHSM2_CONF'] -+ -+ conf = format_pam_cert_auth_conf(config) -+ create_conf_fixture(request, conf) -+ create_sssd_fixture(request) -+ create_nssdb_no_cert_fixture(request) -+ -+ os.environ['SOFTHSM2_CONF'] = old_softhsm2_conf -+ -+ passwd_ops_setup.useradd(**USER1) -+ passwd_ops_setup.useradd(**USER2) -+ - return None - - -@@ -176,26 +221,26 @@ def test_preauth_indicator(simple_pam_cert_auth): - - - @pytest.fixture --def pam_wrapper_setup(request): -+def env_for_sssctl(request): - pwrap_runtimedir = os.getenv("PAM_WRAPPER_SERVICE_DIR") - if pwrap_runtimedir is None: - raise ValueError("The PAM_WRAPPER_SERVICE_DIR variable is unset\n") - -+ env_for_sssctl = os.environ.copy() -+ env_for_sssctl['PAM_WRAPPER'] = "1" -+ env_for_sssctl['SSSD_INTG_PEER_UID'] = "0" -+ env_for_sssctl['SSSD_INTG_PEER_GID'] = "0" -+ env_for_sssctl['LD_PRELOAD'] += ':' + os.environ['PAM_WRAPPER_PATH'] - --def test_sc_auth_wrong_pin(simple_pam_cert_auth, pam_wrapper_setup, -- passwd_ops_setup): -+ return env_for_sssctl - -- passwd_ops_setup.useradd(**USER1) -- current_env = os.environ.copy() -- current_env['PAM_WRAPPER'] = "1" -- current_env['SSSD_INTG_PEER_UID'] = "0" -- current_env['SSSD_INTG_PEER_GID'] = "0" -- current_env['LD_PRELOAD'] += ':' + os.environ['PAM_WRAPPER_PATH'] -+ -+def test_sc_auth_wrong_pin(simple_pam_cert_auth, env_for_sssctl): - - sssctl = subprocess.Popen(["sssctl", "user-checks", "user1", - "--action=auth", "--service=pam_sss_service"], - universal_newlines=True, -- env=current_env, stdin=subprocess.PIPE, -+ env=env_for_sssctl, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - try: -@@ -214,19 +259,120 @@ def test_sc_auth_wrong_pin(simple_pam_cert_auth, pam_wrapper_setup, - "Authentication failure") != -1 - - --def test_sc_auth(simple_pam_cert_auth, pam_wrapper_setup, passwd_ops_setup): -- -- passwd_ops_setup.useradd(**USER1) -- current_env = os.environ.copy() -- current_env['PAM_WRAPPER'] = "1" -- current_env['SSSD_INTG_PEER_UID'] = "0" -- current_env['SSSD_INTG_PEER_GID'] = "0" -- current_env['LD_PRELOAD'] += ':' + os.environ['PAM_WRAPPER_PATH'] -+def test_sc_auth(simple_pam_cert_auth, env_for_sssctl): - - sssctl = subprocess.Popen(["sssctl", "user-checks", "user1", - "--action=auth", "--service=pam_sss_service"], - universal_newlines=True, -- env=current_env, stdin=subprocess.PIPE, -+ env=env_for_sssctl, stdin=subprocess.PIPE, -+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ -+ try: -+ out, err = sssctl.communicate(input="123456") -+ except: -+ sssctl.kill() -+ out, err = sssctl.communicate() -+ -+ sssctl.stdin.close() -+ sssctl.stdout.close() -+ -+ if sssctl.wait() != 0: -+ raise Exception("sssctl failed") -+ -+ assert err.find("pam_authenticate for user [user1]: Success") != -1 -+ -+ -+def test_require_sc_auth(simple_pam_cert_auth, env_for_sssctl): -+ -+ sssctl = subprocess.Popen(["sssctl", "user-checks", "user1", -+ "--action=auth", -+ "--service=pam_sss_sc_required"], -+ universal_newlines=True, -+ env=env_for_sssctl, stdin=subprocess.PIPE, -+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ -+ try: -+ out, err = sssctl.communicate(input="123456") -+ except: -+ sssctl.kill() -+ out, err = sssctl.communicate() -+ -+ sssctl.stdin.close() -+ sssctl.stdout.close() -+ -+ if sssctl.wait() != 0: -+ raise Exception("sssctl failed") -+ -+ assert err.find("pam_authenticate for user [user1]: Success") != -1 -+ -+ -+def test_require_sc_auth_no_cert(simple_pam_cert_auth_no_cert, env_for_sssctl): -+ -+ # We have to wait about 20s before the command returns because there will -+ # be 2 run since retry=1 in the PAM configuration and both -+ # p11_child_timeout and p11_wait_for_card_timeout are 5s in sssd.conf, -+ # so 2*(5+5)=20. */ -+ start_time = time.time() -+ sssctl = subprocess.Popen(["sssctl", "user-checks", "user1", -+ "--action=auth", -+ "--service=pam_sss_sc_required"], -+ universal_newlines=True, -+ env=env_for_sssctl, stdin=subprocess.PIPE, -+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ -+ try: -+ out, err = sssctl.communicate(input="123456") -+ except: -+ sssctl.kill() -+ out, err = sssctl.communicate() -+ -+ sssctl.stdin.close() -+ sssctl.stdout.close() -+ -+ if sssctl.wait() != 0: -+ raise Exception("sssctl failed") -+ -+ end_time = time.time() -+ assert end_time > start_time and \ -+ (end_time - start_time) >= 20 and \ -+ (end_time - start_time) < 40 -+ assert out.find("Please enter smart card\nPlease enter smart card") != -1 -+ assert err.find("pam_authenticate for user [user1]: Authentication " + -+ "service cannot retrieve authentication info") != -1 -+ -+ -+def test_try_sc_auth_no_map(simple_pam_cert_auth, env_for_sssctl): -+ -+ sssctl = subprocess.Popen(["sssctl", "user-checks", "user2", -+ "--action=auth", -+ "--service=pam_sss_try_sc"], -+ universal_newlines=True, -+ env=env_for_sssctl, stdin=subprocess.PIPE, -+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ -+ try: -+ out, err = sssctl.communicate(input="123456") -+ except: -+ sssctl.kill() -+ out, err = sssctl.communicate() -+ -+ sssctl.stdin.close() -+ sssctl.stdout.close() -+ -+ if sssctl.wait() != 0: -+ raise Exception("sssctl failed") -+ -+ assert err.find("pam_authenticate for user [user2]: Authentication " + -+ "service cannot retrieve authentication info") != -1 -+ -+ -+def test_try_sc_auth(simple_pam_cert_auth, env_for_sssctl): -+ -+ sssctl = subprocess.Popen(["sssctl", "user-checks", "user1", -+ "--action=auth", -+ "--service=pam_sss_try_sc"], -+ universal_newlines=True, -+ env=env_for_sssctl, stdin=subprocess.PIPE, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - - try: --- -2.14.4 - diff --git a/SOURCES/0043-MAN-Amend-the-documentation-for-the-background-refre.patch b/SOURCES/0043-MAN-Amend-the-documentation-for-the-background-refre.patch new file mode 100644 index 0000000..27c03ac --- /dev/null +++ b/SOURCES/0043-MAN-Amend-the-documentation-for-the-background-refre.patch @@ -0,0 +1,36 @@ +From 67ede7a6e6199f39f8c62e3ad56c1702fc0b4298 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 26 Jun 2019 12:43:45 +0200 +Subject: [PATCH 43/48] MAN: Amend the documentation for the background refresh + +Related: https://pagure.io/SSSD/sssd/issue/4012 + +Reviewed-by: Sumit Bose +--- + src/man/sssd.conf.5.xml | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml +index 337543e56..3b4840793 100644 +--- a/src/man/sssd.conf.5.xml ++++ b/src/man/sssd.conf.5.xml +@@ -2170,7 +2170,15 @@ p11_uri = library-description=OpenSC%20smartcard%20framework;slot-id=2 + + + The background refresh will process users, +- groups and netgroups in the cache. ++ groups and netgroups in the cache. For users ++ who have performed the initgroups (get group ++ membership for user, typically ran at login) ++ operation in the past, both the user entry ++ and the group membership are updated. ++ ++ ++ This option is automatically inherited for all ++ trusted domains. + + + You can consider setting this value to +-- +2.20.1 + diff --git a/SOURCES/0043-p11_child-show-PKCS-11-URI-in-debug-output.patch b/SOURCES/0043-p11_child-show-PKCS-11-URI-in-debug-output.patch deleted file mode 100644 index 1b0cf16..0000000 --- a/SOURCES/0043-p11_child-show-PKCS-11-URI-in-debug-output.patch +++ /dev/null @@ -1,408 +0,0 @@ -From d931db919e85fda2bfc195403c81b873ca94c4d4 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 8 Oct 2018 10:45:28 +0200 -Subject: [PATCH 43/47] p11_child: show PKCS#11 URI in debug output - -Related to https://pagure.io/SSSD/sssd/issue/3814 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 46fd681a73ffef062cd027e7018e1a02d7a0a9df) ---- - src/p11_child/p11_child_nss.c | 240 ++++++++++++++++++++++++++++++++++++++ - src/p11_child/p11_child_openssl.c | 80 +++++++++++++ - 2 files changed, 320 insertions(+) - -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index b2777d1d245d4942263ebf0610eef5cf6a528bd1..fff1f2525878b596e518b717476e892d1cf2ddae 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -39,6 +39,7 @@ - #include - #include - #include -+#include - - #include "util/child_common.h" - #include "providers/backend.h" -@@ -63,6 +64,239 @@ struct p11_ctx { - | certificateUsageStatusResponder \ - | certificateUsageSSLCA ) - -+ -+static char *get_pkcs11_string(TALLOC_CTX *mem_ctx, const char *in, size_t len) -+{ -+ size_t c = len; -+ -+ if (in == NULL || len == 0) { -+ return NULL; -+ } -+ -+ while(c > 0 && in[c - 1] == ' ') { -+ c--; -+ } -+ -+ return talloc_strndup(mem_ctx, in, c); -+} -+ -+static char *pct_encode(TALLOC_CTX *mem_ctx, SECItem *data) -+{ -+ char *pct; -+ size_t c; -+ int ret; -+ -+ pct = talloc_zero_size(mem_ctx, sizeof(char) * (3*data->len + 1)); -+ if (pct == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n"); -+ return NULL; -+ } -+ -+ for (c = 0; c < data->len; c++) { -+ ret = snprintf(pct + 3*c, 4, "%%%02X", data->data[c]); -+ if (ret != 3) { -+ DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); -+ talloc_free(pct); -+ return NULL; -+ } -+ } -+ -+ return pct; -+} -+ -+static char *get_key_id_pct(TALLOC_CTX *mem_ctx, 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][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); -+ return NULL; -+ } -+ -+ key_id_str = pct_encode(mem_ctx, key_id); -+ SECITEM_FreeItem(key_id, PR_TRUE); -+ if (key_id_str == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "pct_encode failed.\n"); -+ return NULL; -+ } -+ -+ return key_id_str; -+} -+ -+static char *get_pkcs11_uri(TALLOC_CTX *mem_ctx, SECMODModule *mod, -+ PK11SlotInfo *slot, -+ const char *label, CERTCertificate *cert) -+{ -+ CK_INFO module_info; -+ CK_SLOT_INFO slot_info; -+ CK_TOKEN_INFO token_info; -+ char *values[13]; -+ PK11URIAttribute attrs[13]; -+ size_t nattrs = 0; -+ SECStatus rv; -+ char *tmp_str; -+ char *uri_str; -+ PK11URI *uri; -+ CK_SLOT_ID slot_id; -+ char *id_pct; -+ -+ rv = PK11_GetModInfo(mod, &module_info); -+ if (rv != SECSuccess) { -+ DEBUG(SSSDBG_OP_FAILURE, "PK11_GetModInfo failed.\n"); -+ return NULL; -+ } -+ -+ rv = PK11_GetSlotInfo(slot, &slot_info); -+ if (rv != SECSuccess) { -+ DEBUG(SSSDBG_OP_FAILURE, "PK11_GetSlotInfo failed.\n"); -+ return NULL; -+ } -+ -+ rv = PK11_GetTokenInfo(slot, &token_info); -+ if (rv != SECSuccess) { -+ DEBUG(SSSDBG_OP_FAILURE, "PK11_GetTokenInfo failed.\n"); -+ return NULL; -+ } -+ values[nattrs] = get_pkcs11_string(mem_ctx, -+ (char *)module_info.libraryDescription, -+ sizeof(module_info.libraryDescription)); -+ if (values[nattrs] != NULL && *values[nattrs] != '\0') { -+ attrs[nattrs].name = PK11URI_PATTR_LIBRARY_DESCRIPTION; -+ attrs[nattrs].value = values[nattrs]; -+ nattrs++; -+ } -+ -+ values[nattrs] = get_pkcs11_string(mem_ctx, -+ (char *)module_info.manufacturerID, -+ sizeof(module_info.manufacturerID)); -+ if (values[nattrs] != NULL && *values[nattrs] != '\0') { -+ attrs[nattrs].name = PK11URI_PATTR_LIBRARY_MANUFACTURER; -+ attrs[nattrs].value = values[nattrs]; -+ nattrs++; -+ } -+ -+ values[nattrs] = talloc_asprintf(mem_ctx, "%d.%d", -+ module_info.libraryVersion.major, -+ module_info.libraryVersion.minor); -+ if (values[nattrs] != NULL && *values[nattrs] != '\0') { -+ attrs[nattrs].name = PK11URI_PATTR_LIBRARY_VERSION; -+ attrs[nattrs].value = values[nattrs]; -+ nattrs++; -+ } -+ -+ values[nattrs] = get_pkcs11_string(mem_ctx, -+ (char *)slot_info.slotDescription, -+ sizeof(slot_info.slotDescription)); -+ if (values[nattrs] != NULL && *values[nattrs] != '\0') { -+ attrs[nattrs].name = PK11URI_PATTR_SLOT_DESCRIPTION; -+ attrs[nattrs].value = values[nattrs]; -+ nattrs++; -+ } -+ -+ values[nattrs] = get_pkcs11_string(mem_ctx, -+ (char *)slot_info.manufacturerID, -+ sizeof(slot_info.manufacturerID)); -+ if (values[nattrs] != NULL && *values[nattrs] != '\0') { -+ attrs[nattrs].name = PK11URI_PATTR_SLOT_MANUFACTURER; -+ attrs[nattrs].value = values[nattrs]; -+ nattrs++; -+ } -+ -+ slot_id = PK11_GetSlotID(slot); -+ values[nattrs] = talloc_asprintf(mem_ctx, "%d", (int) slot_id); -+ if (values[nattrs] != NULL && *values[nattrs] != '\0') { -+ attrs[nattrs].name = PK11URI_PATTR_SLOT_ID; -+ attrs[nattrs].value = values[nattrs]; -+ nattrs++; -+ } -+ -+ values[nattrs] = get_pkcs11_string(mem_ctx, (char *)token_info.model, -+ sizeof(token_info.model)); -+ if (values[nattrs] != NULL && *values[nattrs] != '\0') { -+ attrs[nattrs].name = PK11URI_PATTR_MODEL; -+ attrs[nattrs].value = values[nattrs]; -+ nattrs++; -+ } -+ -+ values[nattrs] = get_pkcs11_string(mem_ctx, -+ (char *)token_info.manufacturerID, -+ sizeof(token_info.manufacturerID)); -+ if (values[nattrs] != NULL && *values[nattrs] != '\0') { -+ attrs[nattrs].name = PK11URI_PATTR_MANUFACTURER; -+ attrs[nattrs].value = values[nattrs]; -+ nattrs++; -+ } -+ -+ values[nattrs] = get_pkcs11_string(mem_ctx, -+ (char *)token_info.serialNumber, -+ sizeof(token_info.serialNumber)); -+ if (values[nattrs] != NULL && *values[nattrs] != '\0') { -+ attrs[nattrs].name = PK11URI_PATTR_SERIAL; -+ attrs[nattrs].value = values[nattrs]; -+ nattrs++; -+ } -+ -+ values[nattrs] = get_pkcs11_string(mem_ctx, (char *)token_info.label, -+ sizeof(token_info.label)); -+ if (values[nattrs] != NULL && *values[nattrs] != '\0') { -+ attrs[nattrs].name = PK11URI_PATTR_TOKEN; -+ attrs[nattrs].value = values[nattrs]; -+ nattrs++; -+ } -+ -+ if (label != NULL && *label != '\0') { -+ attrs[nattrs].name = PK11URI_PATTR_OBJECT; -+ attrs[nattrs].value = label; -+ nattrs++; -+ } -+ -+ attrs[nattrs].name = PK11URI_PATTR_TYPE; -+ attrs[nattrs].value = "cert"; -+ nattrs++; -+ -+ uri = PK11URI_CreateURI(attrs, nattrs, NULL, 0); -+ if (uri == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "PK11URI_CreateURI failed.\n"); -+ return NULL; -+ } -+ -+ tmp_str = PK11URI_FormatURI(NULL, uri); -+ PK11URI_DestroyURI(uri); -+ if (tmp_str == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "PK11URI_FormatURI failed.\n"); -+ return NULL; -+ } -+ -+ /* Currently I have no idea how to get the ID properly formatted with the -+ * NSS PK11 calls. Since all attribute values are treated as strings zeros -+ * in the IDs cannot be handled. And the IDs cannot be set percent-encoded -+ * since all attribute values will be escaped which means the '%' sign -+ * will be escaped to '%25'. Hence for the time being the ID is added -+ * manually to the end of the URI. */ -+ id_pct = get_key_id_pct(mem_ctx, slot, cert); -+ if (id_pct == NULL || *id_pct == '\0') { -+ DEBUG(SSSDBG_OP_FAILURE, "get_key_id_pct failed.\n"); -+ PORT_Free(tmp_str); -+ return NULL; -+ } -+ -+ uri_str = talloc_asprintf(mem_ctx, "%s;%s=%s", tmp_str, -+ PK11URI_PATTR_ID, id_pct); -+ talloc_free(id_pct); -+ if (uri_str == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); -+ return NULL; -+ } -+ -+ return uri_str; -+ -+} -+ - static char *password_passthrough(PK11SlotInfo *slot, PRBool retry, void *arg) - { - /* give up if 1) no password was supplied, or 2) the password has already -@@ -465,6 +699,9 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - cert_list_node->cert->nickname, - cert_list_node->cert->subjectName); - -+ DEBUG(SSSDBG_TRACE_ALL, "module uri: %s.\n", PK11_GetModuleURI(module)); -+ DEBUG(SSSDBG_TRACE_ALL, "token uri: %s.\n", PK11_GetTokenURI(slot)); -+ - if (p11_ctx->handle != NULL) { - if (!do_verification(p11_ctx, cert_list_node->cert)) { - DEBUG(SSSDBG_OP_FAILURE, -@@ -651,6 +888,9 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - - DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n", - key_id_str); -+ DEBUG(SSSDBG_TRACE_ALL, "uri: %s.\n", get_pkcs11_uri(mem_ctx, module, -+ slot, label, -+ found_cert)); - - multi = talloc_asprintf_append(multi, "%s\n%s\n%s\n%s\n%s\n", - token_name, module_name, key_id_str, -diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c -index d4572d99cd3a3186128b46cc4a9453d716bd7979..09edeefbdf95e151af97cd4b4e5811569386caec 100644 ---- a/src/p11_child/p11_child_openssl.c -+++ b/src/p11_child/p11_child_openssl.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - - #include - -@@ -43,6 +44,72 @@ struct p11_ctx { - bool wait_for_card; - }; - -+ -+static char *get_pkcs11_uri(TALLOC_CTX *mem_ctx, CK_INFO *module_info, -+ CK_SLOT_INFO *slot_info, CK_SLOT_ID slot_id, -+ CK_TOKEN_INFO *token_info, CK_ATTRIBUTE *label, -+ CK_ATTRIBUTE *id) -+{ -+ P11KitUri *uri; -+ char *uri_str = NULL; -+ char *tmp_str = NULL; -+ int ret; -+ CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE; -+ CK_ATTRIBUTE class_attr = {CKA_CLASS, &cert_class, sizeof(CK_OBJECT_CLASS)}; -+ -+ uri = p11_kit_uri_new(); -+ if (uri == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_new failed.\n"); -+ return NULL; -+ } -+ -+ ret = p11_kit_uri_set_attribute(uri, label); -+ if (ret != P11_KIT_URI_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_set_attribute failed.\n"); -+ goto done; -+ } -+ -+ ret = p11_kit_uri_set_attribute(uri, id); -+ if (ret != P11_KIT_URI_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_set_attribute failed.\n"); -+ goto done; -+ } -+ -+ ret = p11_kit_uri_set_attribute(uri, &class_attr); -+ if (ret != P11_KIT_URI_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_set_attribute failed.\n"); -+ goto done; -+ } -+ -+ -+ memcpy(p11_kit_uri_get_token_info(uri), token_info, sizeof(CK_TOKEN_INFO)); -+ -+ memcpy(p11_kit_uri_get_slot_info(uri), slot_info, sizeof(CK_SLOT_INFO)); -+ ret = p11_kit_uri_set_slot_id(uri, slot_id); -+ -+ memcpy(p11_kit_uri_get_module_info(uri), module_info, sizeof(CK_INFO)); -+ -+ ret = p11_kit_uri_format(uri, P11_KIT_URI_FOR_ANY, &tmp_str); -+ if (ret != P11_KIT_URI_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_format failed [%s].\n", -+ p11_kit_uri_message(ret)); -+ goto done; -+ } -+ -+ if (tmp_str != NULL) { -+ uri_str = talloc_strdup(mem_ctx, tmp_str); -+ free(tmp_str); -+ if (uri_str == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); -+ } -+ } -+ -+done: -+ p11_kit_uri_free(uri); -+ -+ return uri_str; -+} -+ - static int talloc_cleanup_openssl(struct p11_ctx *p11_ctx) - { - CRYPTO_cleanup_all_ex_data(); -@@ -234,6 +301,7 @@ struct cert_list { - X509 *cert; - char *subject_dn; - char *cert_b64; -+ char *uri; - CK_KEY_TYPE key_type; - CK_OBJECT_HANDLE private_key; - }; -@@ -608,6 +676,7 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - CK_SLOT_ID slot_id; - CK_SLOT_INFO info; - CK_TOKEN_INFO token_info; -+ CK_INFO module_info; - CK_RV rv; - size_t module_id; - char *module_file_name = NULL; -@@ -821,6 +890,17 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - } - } - -+ memset(&module_info, 0, sizeof(CK_INFO)); -+ module->C_GetInfo(&module_info); -+ -+ DLIST_FOR_EACH(item, cert_list) { -+ item->uri = get_pkcs11_uri(mem_ctx, &module_info, &info, slot_id, -+ &token_info, -+ &item->attributes[1] /* label */, -+ &item->attributes[0] /* id */); -+ DEBUG(SSSDBG_TRACE_ALL, "uri: %s.\n", item->uri); -+ } -+ - /* TODO: check module_name_in, token_name_in, key_id_in */ - - if (cert_list == NULL) { --- -2.14.4 - diff --git a/SOURCES/0044-DP-SYSDB-Move-the-code-to-set-initgrExpireTimestamp-.patch b/SOURCES/0044-DP-SYSDB-Move-the-code-to-set-initgrExpireTimestamp-.patch new file mode 100644 index 0000000..8a169cd --- /dev/null +++ b/SOURCES/0044-DP-SYSDB-Move-the-code-to-set-initgrExpireTimestamp-.patch @@ -0,0 +1,216 @@ +From 4ba4b2d96b59386f3fd4d8bb0c4ada4798db48b0 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 1 Jul 2019 14:15:29 +0200 +Subject: [PATCH 44/48] DP/SYSDB: Move the code to set initgrExpireTimestamp to + a reusable function + +Related: https://pagure.io/SSSD/sssd/issue/4012 + +Because the initgroups request can, especially in the case of IPA provider +with trusts, contain several sub-requests that run some provider-specific +initgroups internally and then run post-processing AND because at the same +time concurrent requests in the responder need to be sure that the +initgrExpireTimestamp is only increased when the initgroups request is +really done, we only set the initgrExpireTimestamp in the DP when the +request finishes. + +This means, the background refresh task needs to also set the +initgrExpireTimestamp attribute on its own as well. This patch so far +splits the helper function into a reusable one so it can later be used +by the background refresh. + +For examples of the bugs caused by the initgrTimestamp being set before +the whole multi-step operation finishes, please see tickets #3744 +or #2634. + +Reviewed-by: Sumit Bose +--- + src/db/sysdb.h | 11 ++++ + src/db/sysdb_ops.c | 70 ++++++++++++++++++++++ + src/providers/data_provider/dp_target_id.c | 55 ++--------------- + 3 files changed, 85 insertions(+), 51 deletions(-) + +diff --git a/src/db/sysdb.h b/src/db/sysdb.h +index 28801e030..56fd770e4 100644 +--- a/src/db/sysdb.h ++++ b/src/db/sysdb.h +@@ -1113,6 +1113,17 @@ errno_t sysdb_store_override(struct sss_domain_info *domain, + enum sysdb_member_type type, + struct sysdb_attrs *attrs, struct ldb_dn *obj_dn); + ++/* ++ * Cache the time of last initgroups invocation. Typically this is not done when ++ * the provider-specific request itself finishes, because currently the request ++ * might hand over to other requests from a different provider (e.g. an AD user ++ * from a trusted domain might need to also call an IPA request to fetch the ++ * external groups). Instead, the caller of the initgroups request, typically ++ * the DP or the periodical refresh task sets the timestamp. ++ */ ++errno_t sysdb_set_initgr_expire_timestamp(struct sss_domain_info *domain, ++ const char *name_or_upn_or_sid); ++ + /* Password caching function. + * If you are in a transaction ignore sysdb and pass in the handle. + * If you are not in a transaction pass NULL in handle and provide sysdb, +diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c +index 55ba62140..c57a13be1 100644 +--- a/src/db/sysdb_ops.c ++++ b/src/db/sysdb_ops.c +@@ -3277,6 +3277,76 @@ int sysdb_cache_password(struct sss_domain_info *domain, + SSS_AUTHTOK_TYPE_PASSWORD, 0); + } + ++static errno_t set_initgroups_expire_attribute(struct sss_domain_info *domain, ++ const char *name) ++{ ++ errno_t ret; ++ time_t cache_timeout; ++ struct sysdb_attrs *attrs; ++ ++ attrs = sysdb_new_attrs(NULL); ++ if (attrs == NULL) { ++ return ENOMEM; ++ } ++ ++ cache_timeout = domain->user_timeout ++ ? time(NULL) + domain->user_timeout ++ : 0; ++ ++ ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, cache_timeout); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up attrs\n"); ++ goto done; ++ } ++ ++ ret = sysdb_set_user_attr(domain, name, attrs, SYSDB_MOD_REP); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "Failed to set initgroups expire attribute\n"); ++ goto done; ++ } ++ ++done: ++ talloc_zfree(attrs); ++ return ret; ++} ++ ++errno_t sysdb_set_initgr_expire_timestamp(struct sss_domain_info *domain, ++ const char *name_or_upn_or_sid) ++{ ++ const char *cname; ++ errno_t ret; ++ TALLOC_CTX *tmp_ctx; ++ ++ tmp_ctx = talloc_new(NULL); ++ if (!tmp_ctx) { ++ return ENOMEM; ++ } ++ ++ ret = sysdb_get_real_name(tmp_ctx, domain, name_or_upn_or_sid, &cname); ++ if (ret == ENOENT) { ++ /* No point trying to bump timestamp of an entry that does not exist..*/ ++ ret = EOK; ++ goto done; ++ } else if (ret != EOK) { ++ cname = name_or_upn_or_sid; ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Failed to canonicalize name, using [%s]\n", name_or_upn_or_sid); ++ } ++ ++ ret = set_initgroups_expire_attribute(domain, cname); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Cannot set the initgroups expire attribute [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ } ++ ++ ret = EOK; ++done: ++ talloc_free(tmp_ctx); ++ return ret; ++} ++ + /* =Custom Search================== */ + + int sysdb_search_custom(TALLOC_CTX *mem_ctx, +diff --git a/src/providers/data_provider/dp_target_id.c b/src/providers/data_provider/dp_target_id.c +index 748d88674..d5b3823ac 100644 +--- a/src/providers/data_provider/dp_target_id.c ++++ b/src/providers/data_provider/dp_target_id.c +@@ -390,69 +390,22 @@ done: + return ret; + } + +-static errno_t set_initgroups_expire_attribute(struct sss_domain_info *domain, +- const char *name) +-{ +- errno_t ret; +- time_t cache_timeout; +- struct sysdb_attrs *attrs; +- +- attrs = sysdb_new_attrs(NULL); +- if (attrs == NULL) { +- return ENOMEM; +- } +- +- cache_timeout = domain->user_timeout +- ? time(NULL) + domain->user_timeout +- : 0; +- +- ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, cache_timeout); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up attrs\n"); +- goto done; +- } +- +- ret = sysdb_set_user_attr(domain, name, attrs, SYSDB_MOD_REP); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, +- "Failed to set initgroups expire attribute\n"); +- goto done; +- } +- +-done: +- talloc_zfree(attrs); +- return ret; +-} +- + static void dp_req_initgr_pp_set_initgr_timestamp(struct dp_initgr_ctx *ctx, + struct dp_reply_std *reply) + { + errno_t ret; +- const char *cname; + + if (reply->dp_error != DP_ERR_OK || reply->error != EOK) { + /* Only bump the timestamp on successful lookups */ + return; + } + +- ret = sysdb_get_real_name(ctx, +- ctx->domain_info, +- ctx->filter_value, +- &cname); +- if (ret == ENOENT) { +- /* No point trying to bump timestamp of an entry that does not exist..*/ +- return; +- } else if (ret != EOK) { +- cname = ctx->filter_value; +- DEBUG(SSSDBG_MINOR_FAILURE, +- "Failed to canonicalize name, using [%s]\n", cname); +- } +- +- ret = set_initgroups_expire_attribute(ctx->domain_info, cname); ++ ret = sysdb_set_initgr_expire_timestamp(ctx->domain_info, ++ ctx->filter_value); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, +- "Cannot set the initgroups expire attribute [%d]: %s\n", +- ret, sss_strerror(ret)); ++ "Failed to set initgroups expiration for [%s]\n", ++ ctx->filter_value); + } + } + +-- +2.20.1 + diff --git a/SOURCES/0044-p11_child-add-PKCS-11-uri-to-restrict-selection.patch b/SOURCES/0044-p11_child-add-PKCS-11-uri-to-restrict-selection.patch deleted file mode 100644 index bc0eb02..0000000 --- a/SOURCES/0044-p11_child-add-PKCS-11-uri-to-restrict-selection.patch +++ /dev/null @@ -1,239 +0,0 @@ -From d0830a4445115ef4cdbc8b524794f276f7954f7a Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 8 Oct 2018 12:47:25 +0200 -Subject: [PATCH 44/47] p11_child: add PKCS#11 uri to restrict selection - -Related to https://pagure.io/SSSD/sssd/issue/3814 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit f7b2152a4c3c816a5bc4226a0e01791313accef3) ---- - src/p11_child/p11_child.h | 2 +- - src/p11_child/p11_child_common.c | 9 +++-- - src/p11_child/p11_child_nss.c | 2 +- - src/p11_child/p11_child_openssl.c | 81 +++++++++++++++++++++++++++++++++++++-- - 4 files changed, 86 insertions(+), 8 deletions(-) - -diff --git a/src/p11_child/p11_child.h b/src/p11_child/p11_child.h -index dd8fdeafbf947aad930e61ae694bc99df6d8212a..92ecf74a891e46f93e8dee69391bec6325fe2249 100644 ---- a/src/p11_child/p11_child.h -+++ b/src/p11_child/p11_child.h -@@ -54,5 +54,5 @@ bool do_verification_b64(struct p11_ctx *p11_ctx, const char *cert_b64); - errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - enum op_mode mode, const char *pin, - const char *module_name_in, const char *token_name_in, -- const char *key_id_in, char **_multi); -+ const char *key_id_in, const char *uri, char **_multi); - #endif /* __P11_CHILD_H__ */ -diff --git a/src/p11_child/p11_child_common.c b/src/p11_child/p11_child_common.c -index bc5f6b09b191f0ea853f45d8a78bc6e4a69c3da7..097e7fa07fb4d90e087250aec9f971b4a2afdb52 100644 ---- a/src/p11_child/p11_child_common.c -+++ b/src/p11_child/p11_child_common.c -@@ -60,7 +60,7 @@ static int do_work(TALLOC_CTX *mem_ctx, enum op_mode mode, const char *ca_db, - bool wait_for_card, - const char *cert_b64, const char *pin, - const char *module_name, const char *token_name, -- const char *key_id, char **multi) -+ const char *key_id, const char *uri, char **multi) - { - int ret; - struct p11_ctx *p11_ctx; -@@ -90,7 +90,7 @@ static int do_work(TALLOC_CTX *mem_ctx, enum op_mode mode, const char *ca_db, - } - } else { - ret = do_card(mem_ctx, p11_ctx, mode, pin, -- module_name, token_name, key_id, multi); -+ module_name, token_name, key_id, uri, multi); - } - - done: -@@ -159,6 +159,7 @@ int main(int argc, const char *argv[]) - char *key_id = NULL; - char *cert_b64 = NULL; - bool wait_for_card = false; -+ char *uri = NULL; - - struct poptOption long_options[] = { - POPT_AUTOHELP -@@ -194,6 +195,8 @@ int main(int argc, const char *argv[]) - _("Key ID for authentication"), NULL}, - {"certificate", 0, POPT_ARG_STRING, &cert_b64, 0, - _("certificate to verify, base64 encoded"), NULL}, -+ {"uri", 0, POPT_ARG_STRING, &uri, 0, -+ _("PKCS#11 URI to restrict selection"), NULL}, - POPT_TABLEEND - }; - -@@ -367,7 +370,7 @@ int main(int argc, const char *argv[]) - } - - ret = do_work(main_ctx, mode, nss_db, cert_verify_opts, wait_for_card, -- cert_b64, pin, module_name, token_name, key_id, &multi); -+ cert_b64, pin, module_name, token_name, key_id, uri, &multi); - if (ret != 0) { - DEBUG(SSSDBG_OP_FAILURE, "do_work failed.\n"); - goto fail; -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index fff1f2525878b596e518b717476e892d1cf2ddae..f9cbf3f37a26c7fefe2106aa9db4b006faaf4e1a 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -480,7 +480,7 @@ bool do_verification_b64(struct p11_ctx *p11_ctx, const char *cert_b64) - errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - enum op_mode mode, const char *pin, - const char *module_name_in, const char *token_name_in, -- const char *key_id_in, char **_multi) -+ const char *key_id_in, const char *uri, char **_multi) - { - int ret; - SECStatus rv; -diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c -index 09edeefbdf95e151af97cd4b4e5811569386caec..000e1c94f11edc32abceafb39e98b16ca0664c50 100644 ---- a/src/p11_child/p11_child_openssl.c -+++ b/src/p11_child/p11_child_openssl.c -@@ -85,7 +85,7 @@ static char *get_pkcs11_uri(TALLOC_CTX *mem_ctx, CK_INFO *module_info, - memcpy(p11_kit_uri_get_token_info(uri), token_info, sizeof(CK_TOKEN_INFO)); - - memcpy(p11_kit_uri_get_slot_info(uri), slot_info, sizeof(CK_SLOT_INFO)); -- ret = p11_kit_uri_set_slot_id(uri, slot_id); -+ p11_kit_uri_set_slot_id(uri, slot_id); - - memcpy(p11_kit_uri_get_module_info(uri), module_info, sizeof(CK_INFO)); - -@@ -662,7 +662,7 @@ static errno_t wait_for_card(CK_FUNCTION_LIST *module, CK_SLOT_ID *slot_id) - errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - enum op_mode mode, const char *pin, - const char *module_name_in, const char *token_name_in, -- const char *key_id_in, char **_multi) -+ const char *key_id_in, const char *uri_str, char **_multi) - { - int ret; - size_t c; -@@ -674,6 +674,7 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - CK_ULONG num_slots; - CK_SLOT_ID slots[MAX_SLOTS]; - CK_SLOT_ID slot_id; -+ CK_SLOT_ID uri_slot_id; - CK_SLOT_INFO info; - CK_TOKEN_INFO token_info; - CK_INFO module_info; -@@ -690,6 +691,19 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - char *multi = NULL; - bool pkcs11_session = false; - bool pkcs11_login = false; -+ P11KitUri *uri = NULL; -+ -+ if (uri_str != NULL) { -+ uri = p11_kit_uri_new(); -+ ret = p11_kit_uri_parse(uri_str, P11_KIT_URI_FOR_ANY, uri); -+ if (ret != P11_KIT_URI_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_parse failed [%d][%s].\n", -+ ret, p11_kit_uri_message(ret)); -+ ret = EINVAL; -+ goto done; -+ } -+ } -+ - - /* Maybe use P11_KIT_MODULE_TRUSTED ? */ - modules = p11_kit_modules_load_and_initialize(0); -@@ -709,6 +723,23 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - free(mod_name); - free(mod_file_name); - -+ if (uri != NULL) { -+ memset(&module_info, 0, sizeof(CK_INFO)); -+ rv = modules[c]->C_GetInfo(&module_info); -+ if (rv != CKR_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, "C_GetInfo failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ /* Skip modules which do not match the PKCS#11 URI */ -+ if (p11_kit_uri_match_module_info(uri, &module_info) != 1) { -+ DEBUG(SSSDBG_TRACE_ALL, -+ "Not matching URI [%s], skipping.\n", uri_str); -+ continue; -+ } -+ } -+ - num_slots = MAX_SLOTS; - rv = modules[c]->C_GetSlotList(CK_FALSE, slots, &num_slots); - if (rv != CKR_OK) { -@@ -730,6 +761,37 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - info.slotDescription, info.manufacturerID, info.flags, - (info.flags & CKF_REMOVABLE_DEVICE) ? "true": "false", - (info.flags & CKF_TOKEN_PRESENT) ? "true": "false"); -+ -+ /* Skip slots which do not match the PKCS#11 URI */ -+ if (uri != NULL) { -+ uri_slot_id = p11_kit_uri_get_slot_id(uri); -+ if ((uri_slot_id != (CK_SLOT_ID)-1 -+ && uri_slot_id != slots[s]) -+ || p11_kit_uri_match_slot_info(uri, &info) != 1) { -+ DEBUG(SSSDBG_TRACE_ALL, -+ "Not matching URI [%s], skipping.\n", uri_str); -+ continue; -+ } -+ } -+ -+ if ((info.flags & CKF_TOKEN_PRESENT) && uri != NULL) { -+ rv = modules[c]->C_GetTokenInfo(slots[s], &token_info); -+ if (rv != CKR_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, "C_GetTokenInfo failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ DEBUG(SSSDBG_TRACE_ALL, "Token label [%s].\n", -+ token_info.label); -+ -+ if (p11_kit_uri_match_token_info(uri, &token_info) != 1) { -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "No matching uri [%s], skipping.\n", uri_str); -+ continue; -+ } -+ -+ } -+ - if ((info.flags & CKF_REMOVABLE_DEVICE)) { - break; - } -@@ -788,6 +850,13 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - goto done; - } - -+ if (uri != NULL && p11_kit_uri_match_token_info(uri, &token_info) != 1) { -+ DEBUG(SSSDBG_CONF_SETTINGS, "No token matching uri [%s] found.", -+ uri_str); -+ ret = ENOENT; -+ goto done; -+ } -+ - module_id = c; - slot_name = p11_kit_space_strdup(info.slotDescription, - sizeof(info.slotDescription)); -@@ -891,7 +960,12 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - } - - memset(&module_info, 0, sizeof(CK_INFO)); -- module->C_GetInfo(&module_info); -+ rv = module->C_GetInfo(&module_info); -+ if (rv != CKR_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, "C_GetInfo failed.\n"); -+ ret = EIO; -+ goto done; -+ } - - DLIST_FOR_EACH(item, cert_list) { - item->uri = get_pkcs11_uri(mem_ctx, &module_info, &info, slot_id, -@@ -970,6 +1044,7 @@ done: - free(token_name); - free(module_file_name); - p11_kit_modules_finalize_and_release(modules); -+ p11_kit_uri_free(uri); - - return ret; - } --- -2.14.4 - diff --git a/SOURCES/0045-IPA-AD-LDAP-Increase-the-initgrExpireTimestamp-after.patch b/SOURCES/0045-IPA-AD-LDAP-Increase-the-initgrExpireTimestamp-after.patch new file mode 100644 index 0000000..0f181c7 --- /dev/null +++ b/SOURCES/0045-IPA-AD-LDAP-Increase-the-initgrExpireTimestamp-after.patch @@ -0,0 +1,137 @@ +From 073f79ecb75ded427d93c5f8925076646b736b1c Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 1 Jul 2019 14:26:38 +0200 +Subject: [PATCH 45/48] IPA/AD/LDAP: Increase the initgrExpireTimestamp after + finishing refresh request + +Related: https://pagure.io/SSSD/sssd/issue/4012 + +Calls sysdb_set_initgr_expire_timestamp() after each successfull refresh +of initgroups data to make sure the initgrExpireTimestamp attribute is +increased. + +If you're wondering why the timestamp is not set by the initgroups operation +itself, see tickets #3744 or #2634 for examples of bugs caused by setting +the initgrExpireTimestamp too soon. + +Reviewed-by: Sumit Bose +--- + src/providers/ad/ad_refresh.c | 12 ++++++++++++ + src/providers/ipa/ipa_refresh.c | 12 ++++++++++++ + src/providers/ldap/sdap_refresh.c | 12 ++++++++++++ + 3 files changed, 36 insertions(+) + +diff --git a/src/providers/ad/ad_refresh.c b/src/providers/ad/ad_refresh.c +index 0c2ebce5e..7aa56f33e 100644 +--- a/src/providers/ad/ad_refresh.c ++++ b/src/providers/ad/ad_refresh.c +@@ -26,6 +26,7 @@ struct ad_refresh_state { + struct be_ctx *be_ctx; + struct dp_id_data *account_req; + struct ad_id_ctx *id_ctx; ++ struct sss_domain_info *domain; + char **names; + size_t index; + }; +@@ -60,6 +61,7 @@ static struct tevent_req *ad_refresh_send(TALLOC_CTX *mem_ctx, + + state->ev = ev; + state->be_ctx = be_ctx; ++ state->domain = domain; + state->id_ctx = talloc_get_type(pvt, struct ad_id_ctx); + state->names = names; + state->index = 0; +@@ -167,6 +169,16 @@ static void ad_refresh_done(struct tevent_req *subreq) + goto done; + } + ++ if (state->account_req->entry_type == BE_REQ_INITGROUPS) { ++ ret = sysdb_set_initgr_expire_timestamp(state->domain, ++ state->account_req->filter_value); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Failed to set initgroups expiration for [%s]\n", ++ state->account_req->filter_value); ++ } ++ } ++ + ret = ad_refresh_step(req); + if (ret == EAGAIN) { + return; +diff --git a/src/providers/ipa/ipa_refresh.c b/src/providers/ipa/ipa_refresh.c +index 13c38dff9..64f8db812 100644 +--- a/src/providers/ipa/ipa_refresh.c ++++ b/src/providers/ipa/ipa_refresh.c +@@ -26,6 +26,7 @@ struct ipa_refresh_state { + struct be_ctx *be_ctx; + struct dp_id_data *account_req; + struct ipa_id_ctx *id_ctx; ++ struct sss_domain_info *domain; + char **names; + size_t index; + }; +@@ -59,6 +60,7 @@ static struct tevent_req *ipa_refresh_send(TALLOC_CTX *mem_ctx, + + state->ev = ev; + state->be_ctx = be_ctx; ++ state->domain = domain; + state->id_ctx = talloc_get_type(pvt, struct ipa_id_ctx); + state->names = names; + state->index = 0; +@@ -147,6 +149,16 @@ static void ipa_refresh_done(struct tevent_req *subreq) + goto done; + } + ++ if (state->account_req->entry_type == BE_REQ_INITGROUPS) { ++ ret = sysdb_set_initgr_expire_timestamp(state->domain, ++ state->account_req->filter_value); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Failed to set initgroups expiration for [%s]\n", ++ state->account_req->filter_value); ++ } ++ } ++ + ret = ipa_refresh_step(req); + if (ret == EAGAIN) { + return; +diff --git a/src/providers/ldap/sdap_refresh.c b/src/providers/ldap/sdap_refresh.c +index 4e464b2f6..402db53a9 100644 +--- a/src/providers/ldap/sdap_refresh.c ++++ b/src/providers/ldap/sdap_refresh.c +@@ -29,6 +29,7 @@ struct sdap_refresh_state { + struct be_ctx *be_ctx; + struct dp_id_data *account_req; + struct sdap_id_ctx *id_ctx; ++ struct sss_domain_info *domain; + struct sdap_domain *sdom; + char **names; + size_t index; +@@ -63,6 +64,7 @@ static struct tevent_req *sdap_refresh_send(TALLOC_CTX *mem_ctx, + + state->ev = ev; + state->be_ctx = be_ctx; ++ state->domain = domain; + state->id_ctx = talloc_get_type(pvt, struct sdap_id_ctx); + state->names = names; + state->index = 0; +@@ -165,6 +167,16 @@ static void sdap_refresh_done(struct tevent_req *subreq) + goto done; + } + ++ if (state->account_req->entry_type == BE_REQ_INITGROUPS) { ++ ret = sysdb_set_initgr_expire_timestamp(state->domain, ++ state->account_req->filter_value); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Failed to set initgroups expiration for [%s]\n", ++ state->account_req->filter_value); ++ } ++ } ++ + ret = sdap_refresh_step(req); + if (ret == EAGAIN) { + return; +-- +2.20.1 + diff --git a/SOURCES/0045-PAM-add-p11_uri-option.patch b/SOURCES/0045-PAM-add-p11_uri-option.patch deleted file mode 100644 index e495f08..0000000 --- a/SOURCES/0045-PAM-add-p11_uri-option.patch +++ /dev/null @@ -1,194 +0,0 @@ -From 7e7252616137378731af75a8482d4a4cade33dbd Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 9 Oct 2018 10:47:04 +0200 -Subject: [PATCH 45/47] PAM: add p11_uri option - -Related to https://pagure.io/SSSD/sssd/issue/3814 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 725b65081d19da658b16338686c53dcf16d49de0) ---- - src/confdb/confdb.h | 1 + - src/config/SSSDConfig/__init__.py.in | 1 + - src/config/cfg_rules.ini | 1 + - src/config/etc/sssd.api.conf | 1 + - src/man/sssd.conf.5.xml | 33 +++++++++++++++++++++++++++++++++ - src/responder/pam/pamsrv.h | 1 + - src/responder/pam/pamsrv_cmd.c | 12 +++++++++++- - src/responder/pam/pamsrv_p11.c | 9 ++++++++- - 8 files changed, 57 insertions(+), 2 deletions(-) - -diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h -index 87904c2146b33b57106ac3799c5a67ee02387e9b..741d4bc47dc77fe23e2ff0bc683354909f61d88f 100644 ---- a/src/confdb/confdb.h -+++ b/src/confdb/confdb.h -@@ -133,6 +133,7 @@ - #define CONFDB_PAM_WAIT_FOR_CARD_TIMEOUT "p11_wait_for_card_timeout" - #define CONFDB_PAM_APP_SERVICES "pam_app_services" - #define CONFDB_PAM_P11_ALLOWED_SERVICES "pam_p11_allowed_services" -+#define CONFDB_PAM_P11_URI "p11_uri" - - /* SUDO */ - #define CONFDB_SUDO_CONF_ENTRY "config/sudo" -diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in -index 4d1dba2d22eae4716fbabe3a3957952f7cd17751..a20157c719765a847a872fe134afe5e0415296db 100644 ---- a/src/config/SSSDConfig/__init__.py.in -+++ b/src/config/SSSDConfig/__init__.py.in -@@ -105,6 +105,7 @@ option_strings = { - 'pam_app_services' : _('Which PAM services are permitted to contact application domains'), - 'pam_p11_allowed_services' : _('Allowed services for using smartcards'), - 'p11_wait_for_card_timeout' : _('Additional timeout to wait for a card if requested'), -+ 'p11_uri' : _('PKCS#11 URI to restrict the selection of devices for Smartcard authentication'), - - # [sudo] - 'sudo_timed' : _('Whether to evaluate the time-based attributes in sudo rules'), -diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini -index 717ccfa3f382b92800bf00ed79f68641a5a83d5c..85366d25dfe508c0faf92d7d0891e287eb66dbe0 100644 ---- a/src/config/cfg_rules.ini -+++ b/src/config/cfg_rules.ini -@@ -128,6 +128,7 @@ option = p11_child_timeout - option = pam_app_services - option = pam_p11_allowed_services - option = p11_wait_for_card_timeout -+option = p11_uri - - [rule/allowed_sudo_options] - validator = ini_allowed_options -diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf -index bb686c34480be27d0829b57a853fa05921730630..c6d6690fb44cafb19b0a01b286812c74cdb2fc71 100644 ---- a/src/config/etc/sssd.api.conf -+++ b/src/config/etc/sssd.api.conf -@@ -77,6 +77,7 @@ p11_child_timeout = int, None, false - pam_app_services = str, None, false - pam_p11_allowed_services = str, None, false - p11_wait_for_card_timeout = int, None, false -+p11_uri = str, None, false - - [sudo] - # sudo service -diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml -index 4df0163311fb3845e6a027be7d0b500cb5d2f0b6..c8d53f01f3eedea1e37f6593d02ce1eeaf11d2de 100644 ---- a/src/man/sssd.conf.5.xml -+++ b/src/man/sssd.conf.5.xml -@@ -1478,6 +1478,39 @@ pam_p11_allowed_services = +my_pam_service, -login - - - -+ -+ p11_uri (string) -+ -+ -+ PKCS#11 URI (see RFC-7512 for details) which can be -+ used to restrict the selection of devices used for -+ Smartcard authentication. By default SSSD's -+ p11_child will search for a PKCS#11 slot (reader) -+ where the 'removable' flags is set and read the -+ certificates from the inserted token from the first -+ slot found. If multiple readers are connected -+ p11_uri can be use to tell p11_child to use a -+ specific reader. -+ -+ -+ Example: -+ -+p11_uri = slot-description=My%20Smartcar%20Reader -+ -+ or -+ -+p11_uri = library-description=OpenSC%20smartcard%20framework;slot-id=2 -+ -+ To find suitable URI please check the debug output -+ of p11_child. As an alternative the GnuTLS utility -+ 'p11tool' with e.g. the '--list-all' will show -+ PKCS#11 URIs as well. -+ -+ -+ Default: none -+ -+ -+ - - - -diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h -index 5d877566fc7bacced4f6385f1eae344a9e6d8bd4..60aa97967456b9b7ab35e64f103c1c9a17bef3a9 100644 ---- a/src/responder/pam/pamsrv.h -+++ b/src/responder/pam/pamsrv.h -@@ -103,6 +103,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - time_t timeout, - const char *verify_opts, - struct sss_certmap_ctx *sss_certmap_ctx, -+ const char *uri, - struct pam_data *pd); - errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct cert_auth_info **cert_list); -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index 6e37f831602e4c367176cc14126dbbec72c858cd..a22afd225894872847a0fb13e202f927fd2ae124 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -1306,6 +1306,7 @@ static errno_t check_cert(TALLOC_CTX *mctx, - char *cert_verification_opts; - errno_t ret; - struct tevent_req *req; -+ char *uri = NULL; - - ret = confdb_get_int(pctx->rctx->cdb, CONFDB_PAM_CONF_ENTRY, - CONFDB_PAM_P11_CHILD_TIMEOUT, -@@ -1342,10 +1343,19 @@ static errno_t check_cert(TALLOC_CTX *mctx, - return ret; - } - -+ ret = confdb_get_string(pctx->rctx->cdb, mctx, CONFDB_PAM_CONF_ENTRY, -+ CONFDB_PAM_P11_URI, NULL, &uri); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to read certificate_verification from confdb: [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ return ret; -+ } -+ - req = pam_check_cert_send(mctx, ev, pctx->p11_child_debug_fd, - pctx->nss_db, p11_child_timeout, - cert_verification_opts, pctx->sss_certmap_ctx, -- pd); -+ uri, pd); - if (req == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "pam_check_cert_send failed.\n"); - return ENOMEM; -diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c -index 8b8859d9d335aec6d310201256522fa8afdd3694..491bd2b01d7bf9137b37c35f9da9eca1eed95a6d 100644 ---- a/src/responder/pam/pamsrv_p11.c -+++ b/src/responder/pam/pamsrv_p11.c -@@ -711,6 +711,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - time_t timeout, - const char *verify_opts, - struct sss_certmap_ctx *sss_certmap_ctx, -+ const char *uri, - struct pam_data *pd) - { - errno_t ret; -@@ -721,7 +722,7 @@ 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[14] = { NULL }; -+ const char *extra_args[16] = { NULL }; - uint8_t *write_buf = NULL; - size_t write_buf_len = 0; - size_t arg_c; -@@ -748,6 +749,12 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - - /* extra_args are added in revers order */ - arg_c = 0; -+ if (uri != NULL) { -+ DEBUG(SSSDBG_TRACE_ALL, "Adding PKCS#11 URI [%s].\n", uri); -+ extra_args[arg_c++] = uri; -+ extra_args[arg_c++] = "--uri"; -+ } -+ - if ((pd->cli_flags & PAM_CLI_FLAGS_REQUIRE_CERT_AUTH) && pd->priv == 1) { - extra_args[arg_c++] = "--wait_for_card"; - } --- -2.14.4 - diff --git a/SOURCES/0046-BE-Introduce-flag-for-be_ptask_create.patch b/SOURCES/0046-BE-Introduce-flag-for-be_ptask_create.patch new file mode 100644 index 0000000..ae2b940 --- /dev/null +++ b/SOURCES/0046-BE-Introduce-flag-for-be_ptask_create.patch @@ -0,0 +1,536 @@ +From c5a0909216c406ce3e23d6f41146daf2bb303226 Mon Sep 17 00:00:00 2001 +From: Tomas Halman +Date: Fri, 19 Jul 2019 13:05:44 +0200 +Subject: [PATCH 46/48] BE: Introduce flag for be_ptask_create +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The be_ptask_create has already too many parameters. Lets have flags +parameter to avoid future extending. + +Reviewed-by: Pavel Březina +--- + src/providers/ad/ad_dyndns.c | 2 +- + src/providers/ad/ad_machine_pw_renewal.c | 2 +- + src/providers/ad/ad_subdomains.c | 2 +- + src/providers/be_ptask.c | 17 +++++- + src/providers/be_ptask.h | 10 ++++ + src/providers/be_ptask_private.h | 1 + + src/providers/be_refresh.c | 2 +- + src/providers/data_provider_be.c | 2 +- + src/providers/ipa/ipa_dyndns.c | 2 +- + src/providers/ipa/ipa_subdomains.c | 2 +- + src/providers/ldap/ldap_id_cleanup.c | 2 +- + src/providers/ldap/ldap_id_enum.c | 2 +- + src/providers/ldap/sdap_sudo_shared.c | 4 +- + src/tests/cmocka/test_be_ptask.c | 67 +++++++++++++++--------- + 14 files changed, 80 insertions(+), 37 deletions(-) + +diff --git a/src/providers/ad/ad_dyndns.c b/src/providers/ad/ad_dyndns.c +index 02ea7f24b..af765b581 100644 +--- a/src/providers/ad/ad_dyndns.c ++++ b/src/providers/ad/ad_dyndns.c +@@ -101,7 +101,7 @@ errno_t ad_dyndns_init(struct be_ctx *be_ctx, + ret = be_ptask_create(ad_opts, be_ctx, period, ptask_first_delay, 0, 0, period, + BE_PTASK_OFFLINE_DISABLE, BE_PTASK_SCHEDULE_FROM_LAST, 0, + ad_dyndns_update_send, ad_dyndns_update_recv, ad_opts, +- "Dyndns update", NULL); ++ "Dyndns update", 0, NULL); + + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup ptask " +diff --git a/src/providers/ad/ad_machine_pw_renewal.c b/src/providers/ad/ad_machine_pw_renewal.c +index 47941dfbf..67802c04a 100644 +--- a/src/providers/ad/ad_machine_pw_renewal.c ++++ b/src/providers/ad/ad_machine_pw_renewal.c +@@ -388,7 +388,7 @@ errno_t ad_machine_account_password_renewal_init(struct be_ctx *be_ctx, + ad_machine_account_password_renewal_send, + ad_machine_account_password_renewal_recv, + renewal_data, +- "AD machine account password renewal", NULL); ++ "AD machine account password renewal", 0, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "be_ptask_create failed.\n"); + goto done; +diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c +index 2510498da..0f46b46ad 100644 +--- a/src/providers/ad/ad_subdomains.c ++++ b/src/providers/ad/ad_subdomains.c +@@ -2070,7 +2070,7 @@ errno_t ad_subdomains_init(TALLOC_CTX *mem_ctx, + BE_PTASK_SCHEDULE_FROM_LAST, + 0, + ad_subdomains_ptask_send, ad_subdomains_ptask_recv, sd_ctx, +- "Subdomains Refresh", NULL); ++ "Subdomains Refresh", 0, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup ptask " + "[%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/providers/be_ptask.c b/src/providers/be_ptask.c +index 32d9a03ce..56c9c82fe 100644 +--- a/src/providers/be_ptask.c ++++ b/src/providers/be_ptask.c +@@ -208,6 +208,12 @@ static void be_ptask_schedule(struct be_ptask *task, + delay = task->enabled_delay; + break; + case BE_PTASK_PERIOD: ++ if (task->flags & BE_PTASK_NO_PERIODIC) { ++ /* Periodic task is disabled, */ ++ /* only online/offline change can cause some activity. */ ++ return; ++ } ++ + delay = task->period; + + if (backoff_allowed(task) && task->period * 2 <= task->max_backoff) { +@@ -269,16 +275,21 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + be_ptask_recv_t recv_fn, + void *pvt, + const char *name, ++ uint32_t flags, + struct be_ptask **_task) + { + struct be_ptask *task = NULL; + errno_t ret; + +- if (be_ctx == NULL || period == 0 || send_fn == NULL || recv_fn == NULL ++ if (be_ctx == NULL || send_fn == NULL || recv_fn == NULL + || name == NULL) { + return EINVAL; + } + ++ if (period == 0 && (flags & BE_PTASK_NO_PERIODIC) == 0) { ++ return EINVAL; ++ } ++ + task = talloc_zero(mem_ctx, struct be_ptask); + if (task == NULL) { + ret = ENOMEM; +@@ -306,6 +317,7 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + goto done; + } + ++ task->flags = flags; + task->enabled = true; + + talloc_set_destructor((TALLOC_CTX*)task, be_ptask_destructor); +@@ -451,6 +463,7 @@ errno_t be_ptask_create_sync(TALLOC_CTX *mem_ctx, + be_ptask_sync_t fn, + void *pvt, + const char *name, ++ uint32_t flags, + struct be_ptask **_task) + { + errno_t ret; +@@ -469,7 +482,7 @@ errno_t be_ptask_create_sync(TALLOC_CTX *mem_ctx, + enabled_delay, random_offset, timeout, offline, + BE_PTASK_SCHEDULE_FROM_LAST, + max_backoff, be_ptask_sync_send, be_ptask_sync_recv, +- ctx, name, _task); ++ ctx, name, flags, _task); + if (ret != EOK) { + goto done; + } +diff --git a/src/providers/be_ptask.h b/src/providers/be_ptask.h +index c23278e88..a33443965 100644 +--- a/src/providers/be_ptask.h ++++ b/src/providers/be_ptask.h +@@ -30,6 +30,14 @@ struct be_ctx; + + struct be_ptask; + ++/* be_ptask flags */ ++ ++/** ++ * Do not schedule periodic task. This flag is useful for tasks that ++ * should be performend only when there is offline/online change. ++ */ ++#define BE_PTASK_NO_PERIODIC 0x0001 ++ + /** + * Defines how should task behave when back end is offline. + */ +@@ -127,6 +135,7 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + be_ptask_recv_t recv_fn, + void *pvt, + const char *name, ++ uint32_t flags, + struct be_ptask **_task); + + errno_t be_ptask_create_sync(TALLOC_CTX *mem_ctx, +@@ -141,6 +150,7 @@ errno_t be_ptask_create_sync(TALLOC_CTX *mem_ctx, + be_ptask_sync_t fn, + void *pvt, + const char *name, ++ uint32_t flags, + struct be_ptask **_task); + + void be_ptask_enable(struct be_ptask *task); +diff --git a/src/providers/be_ptask_private.h b/src/providers/be_ptask_private.h +index e89105f95..496a2f9ae 100644 +--- a/src/providers/be_ptask_private.h ++++ b/src/providers/be_ptask_private.h +@@ -43,6 +43,7 @@ struct be_ptask { + time_t last_execution; /* last time when send was called */ + struct tevent_req *req; /* active tevent request */ + struct tevent_timer *timer; /* active tevent timer */ ++ uint32_t flags; + bool enabled; + }; + +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index 8f50e231d..687d3f022 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -177,7 +177,7 @@ static errno_t be_refresh_ctx_init(struct be_ctx *be_ctx, + BE_PTASK_SCHEDULE_FROM_NOW, + 0, + be_refresh_send, be_refresh_recv, +- ctx, "Refresh Records", NULL); ++ ctx, "Refresh Records", 0, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Unable to initialize refresh periodic task [%d]: %s\n", +diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c +index 877841055..f21669b8c 100644 +--- a/src/providers/data_provider_be.c ++++ b/src/providers/data_provider_be.c +@@ -133,7 +133,7 @@ void be_mark_offline(struct be_ctx *ctx) + BE_PTASK_OFFLINE_EXECUTE, + 3600 /* max_backoff */, + try_to_go_online, +- ctx, "Check if online (periodic)", ++ ctx, "Check if online (periodic)", 0, + &ctx->check_if_online_ptask); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, +diff --git a/src/providers/ipa/ipa_dyndns.c b/src/providers/ipa/ipa_dyndns.c +index 8e8ff5a4f..27852c2e2 100644 +--- a/src/providers/ipa/ipa_dyndns.c ++++ b/src/providers/ipa/ipa_dyndns.c +@@ -78,7 +78,7 @@ errno_t ipa_dyndns_init(struct be_ctx *be_ctx, + BE_PTASK_SCHEDULE_FROM_LAST, + 0, + ipa_dyndns_update_send, ipa_dyndns_update_recv, ctx, +- "Dyndns update", NULL); ++ "Dyndns update", 0, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup ptask " + "[%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c +index 3a17c851d..13e49c5c0 100644 +--- a/src/providers/ipa/ipa_subdomains.c ++++ b/src/providers/ipa/ipa_subdomains.c +@@ -3138,7 +3138,7 @@ errno_t ipa_subdomains_init(TALLOC_CTX *mem_ctx, + BE_PTASK_SCHEDULE_FROM_LAST, + 0, + ipa_subdomains_ptask_send, ipa_subdomains_ptask_recv, sd_ctx, +- "Subdomains Refresh", NULL); ++ "Subdomains Refresh", 0, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup ptask " + "[%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/providers/ldap/ldap_id_cleanup.c b/src/providers/ldap/ldap_id_cleanup.c +index e50fb0f22..df56f4da4 100644 +--- a/src/providers/ldap/ldap_id_cleanup.c ++++ b/src/providers/ldap/ldap_id_cleanup.c +@@ -88,7 +88,7 @@ errno_t ldap_setup_cleanup(struct sdap_id_ctx *id_ctx, + ret = be_ptask_create_sync(sdom, id_ctx->be, period, first_delay, + 5 /* enabled delay */, 0 /* random offset */, + period /* timeout */, BE_PTASK_OFFLINE_SKIP, 0, +- ldap_cleanup_task, cleanup_ctx, name, ++ ldap_cleanup_task, cleanup_ctx, name, 0, + &sdom->cleanup_task); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize cleanup periodic " +diff --git a/src/providers/ldap/ldap_id_enum.c b/src/providers/ldap/ldap_id_enum.c +index 062185c55..2137f6821 100644 +--- a/src/providers/ldap/ldap_id_enum.c ++++ b/src/providers/ldap/ldap_id_enum.c +@@ -102,7 +102,7 @@ errno_t ldap_setup_enumeration(struct be_ctx *be_ctx, + BE_PTASK_SCHEDULE_FROM_LAST, + 0, /* max_backoff */ + send_fn, recv_fn, +- ectx, "enumeration", &sdom->enum_task); ++ ectx, "enumeration", 0, &sdom->enum_task); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Unable to initialize enumeration periodic task\n"); +diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c +index a00d8e6a9..59356bd44 100644 +--- a/src/providers/ldap/sdap_sudo_shared.c ++++ b/src/providers/ldap/sdap_sudo_shared.c +@@ -94,7 +94,7 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx, + BE_PTASK_SCHEDULE_FROM_LAST, + 0, + full_send_fn, full_recv_fn, pvt, +- "SUDO Full Refresh", NULL); ++ "SUDO Full Refresh", 0, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup full refresh ptask " + "[%d]: %s\n", ret, sss_strerror(ret)); +@@ -113,7 +113,7 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx, + BE_PTASK_SCHEDULE_FROM_LAST, + 0, + smart_send_fn, smart_recv_fn, pvt, +- "SUDO Smart Refresh", NULL); ++ "SUDO Smart Refresh", 0, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup smart refresh ptask " + "[%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/tests/cmocka/test_be_ptask.c b/src/tests/cmocka/test_be_ptask.c +index 03b1165bb..ac8c0767f 100644 +--- a/src/tests/cmocka/test_be_ptask.c ++++ b/src/tests/cmocka/test_be_ptask.c +@@ -306,7 +306,7 @@ void test_be_ptask_create_einval_be(void **state) + ret = be_ptask_create(test_ctx, NULL, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, NULL, "Test ptask", &ptask); ++ test_be_ptask_recv, NULL, "Test ptask", 0, &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); + } +@@ -320,7 +320,7 @@ void test_be_ptask_create_einval_period(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, 0, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, NULL, "Test ptask", &ptask); ++ test_be_ptask_recv, NULL, "Test ptask", 0, &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); + } +@@ -334,7 +334,7 @@ void test_be_ptask_create_einval_send(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, NULL, +- test_be_ptask_recv, NULL, "Test ptask", &ptask); ++ test_be_ptask_recv, NULL, "Test ptask", 0, &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); + } +@@ -348,7 +348,7 @@ void test_be_ptask_create_einval_recv(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- NULL, NULL, "Test ptask", &ptask); ++ NULL, NULL, "Test ptask", 0, &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); + } +@@ -362,7 +362,7 @@ void test_be_ptask_create_einval_name(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, NULL, NULL, &ptask); ++ test_be_ptask_recv, NULL, NULL, 0, &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); + } +@@ -378,7 +378,7 @@ void test_be_ptask_create_no_delay(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -406,7 +406,7 @@ void test_be_ptask_create_first_delay(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, DELAY, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -432,7 +432,7 @@ void test_be_ptask_disable(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -457,7 +457,7 @@ void test_be_ptask_enable(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -490,7 +490,7 @@ void test_be_ptask_enable_delay(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, DELAY, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -530,7 +530,7 @@ void test_be_ptask_offline_skip(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -565,7 +565,7 @@ void test_be_ptask_offline_disable(void **state) + BE_PTASK_OFFLINE_DISABLE, + BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -597,7 +597,7 @@ void test_be_ptask_offline_execute(void **state) + BE_PTASK_OFFLINE_EXECUTE, + BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -625,7 +625,7 @@ void test_be_ptask_reschedule_ok(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -657,7 +657,7 @@ void test_be_ptask_reschedule_null(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_null_send, +- test_be_ptask_recv, test_ctx, "Test ptask", ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, + &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -685,7 +685,7 @@ void test_be_ptask_reschedule_error(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_error_recv, test_ctx, "Test ptask", ++ test_be_ptask_error_recv, test_ctx, "Test ptask", 0, + &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -713,7 +713,7 @@ void test_be_ptask_reschedule_timeout(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 1, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_timeout_send, +- test_be_ptask_error_recv, test_ctx, "Test ptask", ++ test_be_ptask_error_recv, test_ctx, "Test ptask", 0, + &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -751,7 +751,7 @@ void test_be_ptask_reschedule_backoff(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + PERIOD*2, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -806,7 +806,7 @@ void test_be_ptask_get_period(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + +@@ -827,7 +827,7 @@ void test_be_ptask_get_timeout(void **state) + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, TIMEOUT, + BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + +@@ -838,6 +838,24 @@ void test_be_ptask_get_timeout(void **state) + assert_null(ptask); + } + ++void test_be_ptask_no_periodic(void **state) ++{ ++ struct test_ctx *test_ctx = (struct test_ctx *)(*state); ++ struct be_ptask *ptask = NULL; ++ errno_t ret; ++ ++ ret = be_ptask_create(test_ctx, test_ctx->be_ctx, 0, 0, DELAY, 0, 0, ++ BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, ++ 0, test_be_ptask_send, ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_NO_PERIODIC, &ptask); ++ assert_int_equal(ret, ERR_OK); ++ assert_non_null(ptask); ++ ++ be_ptask_destroy(&ptask); ++ assert_null(ptask); ++} ++ + void test_be_ptask_create_sync(void **state) + { + struct test_ctx *test_ctx = (struct test_ctx *)(*state); +@@ -848,7 +866,7 @@ void test_be_ptask_create_sync(void **state) + now = get_current_time(); + ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_sync, +- test_ctx, "Test ptask", &ptask); ++ test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -876,7 +894,7 @@ void test_be_ptask_sync_reschedule_ok(void **state) + now = get_current_time(); + ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_sync, +- test_ctx, "Test ptask", &ptask); ++ test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -908,7 +926,7 @@ void test_be_ptask_sync_reschedule_error(void **state) + ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, 0, + test_be_ptask_sync_error, +- test_ctx, "Test ptask", &ptask); ++ test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -938,7 +956,7 @@ void test_be_ptask_sync_reschedule_backoff(void **state) + ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, + BE_PTASK_OFFLINE_SKIP, PERIOD*2, + test_be_ptask_sync_error, +- test_ctx, "Test ptask", &ptask); ++ test_ctx, "Test ptask", 0, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -1014,6 +1032,7 @@ int main(int argc, const char *argv[]) + new_test(be_ptask_reschedule_backoff), + new_test(be_ptask_get_period), + new_test(be_ptask_get_timeout), ++ new_test(be_ptask_no_periodic), + new_test(be_ptask_create_sync), + new_test(be_ptask_sync_reschedule_ok), + new_test(be_ptask_sync_reschedule_error), +-- +2.20.1 + diff --git a/SOURCES/0046-tests-add-PKCS-11-URI-tests.patch b/SOURCES/0046-tests-add-PKCS-11-URI-tests.patch deleted file mode 100644 index a63bb54..0000000 --- a/SOURCES/0046-tests-add-PKCS-11-URI-tests.patch +++ /dev/null @@ -1,210 +0,0 @@ -From b2a979e5e66f463d9567165fa7a46a39a9e6ae18 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 9 Oct 2018 10:46:43 +0200 -Subject: [PATCH 46/47] tests: add PKCS#11 URI tests - -Related to https://pagure.io/SSSD/sssd/issue/3814 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 4a22fb6bba6662ad628f6e17203e8ccf20eb9666) ---- - src/tests/cmocka/test_pam_srv.c | 120 ++++++++++++++++++++++++++++++++++++++++ - src/tests/test_CA/Makefile.am | 16 +++++- - 2 files changed, 135 insertions(+), 1 deletion(-) - -diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c -index 2b02ac27b7356c5bce9e11dae785ecdbddd31aa3..7fc9224e152b8c206faf5d0cd9b6778099c6605c 100644 ---- a/src/tests/cmocka/test_pam_srv.c -+++ b/src/tests/cmocka/test_pam_srv.c -@@ -65,6 +65,7 @@ - #endif - - #define TEST_TOKEN_NAME "SSSD Test Token" -+#define TEST_TOKEN2_NAME "SSSD Test Token Number 2" - #define TEST_KEY_ID "C554C9F82C2A9D58B70921C143304153A8A42F17" - #ifdef HAVE_NSS - #define TEST_MODULE_NAME "NSS-Internal" -@@ -961,6 +962,54 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - return EOK; - } - -+static int test_pam_cert2_token2_check_ex(uint32_t status, uint8_t *body, -+ size_t blen, enum response_type type, -+ const char *name) -+{ -+ size_t rp = 0; -+ uint32_t val; -+ size_t check2_len = 0; -+ char const *check2_strings[] = { NULL, -+ TEST_TOKEN2_NAME, -+ TEST_MODULE_NAME, -+ TEST2_KEY_ID, -+ TEST2_PROMPT, -+ NULL }; -+ -+ assert_int_equal(status, 0); -+ -+ check2_strings[0] = name; -+ check2_len = check_string_array_len(check2_strings); -+ -+ SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); -+ assert_int_equal(val, pam_test_ctx->exp_pam_status); -+ -+ SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); -+ assert_int_equal(val, 2); -+ -+ SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); -+ assert_int_equal(val, SSS_PAM_DOMAIN_NAME); -+ -+ SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); -+ assert_int_equal(val, 9); -+ -+ assert_int_equal(*(body + rp + val - 1), 0); -+ assert_string_equal(body + rp, TEST_DOM_NAME); -+ rp += val; -+ -+ SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); -+ assert_int_equal(val, type); -+ -+ SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); -+ assert_int_equal(val, check2_len); -+ -+ check_string_array(check2_strings, body, &rp); -+ -+ assert_int_equal(rp, blen); -+ -+ return EOK; -+} -+ - static int test_pam_cert_check(uint32_t status, uint8_t *body, size_t blen) - { - return test_pam_cert_check_ex(status, body, blen, -@@ -968,6 +1017,12 @@ static int test_pam_cert_check(uint32_t status, uint8_t *body, size_t blen) - NULL); - } - -+static int test_pam_cert2_check(uint32_t status, uint8_t *body, size_t blen) -+{ -+ return test_pam_cert2_token2_check_ex(status, body, blen, SSS_PAM_CERT_INFO, -+ "pamuser@"TEST_DOM_NAME); -+} -+ - static int test_pam_cert_check_auth_success(uint32_t status, uint8_t *body, - size_t blen) - { -@@ -2476,6 +2531,65 @@ void test_pam_cert_auth_2certs_one_mapping(void **state) - assert_int_equal(ret, EOK); - } - -+void test_pam_cert_preauth_uri_token1(void **state) -+{ -+ int ret; -+ -+ struct sss_test_conf_param pam_params[] = { -+ { CONFDB_PAM_P11_URI, "pkcs11:token=SSSD%20Test%20Token" }, -+ { NULL, NULL }, /* Sentinel */ -+ }; -+ -+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); -+ assert_int_equal(ret, EOK); -+ set_cert_auth_param(pam_test_ctx->pctx, CA_DB); -+ putenv(discard_const("SOFTHSM2_CONF=" ABS_BUILD_DIR "/src/tests/test_CA/softhsm2_2tokens.conf")); -+ -+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL, -+ test_lookup_by_cert_cb, SSSD_TEST_CERT_0001, false); -+ -+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ -+ set_cmd_cb(test_pam_cert_check); -+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH, -+ 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_preauth_uri_token2(void **state) -+{ -+ int ret; -+ -+ struct sss_test_conf_param pam_params[] = { -+ { CONFDB_PAM_P11_URI, "pkcs11:token=SSSD%20Test%20Token%20Number%202" }, -+ { NULL, NULL }, /* Sentinel */ -+ }; -+ -+ ret = add_pam_params(pam_params, pam_test_ctx->rctx->cdb); -+ assert_int_equal(ret, EOK); -+ set_cert_auth_param(pam_test_ctx->pctx, CA_DB); -+ putenv(discard_const("SOFTHSM2_CONF=" ABS_BUILD_DIR "/src/tests/test_CA/softhsm2_2tokens.conf")); -+ -+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL, -+ test_lookup_by_cert_cb, SSSD_TEST_CERT_0002, false); -+ -+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ -+ set_cmd_cb(test_pam_cert2_check); -+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_PREAUTH, -+ 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_filter_response(void **state) - { -@@ -2915,6 +3029,12 @@ int main(int argc, const char *argv[]) - 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), -+#ifndef HAVE_NSS -+ cmocka_unit_test_setup_teardown(test_pam_cert_preauth_uri_token1, -+ pam_test_setup, pam_test_teardown), -+ cmocka_unit_test_setup_teardown(test_pam_cert_preauth_uri_token2, -+ pam_test_setup, pam_test_teardown), -+#endif /* ! HAVE_NSS */ - #endif /* HAVE_TEST_CA */ - - cmocka_unit_test_setup_teardown(test_filter_response, -diff --git a/src/tests/test_CA/Makefile.am b/src/tests/test_CA/Makefile.am -index 1bce2c36633b2d1df65c29258f8ee163a4bfce9e..b574c76111560ba3fce453254e74c267fc680681 100644 ---- a/src/tests/test_CA/Makefile.am -+++ b/src/tests/test_CA/Makefile.am -@@ -24,7 +24,7 @@ pkcs12 = $(addprefix SSSD_test_cert_pkcs12_,$(addsuffix .pem,$(ids))) - if HAVE_NSS - extra = p11_nssdb p11_nssdb_2certs - else --extra = softhsm2_none softhsm2_one softhsm2_two -+extra = softhsm2_none softhsm2_one softhsm2_two softhsm2_2tokens - endif - - # If openssl is run in parallel there might be conflicts with the serial -@@ -114,6 +114,20 @@ softhsm2_two.conf: - @echo "objectstore.backend = file" >> $@ - @echo "slots.removable = true" >> $@ - -+softhsm2_2tokens: softhsm2_2tokens.conf -+ mkdir $@ -+ SOFTHSM2_CONF=./$< $(SOFTHSM2_UTIL) --init-token --label "SSSD Test Token" --pin 123456 --so-pin 123456 --free -+ GNUTLS_PIN=123456 SOFTHSM2_CONF=./$< $(P11TOOL) --provider=$(SOFTHSM2_PATH) --write --no-mark-private --load-certificate=SSSD_test_cert_x509_0001.pem --login --label 'SSSD test cert 0001' --id 'C554C9F82C2A9D58B70921C143304153A8A42F17' pkcs11:token=SSSD%20Test%20Token -+ GNUTLS_PIN=123456 SOFTHSM2_CONF=./$< $(P11TOOL) --provider=$(SOFTHSM2_PATH) --write --load-privkey=$(srcdir)/SSSD_test_cert_key_0001.pem --login --label 'SSSD test cert 0001' --id 'C554C9F82C2A9D58B70921C143304153A8A42F17' pkcs11:token=SSSD%20Test%20Token -+ SOFTHSM2_CONF=./$< $(SOFTHSM2_UTIL) --init-token --label "SSSD Test Token Number 2" --pin 654321 --so-pin 654321 --free -+ GNUTLS_PIN=654321 SOFTHSM2_CONF=./$< $(P11TOOL) --provider=$(SOFTHSM2_PATH) --write --no-mark-private --load-certificate=SSSD_test_cert_x509_0002.pem --login --label 'SSSD test cert 0002' --id '5405842D56CF31F0BB025A695C5F3E907051C5B9' pkcs11:token=SSSD%20Test%20Token%20Number%202 -+ GNUTLS_PIN=654321 SOFTHSM2_CONF=./$< $(P11TOOL) --provider=$(SOFTHSM2_PATH) --write --load-privkey=$(srcdir)/SSSD_test_cert_key_0002.pem --login --label 'SSSD test cert 0002' --id '5405842D56CF31F0BB025A695C5F3E907051C5B9' pkcs11:token=SSSD%20Test%20Token%20Number%202 -+ -+softhsm2_2tokens.conf: -+ @echo "directories.tokendir = "$(abs_top_builddir)"/src/tests/test_CA/softhsm2_2tokens" > $@ -+ @echo "objectstore.backend = file" >> $@ -+ @echo "slots.removable = true" >> $@ -+ - CLEANFILES = \ - index.txt index.txt.attr \ - index.txt.attr.old index.txt.old \ --- -2.14.4 - diff --git a/SOURCES/0047-BE-Convert-be_ptask-params-to-flags.patch b/SOURCES/0047-BE-Convert-be_ptask-params-to-flags.patch new file mode 100644 index 0000000..af30e21 --- /dev/null +++ b/SOURCES/0047-BE-Convert-be_ptask-params-to-flags.patch @@ -0,0 +1,916 @@ +From f5ef6aa9965fec34c8de9fe2635b0e5c5b8a0ab9 Mon Sep 17 00:00:00 2001 +From: Tomas Halman +Date: Fri, 19 Jul 2019 15:59:32 +0200 +Subject: [PATCH 47/48] BE: Convert be_ptask params to flags +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The be_ptask_create call has a lot of parameters. +Some of them can be converted to flags to simplify +the declaration. + +Reviewed-by: Pavel Březina +--- + src/providers/ad/ad_dyndns.c | 9 +- + src/providers/ad/ad_machine_pw_renewal.c | 10 +- + src/providers/ad/ad_subdomains.c | 11 +- + src/providers/be_ptask.c | 74 ++++++--- + src/providers/be_ptask.h | 39 ++--- + src/providers/be_ptask_private.h | 2 - + src/providers/be_refresh.c | 9 +- + src/providers/data_provider_be.c | 4 +- + src/providers/ipa/ipa_dyndns.c | 7 +- + src/providers/ipa/ipa_subdomains.c | 7 +- + src/providers/ldap/ldap_id_cleanup.c | 5 +- + src/providers/ldap/ldap_id_enum.c | 6 +- + src/providers/ldap/sdap_sudo_shared.c | 16 +- + src/tests/cmocka/test_be_ptask.c | 194 ++++++++++++++++------- + 14 files changed, 251 insertions(+), 142 deletions(-) + +diff --git a/src/providers/ad/ad_dyndns.c b/src/providers/ad/ad_dyndns.c +index af765b581..c9763d449 100644 +--- a/src/providers/ad/ad_dyndns.c ++++ b/src/providers/ad/ad_dyndns.c +@@ -98,10 +98,13 @@ errno_t ad_dyndns_init(struct be_ctx *be_ctx, + return EINVAL; + } + +- ret = be_ptask_create(ad_opts, be_ctx, period, ptask_first_delay, 0, 0, period, +- BE_PTASK_OFFLINE_DISABLE, BE_PTASK_SCHEDULE_FROM_LAST, 0, ++ ret = be_ptask_create(ad_opts, be_ctx, period, ptask_first_delay, 0, 0, ++ period, 0, + ad_dyndns_update_send, ad_dyndns_update_recv, ad_opts, +- "Dyndns update", 0, NULL); ++ "Dyndns update", ++ BE_PTASK_OFFLINE_DISABLE | ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ NULL); + + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup ptask " +diff --git a/src/providers/ad/ad_machine_pw_renewal.c b/src/providers/ad/ad_machine_pw_renewal.c +index 67802c04a..9dc36247a 100644 +--- a/src/providers/ad/ad_machine_pw_renewal.c ++++ b/src/providers/ad/ad_machine_pw_renewal.c +@@ -381,14 +381,14 @@ errno_t ad_machine_account_password_renewal_init(struct be_ctx *be_ctx, + goto done; + } + +- ret = be_ptask_create(be_ctx, be_ctx, period, initial_delay, 0, 0, 60, +- BE_PTASK_OFFLINE_DISABLE, +- BE_PTASK_SCHEDULE_FROM_LAST, +- 0, ++ ret = be_ptask_create(be_ctx, be_ctx, period, initial_delay, 0, 0, 60, 0, + ad_machine_account_password_renewal_send, + ad_machine_account_password_renewal_recv, + renewal_data, +- "AD machine account password renewal", 0, NULL); ++ "AD machine account password renewal", ++ BE_PTASK_OFFLINE_DISABLE | ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ NULL); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "be_ptask_create failed.\n"); + goto done; +diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c +index 0f46b46ad..d934e70d6 100644 +--- a/src/providers/ad/ad_subdomains.c ++++ b/src/providers/ad/ad_subdomains.c +@@ -2065,12 +2065,13 @@ errno_t ad_subdomains_init(TALLOC_CTX *mem_ctx, + struct ad_subdomains_ctx, struct dp_subdomains_data, struct dp_reply_std); + + period = be_ctx->domain->subdomain_refresh_interval; +- ret = be_ptask_create(sd_ctx, be_ctx, period, 0, 0, 0, period, +- BE_PTASK_OFFLINE_DISABLE, ++ ret = be_ptask_create(sd_ctx, be_ctx, period, 0, 0, 0, period, 0, ++ ad_subdomains_ptask_send, ad_subdomains_ptask_recv, ++ sd_ctx, ++ "Subdomains Refresh", ++ BE_PTASK_OFFLINE_DISABLE | + BE_PTASK_SCHEDULE_FROM_LAST, +- 0, +- ad_subdomains_ptask_send, ad_subdomains_ptask_recv, sd_ctx, +- "Subdomains Refresh", 0, NULL); ++ NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup ptask " + "[%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/providers/be_ptask.c b/src/providers/be_ptask.c +index 56c9c82fe..9a432c948 100644 +--- a/src/providers/be_ptask.c ++++ b/src/providers/be_ptask.c +@@ -38,7 +38,7 @@ enum be_ptask_delay { + + static void be_ptask_schedule(struct be_ptask *task, + enum be_ptask_delay delay_type, +- enum be_ptask_schedule from); ++ uint32_t from); + + static int be_ptask_destructor(void *pvt) + { +@@ -107,21 +107,20 @@ static void be_ptask_execute(struct tevent_context *ev, + + if (be_is_offline(task->be_ctx)) { + DEBUG(SSSDBG_TRACE_FUNC, "Back end is offline\n"); +- switch (task->offline) { +- case BE_PTASK_OFFLINE_SKIP: ++ if (task->flags & BE_PTASK_OFFLINE_SKIP) { + be_ptask_schedule(task, BE_PTASK_PERIOD, + BE_PTASK_SCHEDULE_FROM_NOW); + return; +- case BE_PTASK_OFFLINE_DISABLE: ++ } ++ else if(task->flags & BE_PTASK_OFFLINE_DISABLE) { + /* This case is normally handled by offline callback but we + * should handle it here as well since we can get here in some + * special cases for example unit tests or tevent events order. */ + be_ptask_disable(task); + return; +- case BE_PTASK_OFFLINE_EXECUTE: +- /* continue */ +- break; + } ++ /* BE_PTASK_OFFLINE_EXECUTE */ ++ /* continue */ + } + + DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: executing task, timeout %lu " +@@ -177,7 +176,7 @@ static void be_ptask_done(struct tevent_req *req) + DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: finished successfully\n", + task->name); + +- be_ptask_schedule(task, BE_PTASK_PERIOD, task->success_schedule_type); ++ be_ptask_schedule(task, BE_PTASK_PERIOD, task->flags); + break; + default: + DEBUG(SSSDBG_OP_FAILURE, "Task [%s]: failed with [%d]: %s\n", +@@ -190,7 +189,7 @@ static void be_ptask_done(struct tevent_req *req) + + static void be_ptask_schedule(struct be_ptask *task, + enum be_ptask_delay delay_type, +- enum be_ptask_schedule from) ++ uint32_t from) + { + struct timeval tv = { 0, }; + time_t delay = 0; +@@ -228,20 +227,18 @@ static void be_ptask_schedule(struct be_ptask *task, + delay = delay + (rand_r(&task->ro_seed) % task->random_offset); + } + +- switch (from) { +- case BE_PTASK_SCHEDULE_FROM_NOW: ++ if(from | BE_PTASK_SCHEDULE_FROM_NOW) { + tv = tevent_timeval_current_ofs(delay, 0); + + DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: scheduling task %lu seconds " + "from now [%lu]\n", task->name, delay, tv.tv_sec); +- break; +- case BE_PTASK_SCHEDULE_FROM_LAST: ++ } ++ else if (from | BE_PTASK_SCHEDULE_FROM_LAST) { + tv = tevent_timeval_set(task->last_execution + delay, 0); + + DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: scheduling task %lu seconds " + "from last execution time [%lu]\n", + task->name, delay, tv.tv_sec); +- break; + } + + if (task->timer != NULL) { +@@ -261,6 +258,36 @@ static void be_ptask_schedule(struct be_ptask *task, + task->next_execution = tv.tv_sec; + } + ++static unsigned int be_ptask_flag_bits(uint32_t flags) ++{ ++ unsigned int cnt = 0; ++ while (flags != 0) { ++ cnt += flags & 1; ++ flags >>= 1; ++ } ++ return cnt; ++} ++ ++static int be_ptask_flag_check(uint32_t flags) ++{ ++ uint32_t tmpflags; ++ ++ tmpflags = flags & (BE_PTASK_SCHEDULE_FROM_LAST | ++ BE_PTASK_SCHEDULE_FROM_NOW); ++ if (be_ptask_flag_bits(tmpflags) != 1) { ++ return EINVAL; ++ } ++ ++ tmpflags = flags & (BE_PTASK_OFFLINE_SKIP | ++ BE_PTASK_OFFLINE_DISABLE | ++ BE_PTASK_OFFLINE_EXECUTE); ++ if (be_ptask_flag_bits(tmpflags) != 1) { ++ return EINVAL; ++ } ++ ++ return EOK; ++} ++ + errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + struct be_ctx *be_ctx, + time_t period, +@@ -268,8 +295,6 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + time_t enabled_delay, + time_t random_offset, + time_t timeout, +- enum be_ptask_offline offline, +- enum be_ptask_schedule success_schedule_type, + time_t max_backoff, + be_ptask_send_t send_fn, + be_ptask_recv_t recv_fn, +@@ -290,6 +315,12 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + return EINVAL; + } + ++ /* check flags, some of them are exclusive, some must be present */ ++ ret = be_ptask_flag_check(flags); ++ if (ret != EOK) { ++ return ret; ++ } ++ + task = talloc_zero(mem_ctx, struct be_ptask); + if (task == NULL) { + ret = ENOMEM; +@@ -306,8 +337,6 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + task->ro_seed = time(NULL) * getpid(); + task->max_backoff = max_backoff; + task->timeout = timeout; +- task->offline = offline; +- task->success_schedule_type = success_schedule_type; + task->send_fn = send_fn; + task->recv_fn = recv_fn; + task->pvt = pvt; +@@ -322,7 +351,7 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + + talloc_set_destructor((TALLOC_CTX*)task, be_ptask_destructor); + +- if (offline == BE_PTASK_OFFLINE_DISABLE) { ++ if (flags & BE_PTASK_OFFLINE_DISABLE) { + /* install offline and online callbacks */ + ret = be_add_online_cb(task, be_ctx, be_ptask_online_cb, task, NULL); + if (ret != EOK) { +@@ -458,7 +487,6 @@ errno_t be_ptask_create_sync(TALLOC_CTX *mem_ctx, + time_t enabled_delay, + time_t random_offset, + time_t timeout, +- enum be_ptask_offline offline, + time_t max_backoff, + be_ptask_sync_t fn, + void *pvt, +@@ -479,10 +507,10 @@ errno_t be_ptask_create_sync(TALLOC_CTX *mem_ctx, + ctx->pvt = pvt; + + ret = be_ptask_create(mem_ctx, be_ctx, period, first_delay, +- enabled_delay, random_offset, timeout, offline, +- BE_PTASK_SCHEDULE_FROM_LAST, ++ enabled_delay, random_offset, timeout, + max_backoff, be_ptask_sync_send, be_ptask_sync_recv, +- ctx, name, flags, _task); ++ ctx, name, flags | BE_PTASK_SCHEDULE_FROM_LAST, ++ _task); + if (ret != EOK) { + goto done; + } +diff --git a/src/providers/be_ptask.h b/src/providers/be_ptask.h +index a33443965..640c8570a 100644 +--- a/src/providers/be_ptask.h ++++ b/src/providers/be_ptask.h +@@ -39,33 +39,23 @@ struct be_ptask; + #define BE_PTASK_NO_PERIODIC 0x0001 + + /** +- * Defines how should task behave when back end is offline. ++ * Flags defining the starting point for scheduling a task + */ +-enum be_ptask_offline { +- /* current request will be skipped and rescheduled to 'now + period' */ +- BE_PTASK_OFFLINE_SKIP, +- +- /* An offline and online callback is registered. The task is disabled +- * immediately when back end goes offline and then enabled again +- * when back end goes back online */ +- BE_PTASK_OFFLINE_DISABLE, +- +- /* current request will be executed as planned */ +- BE_PTASK_OFFLINE_EXECUTE +-}; ++/* Schedule starting from now, typically this is used when scheduling ++ * relative to the finish time */ ++#define BE_PTASK_SCHEDULE_FROM_NOW 0x0002 ++/* Schedule relative to the start time of the task */ ++#define BE_PTASK_SCHEDULE_FROM_LAST 0x0004 + + /** +- * Defines the starting point for scheduling a task ++ * Flags defining how should task behave when back end is offline. + */ +-enum be_ptask_schedule { +- /* Schedule starting from now, typically this is used when scheduling +- * relative to the finish time +- */ +- BE_PTASK_SCHEDULE_FROM_NOW, +- /* Schedule relative to the start time of the task +- */ +- BE_PTASK_SCHEDULE_FROM_LAST +-}; ++/* current request will be skipped and rescheduled to 'now + period' */ ++#define BE_PTASK_OFFLINE_SKIP 0x0008 ++/* An offline and online callback is registered. The task is disabled */ ++#define BE_PTASK_OFFLINE_DISABLE 0x0010 ++/* current request will be executed as planned */ ++#define BE_PTASK_OFFLINE_EXECUTE 0x0020 + + typedef struct tevent_req * + (*be_ptask_send_t)(TALLOC_CTX *mem_ctx, +@@ -128,8 +118,6 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx, + time_t enabled_delay, + time_t random_offset, + time_t timeout, +- enum be_ptask_offline offline, +- enum be_ptask_schedule success_schedule_type, + time_t max_backoff, + be_ptask_send_t send_fn, + be_ptask_recv_t recv_fn, +@@ -145,7 +133,6 @@ errno_t be_ptask_create_sync(TALLOC_CTX *mem_ctx, + time_t enabled_delay, + time_t random_offset, + time_t timeout, +- enum be_ptask_offline offline, + time_t max_backoff, + be_ptask_sync_t fn, + void *pvt, +diff --git a/src/providers/be_ptask_private.h b/src/providers/be_ptask_private.h +index 496a2f9ae..f3e5beec7 100644 +--- a/src/providers/be_ptask_private.h ++++ b/src/providers/be_ptask_private.h +@@ -31,8 +31,6 @@ struct be_ptask { + unsigned int ro_seed; + time_t timeout; + time_t max_backoff; +- enum be_ptask_offline offline; +- enum be_ptask_schedule success_schedule_type; + be_ptask_send_t send_fn; + be_ptask_recv_t recv_fn; + void *pvt; +diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c +index 687d3f022..6cce38390 100644 +--- a/src/providers/be_refresh.c ++++ b/src/providers/be_refresh.c +@@ -173,11 +173,12 @@ static errno_t be_refresh_ctx_init(struct be_ctx *be_ctx, + refresh_interval = be_ctx->domain->refresh_expired_interval; + if (refresh_interval > 0) { + ret = be_ptask_create(be_ctx, be_ctx, refresh_interval, 30, 5, 0, +- refresh_interval, BE_PTASK_OFFLINE_SKIP, +- BE_PTASK_SCHEDULE_FROM_NOW, +- 0, ++ refresh_interval, 0, + be_refresh_send, be_refresh_recv, +- ctx, "Refresh Records", 0, NULL); ++ ctx, "Refresh Records", ++ BE_PTASK_OFFLINE_SKIP | ++ BE_PTASK_SCHEDULE_FROM_NOW, ++ NULL); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Unable to initialize refresh periodic task [%d]: %s\n", +diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c +index f21669b8c..ce00231ff 100644 +--- a/src/providers/data_provider_be.c ++++ b/src/providers/data_provider_be.c +@@ -130,10 +130,10 @@ void be_mark_offline(struct be_ctx *ctx) + ret = be_ptask_create_sync(ctx, ctx, + offline_timeout, offline_timeout, + offline_timeout, 30, offline_timeout, +- BE_PTASK_OFFLINE_EXECUTE, + 3600 /* max_backoff */, + try_to_go_online, +- ctx, "Check if online (periodic)", 0, ++ ctx, "Check if online (periodic)", ++ BE_PTASK_OFFLINE_EXECUTE, + &ctx->check_if_online_ptask); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, +diff --git a/src/providers/ipa/ipa_dyndns.c b/src/providers/ipa/ipa_dyndns.c +index 27852c2e2..f8831287a 100644 +--- a/src/providers/ipa/ipa_dyndns.c ++++ b/src/providers/ipa/ipa_dyndns.c +@@ -74,11 +74,12 @@ errno_t ipa_dyndns_init(struct be_ctx *be_ctx, + } + + ret = be_ptask_create(ctx, be_ctx, period, ptask_first_delay, 0, 0, period, +- BE_PTASK_OFFLINE_DISABLE, +- BE_PTASK_SCHEDULE_FROM_LAST, + 0, + ipa_dyndns_update_send, ipa_dyndns_update_recv, ctx, +- "Dyndns update", 0, NULL); ++ "Dyndns update", ++ BE_PTASK_OFFLINE_DISABLE | ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup ptask " + "[%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c +index 13e49c5c0..d000f1230 100644 +--- a/src/providers/ipa/ipa_subdomains.c ++++ b/src/providers/ipa/ipa_subdomains.c +@@ -3134,11 +3134,12 @@ errno_t ipa_subdomains_init(TALLOC_CTX *mem_ctx, + + period = be_ctx->domain->subdomain_refresh_interval; + ret = be_ptask_create(sd_ctx, be_ctx, period, ptask_first_delay, 0, 0, period, +- BE_PTASK_OFFLINE_DISABLE, +- BE_PTASK_SCHEDULE_FROM_LAST, + 0, + ipa_subdomains_ptask_send, ipa_subdomains_ptask_recv, sd_ctx, +- "Subdomains Refresh", 0, NULL); ++ "Subdomains Refresh", ++ BE_PTASK_OFFLINE_DISABLE | ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup ptask " + "[%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/providers/ldap/ldap_id_cleanup.c b/src/providers/ldap/ldap_id_cleanup.c +index df56f4da4..a62060337 100644 +--- a/src/providers/ldap/ldap_id_cleanup.c ++++ b/src/providers/ldap/ldap_id_cleanup.c +@@ -87,8 +87,9 @@ errno_t ldap_setup_cleanup(struct sdap_id_ctx *id_ctx, + + ret = be_ptask_create_sync(sdom, id_ctx->be, period, first_delay, + 5 /* enabled delay */, 0 /* random offset */, +- period /* timeout */, BE_PTASK_OFFLINE_SKIP, 0, +- ldap_cleanup_task, cleanup_ctx, name, 0, ++ period /* timeout */, 0, ++ ldap_cleanup_task, cleanup_ctx, name, ++ BE_PTASK_OFFLINE_SKIP, + &sdom->cleanup_task); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize cleanup periodic " +diff --git a/src/providers/ldap/ldap_id_enum.c b/src/providers/ldap/ldap_id_enum.c +index 2137f6821..009d9d275 100644 +--- a/src/providers/ldap/ldap_id_enum.c ++++ b/src/providers/ldap/ldap_id_enum.c +@@ -98,11 +98,11 @@ errno_t ldap_setup_enumeration(struct be_ctx *be_ctx, + 5, /* enabled delay */ + 0, /* random offset */ + period, /* timeout */ +- BE_PTASK_OFFLINE_SKIP, +- BE_PTASK_SCHEDULE_FROM_LAST, + 0, /* max_backoff */ + send_fn, recv_fn, +- ectx, "enumeration", 0, &sdom->enum_task); ++ ectx, "enumeration", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &sdom->enum_task); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Unable to initialize enumeration periodic task\n"); +diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c +index 59356bd44..062a95ab6 100644 +--- a/src/providers/ldap/sdap_sudo_shared.c ++++ b/src/providers/ldap/sdap_sudo_shared.c +@@ -90,11 +90,12 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx, + * when offline. */ + if (full > 0) { + ret = be_ptask_create(be_ctx, be_ctx, full, delay, 0, 0, full, +- BE_PTASK_OFFLINE_DISABLE, +- BE_PTASK_SCHEDULE_FROM_LAST, + 0, + full_send_fn, full_recv_fn, pvt, +- "SUDO Full Refresh", 0, NULL); ++ "SUDO Full Refresh", ++ BE_PTASK_OFFLINE_DISABLE | ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup full refresh ptask " + "[%d]: %s\n", ret, sss_strerror(ret)); +@@ -109,11 +110,12 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx, + * when offline. */ + if (smart > 0) { + ret = be_ptask_create(be_ctx, be_ctx, smart, delay + smart, smart, 0, +- smart, BE_PTASK_OFFLINE_DISABLE, +- BE_PTASK_SCHEDULE_FROM_LAST, +- 0, ++ smart, 0, + smart_send_fn, smart_recv_fn, pvt, +- "SUDO Smart Refresh", 0, NULL); ++ "SUDO Smart Refresh", ++ BE_PTASK_OFFLINE_DISABLE | ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup smart refresh ptask " + "[%d]: %s\n", ret, sss_strerror(ret)); +diff --git a/src/tests/cmocka/test_be_ptask.c b/src/tests/cmocka/test_be_ptask.c +index ac8c0767f..b30775306 100644 +--- a/src/tests/cmocka/test_be_ptask.c ++++ b/src/tests/cmocka/test_be_ptask.c +@@ -304,9 +304,10 @@ void test_be_ptask_create_einval_be(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, NULL, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, NULL, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, NULL, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); + } +@@ -318,9 +319,10 @@ void test_be_ptask_create_einval_period(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, 0, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, NULL, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, NULL, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); + } +@@ -332,9 +334,10 @@ void test_be_ptask_create_einval_send(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, NULL, +- test_be_ptask_recv, NULL, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, NULL, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); + } +@@ -346,9 +349,10 @@ void test_be_ptask_create_einval_recv(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- NULL, NULL, "Test ptask", 0, &ptask); ++ NULL, NULL, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); + } +@@ -360,9 +364,72 @@ void test_be_ptask_create_einval_name(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, NULL, NULL, 0, &ptask); ++ test_be_ptask_recv, NULL, NULL, ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); ++ assert_int_equal(ret, EINVAL); ++ assert_null(ptask); ++} ++ ++void test_be_ptask_mixed_from_flags_einval(void **state) ++{ ++ struct test_ctx *test_ctx = (struct test_ctx *)(*state); ++ struct be_ptask *ptask = NULL; ++ errno_t ret; ++ ++ ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, ++ 0, test_be_ptask_send, ++ test_be_ptask_recv, NULL, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | ++ BE_PTASK_SCHEDULE_FROM_LAST | ++ BE_PTASK_SCHEDULE_FROM_NOW, ++ &ptask); ++ assert_int_equal(ret, EINVAL); ++ assert_null(ptask); ++} ++ ++void test_be_ptask_no_from_flags_einval(void **state) ++{ ++ struct test_ctx *test_ctx = (struct test_ctx *)(*state); ++ struct be_ptask *ptask = NULL; ++ errno_t ret; ++ ++ ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, ++ 0, test_be_ptask_send, ++ test_be_ptask_recv, NULL, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP, ++ &ptask); ++ assert_int_equal(ret, EINVAL); ++ assert_null(ptask); ++} ++void test_be_ptask_mixed_offline_flags_einval(void **state) ++{ ++ struct test_ctx *test_ctx = (struct test_ctx *)(*state); ++ struct be_ptask *ptask = NULL; ++ errno_t ret; ++ ++ ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, ++ 0, test_be_ptask_send, ++ test_be_ptask_recv, NULL, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | ++ BE_PTASK_OFFLINE_DISABLE | ++ BE_PTASK_SCHEDULE_FROM_NOW, ++ &ptask); ++ assert_int_equal(ret, EINVAL); ++ assert_null(ptask); ++} ++void test_be_ptask_no_offline_flags_einval(void **state) ++{ ++ struct test_ctx *test_ctx = (struct test_ctx *)(*state); ++ struct be_ptask *ptask = NULL; ++ errno_t ret; ++ ++ ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, ++ 0, test_be_ptask_send, ++ test_be_ptask_recv, NULL, "Test ptask", ++ BE_PTASK_SCHEDULE_FROM_NOW, ++ &ptask); + assert_int_equal(ret, EINVAL); + assert_null(ptask); + } +@@ -376,9 +443,10 @@ void test_be_ptask_create_no_delay(void **state) + + now = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -404,9 +472,10 @@ void test_be_ptask_create_first_delay(void **state) + + now = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, DELAY, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -430,9 +499,10 @@ void test_be_ptask_disable(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -455,9 +525,10 @@ void test_be_ptask_enable(void **state) + + now = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -488,9 +559,10 @@ void test_be_ptask_enable_delay(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, DELAY, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -528,9 +600,10 @@ void test_be_ptask_offline_skip(void **state) + + now = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -562,10 +635,11 @@ void test_be_ptask_offline_disable(void **state) + will_return(be_add_offline_cb, test_ctx); + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_DISABLE, +- BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_DISABLE | ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -594,10 +668,11 @@ void test_be_ptask_offline_execute(void **state) + mark_offline(test_ctx); + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_EXECUTE, +- BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_EXECUTE | ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -623,9 +698,10 @@ void test_be_ptask_reschedule_ok(void **state) + + now = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -655,9 +731,9 @@ void test_be_ptask_reschedule_null(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_null_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, + &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -683,9 +759,9 @@ void test_be_ptask_reschedule_error(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_error_recv, test_ctx, "Test ptask", 0, ++ test_be_ptask_error_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, + &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -711,9 +787,9 @@ void test_be_ptask_reschedule_timeout(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 1, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_timeout_send, +- test_be_ptask_error_recv, test_ctx, "Test ptask", 0, ++ test_be_ptask_error_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, + &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); +@@ -749,9 +825,10 @@ void test_be_ptask_reschedule_backoff(void **state) + + now_first = get_current_time(); + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + PERIOD*2, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -804,9 +881,10 @@ void test_be_ptask_get_period(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + +@@ -825,9 +903,10 @@ void test_be_ptask_get_timeout(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, TIMEOUT, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, +- test_be_ptask_recv, test_ctx, "Test ptask", 0, &ptask); ++ test_be_ptask_recv, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP | BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + +@@ -845,10 +924,12 @@ void test_be_ptask_no_periodic(void **state) + errno_t ret; + + ret = be_ptask_create(test_ctx, test_ctx->be_ctx, 0, 0, DELAY, 0, 0, +- BE_PTASK_OFFLINE_SKIP, BE_PTASK_SCHEDULE_FROM_LAST, + 0, test_be_ptask_send, + test_be_ptask_recv, test_ctx, "Test ptask", +- BE_PTASK_NO_PERIODIC, &ptask); ++ BE_PTASK_NO_PERIODIC | ++ BE_PTASK_OFFLINE_SKIP | ++ BE_PTASK_SCHEDULE_FROM_LAST, ++ &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + +@@ -865,8 +946,8 @@ void test_be_ptask_create_sync(void **state) + + now = get_current_time(); + ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_sync, +- test_ctx, "Test ptask", 0, &ptask); ++ 0, test_be_ptask_sync, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -893,8 +974,8 @@ void test_be_ptask_sync_reschedule_ok(void **state) + + now = get_current_time(); + ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_sync, +- test_ctx, "Test ptask", 0, &ptask); ++ 0, test_be_ptask_sync, test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -924,9 +1005,9 @@ void test_be_ptask_sync_reschedule_error(void **state) + errno_t ret; + + ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, 0, +- test_be_ptask_sync_error, +- test_ctx, "Test ptask", 0, &ptask); ++ 0, test_be_ptask_sync_error, ++ test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -953,10 +1034,11 @@ void test_be_ptask_sync_reschedule_backoff(void **state) + errno_t ret; + + now_first = get_current_time(); +- ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, 0, +- BE_PTASK_OFFLINE_SKIP, PERIOD*2, ++ ret = be_ptask_create_sync(test_ctx, test_ctx->be_ctx, PERIOD, ++ 0, 0, 0, 0, PERIOD*2, + test_be_ptask_sync_error, +- test_ctx, "Test ptask", 0, &ptask); ++ test_ctx, "Test ptask", ++ BE_PTASK_OFFLINE_SKIP, &ptask); + assert_int_equal(ret, ERR_OK); + assert_non_null(ptask); + assert_non_null(ptask->timer); +@@ -1017,6 +1099,10 @@ int main(int argc, const char *argv[]) + new_test(be_ptask_create_einval_send), + new_test(be_ptask_create_einval_recv), + new_test(be_ptask_create_einval_name), ++ new_test(be_ptask_mixed_from_flags_einval), ++ new_test(be_ptask_no_from_flags_einval), ++ new_test(be_ptask_mixed_offline_flags_einval), ++ new_test(be_ptask_no_offline_flags_einval), + new_test(be_ptask_create_no_delay), + new_test(be_ptask_create_first_delay), + new_test(be_ptask_disable), +-- +2.20.1 + diff --git a/SOURCES/0047-PAM-return-short-name-for-files-provider-users.patch b/SOURCES/0047-PAM-return-short-name-for-files-provider-users.patch deleted file mode 100644 index b3cbed2..0000000 --- a/SOURCES/0047-PAM-return-short-name-for-files-provider-users.patch +++ /dev/null @@ -1,148 +0,0 @@ -From f743c82d11ffafa1a48f9b7108eff072ecc9ab1c Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 9 Oct 2018 13:25:35 +0200 -Subject: [PATCH 47/47] PAM: return short name for files provider users - -If the 'allow_missing_name' option is used with pam_sss and the user -name will be determined based on the certificate content and the mapping -rules the PAM responder will by default return the fully-qualified name -of the user which is then later used by other PAM modules as well. - -For local users which are configured to use SSSD for Smartcard -authentication this might cause issues in other PAM modules because they -are not aware of the fully-qualified name and will treat the user as -unknown. - -With this patch the PAM responder will return the short name for all -users handled by the files provider. - -Related to https://pagure.io/SSSD/sssd/issue/3848 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit dbd717fe5b7d8dd640b6ade435b49edb3db5280a) ---- - src/responder/pam/pamsrv.h | 3 ++- - src/responder/pam/pamsrv_cmd.c | 13 +++++++++---- - src/responder/pam/pamsrv_p11.c | 32 +++++++++++++++++++++++++++++--- - 3 files changed, 40 insertions(+), 8 deletions(-) - -diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h -index 60aa97967456b9b7ab35e64f103c1c9a17bef3a9..3a927bb39b1e03735c237cc6b5a33234c2f4e2ef 100644 ---- a/src/responder/pam/pamsrv.h -+++ b/src/responder/pam/pamsrv.h -@@ -108,7 +108,8 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct cert_auth_info **cert_list); - --errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username, -+errno_t add_pam_cert_response(struct pam_data *pd, struct sss_domain_info *dom, -+ const char *sysdb_username, - struct cert_auth_info *cert_info, - enum response_type type); - -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index a22afd225894872847a0fb13e202f927fd2ae124..553bf8fbbdb485f4a7b2610b894b1a78b4e47317 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -1645,7 +1645,8 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - preq->current_cert != NULL; - preq->current_cert = sss_cai_get_next(preq->current_cert)) { - -- ret = add_pam_cert_response(preq->pd, "", -+ ret = add_pam_cert_response(preq->pd, -+ preq->cctx->rctx->domains, "", - preq->current_cert, - preq->cctx->rctx->domains->user_name_hint - ? SSS_PAM_CERT_INFO_WITH_HINT -@@ -1699,7 +1700,8 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - - if (preq->cctx->rctx->domains->user_name_hint - && preq->pd->cmd == SSS_PAM_PREAUTH) { -- ret = add_pam_cert_response(preq->pd, cert_user, -+ ret = add_pam_cert_response(preq->pd, -+ preq->cctx->rctx->domains, cert_user, - preq->cert_list, - SSS_PAM_CERT_INFO_WITH_HINT); - preq->pd->pam_status = PAM_SUCCESS; -@@ -1725,7 +1727,8 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - * 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, -+ ret = add_pam_cert_response(preq->pd, -+ preq->cctx->rctx->domains, cert_user, - preq->cert_list, - SSS_PAM_CERT_INFO); - if (ret != EOK) { -@@ -2117,7 +2120,9 @@ static void pam_dom_forwarder(struct pam_auth_req *preq) - "the backend.\n"); - } - -- ret = add_pam_cert_response(preq->pd, cert_user, -+ ret = add_pam_cert_response(preq->pd, -+ preq->cctx->rctx->domains, -+ cert_user, - preq->current_cert, - SSS_PAM_CERT_INFO); - if (ret != EOK) { -diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c -index 491bd2b01d7bf9137b37c35f9da9eca1eed95a6d..785b29c99a65ec7167b31f746fd9a897b038d817 100644 ---- a/src/responder/pam/pamsrv_p11.c -+++ b/src/responder/pam/pamsrv_p11.c -@@ -1145,7 +1145,8 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username, - * used when running gdm-password. */ - #define PKCS11_LOGIN_TOKEN_ENV_NAME "PKCS11_LOGIN_TOKEN_NAME" - --errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username, -+errno_t add_pam_cert_response(struct pam_data *pd, struct sss_domain_info *dom, -+ const char *sysdb_username, - struct cert_auth_info *cert_info, - enum response_type type) - { -@@ -1153,6 +1154,10 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username, - char *env = NULL; - size_t msg_len; - int ret; -+ char *short_name = NULL; -+ char *domain_name = NULL; -+ const char *cert_info_name = sysdb_username; -+ - - if (type != SSS_PAM_CERT_INFO && type != SSS_PAM_CERT_INFO_WITH_HINT) { - DEBUG(SSSDBG_CRIT_FAILURE, "Invalid response type [%d].\n", type); -@@ -1174,9 +1179,30 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username, - * Smartcard. If this type of name is irritating at the PIN prompt or the - * 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. */ -+ * being I think using sysdb_username is fine. -+ * As special case is the files provider which handles local users which -+ * by definition only have a short name. To avoid confusion by other -+ * modules on the PAM stack the short name is returned in this case. */ - -- ret = pack_cert_data(pd, sysdb_username, cert_info, &msg, &msg_len); -+ if (sysdb_username != NULL) { -+ ret = sss_parse_internal_fqname(pd, sysdb_username, -+ &short_name, &domain_name); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse name '%s' [%d]: %s, " -+ "using full name.\n", -+ sysdb_username, ret, sss_strerror(ret)); -+ } else { -+ if (domain_name != NULL -+ && is_files_provider(find_domain_by_name(dom, domain_name, -+ false))) { -+ cert_info_name = short_name; -+ } -+ } -+ } -+ -+ ret = pack_cert_data(pd, cert_info_name, cert_info, &msg, &msg_len); -+ talloc_free(short_name); -+ talloc_free(domain_name); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "pack_cert_data failed.\n"); - return ret; --- -2.14.4 - diff --git a/SOURCES/0048-DYNDNS-dyndns_update-is-not-enough.patch b/SOURCES/0048-DYNDNS-dyndns_update-is-not-enough.patch new file mode 100644 index 0000000..aee251f --- /dev/null +++ b/SOURCES/0048-DYNDNS-dyndns_update-is-not-enough.patch @@ -0,0 +1,92 @@ +From 07b5dd9640071cf5ca5cd91acfc84af8d0cf69fe Mon Sep 17 00:00:00 2001 +From: Tomas Halman +Date: Fri, 19 Jul 2019 16:52:43 +0200 +Subject: [PATCH 48/48] DYNDNS: dyndns_update is not enough +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When dyndns_update is set to True and dyndns_refresh_interval is +not set or set to 0, DNS is not updated at all. + +With this patch DNS is updated when sssd changes its state to +online. + +If dyndns_refresh_interval is set, updates are performed as +before - i. e. when comming online and then every +dyndns_refresh_interval. + +Resolves: +https://pagure.io/SSSD/sssd/issue/4047 + +Reviewed-by: Pavel Březina +--- + src/providers/ad/ad_dyndns.c | 6 ++++-- + src/providers/ipa/ipa_dyndns.c | 6 ++++-- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/providers/ad/ad_dyndns.c b/src/providers/ad/ad_dyndns.c +index c9763d449..00e1d253a 100644 +--- a/src/providers/ad/ad_dyndns.c ++++ b/src/providers/ad/ad_dyndns.c +@@ -56,6 +56,7 @@ errno_t ad_dyndns_init(struct be_ctx *be_ctx, + errno_t ret; + const time_t ptask_first_delay = 10; + int period; ++ uint32_t extraflags = 0; + + /* nsupdate is available. Dynamic updates + * are supported +@@ -93,15 +94,16 @@ errno_t ad_dyndns_init(struct be_ctx *be_ctx, + + period = dp_opt_get_int(ad_opts->dyndns_ctx->opts, DP_OPT_DYNDNS_REFRESH_INTERVAL); + if (period == 0) { +- DEBUG(SSSDBG_OP_FAILURE, "Dyndns update task can't be started, " ++ DEBUG(SSSDBG_TRACE_FUNC, "DNS will not be updated periodically, " + "dyndns_refresh_interval is 0\n"); +- return EINVAL; ++ extraflags |= BE_PTASK_NO_PERIODIC; + } + + ret = be_ptask_create(ad_opts, be_ctx, period, ptask_first_delay, 0, 0, + period, 0, + ad_dyndns_update_send, ad_dyndns_update_recv, ad_opts, + "Dyndns update", ++ extraflags | + BE_PTASK_OFFLINE_DISABLE | + BE_PTASK_SCHEDULE_FROM_LAST, + NULL); +diff --git a/src/providers/ipa/ipa_dyndns.c b/src/providers/ipa/ipa_dyndns.c +index f8831287a..9404ea9cb 100644 +--- a/src/providers/ipa/ipa_dyndns.c ++++ b/src/providers/ipa/ipa_dyndns.c +@@ -58,6 +58,7 @@ errno_t ipa_dyndns_init(struct be_ctx *be_ctx, + errno_t ret; + const time_t ptask_first_delay = 10; + int period; ++ uint32_t extraflags = 0; + + ctx->be_res = be_ctx->be_res; + if (ctx->be_res == NULL) { +@@ -68,15 +69,16 @@ errno_t ipa_dyndns_init(struct be_ctx *be_ctx, + + period = dp_opt_get_int(ctx->dyndns_ctx->opts, DP_OPT_DYNDNS_REFRESH_INTERVAL); + if (period == 0) { +- DEBUG(SSSDBG_OP_FAILURE, "Dyndns task can't be started, " ++ DEBUG(SSSDBG_TRACE_FUNC, "DNS will not be updated periodically, " + "dyndns_refresh_interval is 0\n"); +- return EINVAL; ++ extraflags |= BE_PTASK_NO_PERIODIC; + } + + ret = be_ptask_create(ctx, be_ctx, period, ptask_first_delay, 0, 0, period, + 0, + ipa_dyndns_update_send, ipa_dyndns_update_recv, ctx, + "Dyndns update", ++ extraflags | + BE_PTASK_OFFLINE_DISABLE | + BE_PTASK_SCHEDULE_FROM_LAST, + NULL); +-- +2.20.1 + diff --git a/SOURCES/0048-doc-Add-nsswitch.conf-note-to-manpage.patch b/SOURCES/0048-doc-Add-nsswitch.conf-note-to-manpage.patch deleted file mode 100644 index 7fd3b19..0000000 --- a/SOURCES/0048-doc-Add-nsswitch.conf-note-to-manpage.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 42b92ad5b26ebbc7c387aa7111f70c74b63cd84f Mon Sep 17 00:00:00 2001 -From: Tomas Halman -Date: Mon, 1 Oct 2018 13:45:52 +0200 -Subject: [PATCH 48/57] doc: Add nsswitch.conf note to manpage - -We want to add note about nsswitch.conf configuration -into sssd-files manpage. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3750 - -Reviewed-by: Jakub Hrozek -Reviewed-by: Justin Stephenson -(cherry picked from commit 0be037bbedd0aed6a7eccead6aabe0d07258242a) ---- - src/man/sssd-files.5.xml | 34 +++++++++++++++++++++++++++++++++- - 1 file changed, 33 insertions(+), 1 deletion(-) - -diff --git a/src/man/sssd-files.5.xml b/src/man/sssd-files.5.xml -index 59e1b652328b6548386d9e15938db38197ad2a92..067e21949ffe10d783cc305c57c0ae57c906f899 100644 ---- a/src/man/sssd-files.5.xml -+++ b/src/man/sssd-files.5.xml -@@ -51,6 +51,27 @@ - 5 - . - -+ -+ Another reason is to provide efficient caching of local users and groups. -+ -+ -+ Please note that some distributions enable the files domain automatically, -+ prepending the domain before any explicitly configured domains. -+ See enable_files_domain in -+ -+ sssd.conf -+ 5 -+ . -+ -+ -+ SSSD never handles resolution of user/group "root". Also resolution of -+ UID/GID 0 is not handled by SSSD. Such requests are passed to next -+ NSS module (usually files). -+ -+ -+ When SSSD is not running or responding, nss_sss returns the UNAVAIL code -+ which causes the request to be passed to the next module. -+ - - - -@@ -110,11 +131,22 @@ - - [domain/files] - id_provider = files -+ -+ -+ -+ To leverage caching of local users and groups by SSSD -+ nss_sss module must be listed before nss_files module -+ in /etc/nsswitch.conf. -+ -+ -+ -+passwd: sss files -+group: sss files - - - - -- -+ - - - --- -2.14.4 - diff --git a/SOURCES/0049-intg-flush-the-SSSD-caches-to-sync-with-files.patch b/SOURCES/0049-intg-flush-the-SSSD-caches-to-sync-with-files.patch deleted file mode 100644 index a49ca25..0000000 --- a/SOURCES/0049-intg-flush-the-SSSD-caches-to-sync-with-files.patch +++ /dev/null @@ -1,45 +0,0 @@ -From b24cc168b6244a9f215e2e235dbbcb3947da9280 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 10 Sep 2018 15:35:45 +0200 -Subject: [PATCH 49/57] intg: flush the SSSD caches to sync with files - -To make sure that SSSD has synced with the latest data added to the -passwd file sss_cache is called in two places where the current sync -scheme was not reliable. This was mainly observed when running the -integration tests on Debian. - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 1e2398870e8aa512ead3012d46cbe6252429467a) ---- - src/tests/intg/test_files_provider.py | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/src/tests/intg/test_files_provider.py b/src/tests/intg/test_files_provider.py -index 9f30d2bb485cb4ccd14da2fa2317f62a7c347745..ead1cc4c34a8027f74f2a9564863159defce02ef 100644 ---- a/src/tests/intg/test_files_provider.py -+++ b/src/tests/intg/test_files_provider.py -@@ -644,6 +644,10 @@ def test_enum_users(setup_pw_with_canary, files_domain_only): - user = user_generator(i) - setup_pw_with_canary.useradd(**user) - -+ # syncing with the help of the canary is not reliable after adding -+ # multiple users because the canary might still be in some caches so that -+ # the data is not refreshed properly. -+ subprocess.call(["sss_cache", "-E"]) - sssd_getpwnam_sync(CANARY["name"]) - user_list = call_sssd_enumeration() - # +1 because the canary is added -@@ -1043,6 +1047,10 @@ def test_getgrnam_add_remove_ghosts(setup_pw_with_canary, - - # Add this user and verify it's been added as a member - pwd_ops.useradd(**USER2) -+ # The negative cache might still have user2 from the previous request, -+ # flushing the caches might help to prevent a failed lookup after adding -+ # the user. -+ subprocess.call(["sss_cache", "-E"]) - res, groups = sssd_id_sync('user2') - assert res == sssd_id.NssReturnCode.SUCCESS - assert len(groups) == 2 --- -2.14.4 - diff --git a/SOURCES/0049-tests-Use-idm-DL1-module-to-install-389-ds.patch b/SOURCES/0049-tests-Use-idm-DL1-module-to-install-389-ds.patch new file mode 100644 index 0000000..f3834ac --- /dev/null +++ b/SOURCES/0049-tests-Use-idm-DL1-module-to-install-389-ds.patch @@ -0,0 +1,31 @@ +From bd14c31c37da420d3a9c478cadded97545e6609a Mon Sep 17 00:00:00 2001 +From: "Niranjan M.R" +Date: Tue, 20 Aug 2019 15:19:14 +0530 +Subject: [PATCH] tests: Use idm:DL1 module to install 389-ds +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Niranjan M.R + +Reviewed-by: Michal Židek +--- + src/tests/multihost/basic/conftest.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/tests/multihost/basic/conftest.py b/src/tests/multihost/basic/conftest.py +index a9e9cf0a6..87f74031c 100644 +--- a/src/tests/multihost/basic/conftest.py ++++ b/src/tests/multihost/basic/conftest.py +@@ -42,7 +42,7 @@ def package_install(session_multihost): + if 'Fedora' in distro: + cmd = 'dnf install -y %s' % (pkg_list) + elif '8.' in distro.split()[5]: +- cmd = 'dnf module -y install 389-ds:1.4' ++ cmd = 'yum -y module enable idm:DL1' + session_multihost.master[0].run_command(cmd) + + +-- +2.20.1 + diff --git a/SOURCES/0050-FILES-The-files-provider-should-not-enumerate.patch b/SOURCES/0050-FILES-The-files-provider-should-not-enumerate.patch deleted file mode 100644 index 654964a..0000000 --- a/SOURCES/0050-FILES-The-files-provider-should-not-enumerate.patch +++ /dev/null @@ -1,101 +0,0 @@ -From c26e713307339699dd26b17f11a2f3136d334ba8 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 15 Oct 2018 22:26:07 +0200 -Subject: [PATCH 50/57] FILES: The files provider should not enumerate -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Resolves: -https://pagure.io/SSSD/sssd/issue/3849 - -For reason I cannot explain now, the files provider always enumerates. -There is commit a60e6ec which implements this, but it's clearly wrong, -because then the plain getent passwd output contains duplicates from -nss_files and nss_sss: - -$ getent passwd | sort -adm:x:3:4:adm:/var/adm:/sbin/nologin -adm:x:3:4:adm:/var/adm:/sbin/nologin -bin:x:1:1:bin:/bin:/sbin/nologin -bin:x:1:1:bin:/bin:/sbin/nologin -certuser:x:10329:10330::/home/certuser:/bin/bash -certuser:x:10329:10330::/home/certuser:/bin/bash -chrony:x:997:994::/var/lib/chrony:/sbin/nologin -chrony:x:997:994::/var/lib/chrony:/sbin/nologin -daemon:x:2:2:daemon:/sbin:/sbin/nologin -daemon:x:2:2:daemon:/sbin:/sbin/nologin - -Reviewed-by: Michal Židek ---- - src/confdb/confdb.c | 5 +---- - src/tests/intg/test_files_provider.py | 22 ---------------------- - 2 files changed, 1 insertion(+), 26 deletions(-) - -diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c -index 2f3d90087e640f77835400b11184b684852d7fda..fdc61226fd7d8e078dd7eb7eb532c11be3cc05ec 100644 ---- a/src/confdb/confdb.c -+++ b/src/confdb/confdb.c -@@ -875,7 +875,6 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb, - char *default_domain; - bool fqnames_default = false; - int memcache_timeout; -- bool enum_default; - - tmp_ctx = talloc_new(mem_ctx); - if (!tmp_ctx) return ENOMEM; -@@ -1009,10 +1008,8 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb, - "Interpreting as true\n", domain->name); - domain->enumerate = true; - } else { /* assume the new format */ -- enum_default = is_files_provider(domain); -- - ret = get_entry_as_bool(res->msgs[0], &domain->enumerate, -- CONFDB_DOMAIN_ENUMERATE, enum_default); -+ CONFDB_DOMAIN_ENUMERATE, 0); - if(ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Invalid value for %s\n", CONFDB_DOMAIN_ENUMERATE); -diff --git a/src/tests/intg/test_files_provider.py b/src/tests/intg/test_files_provider.py -index ead1cc4c34a8027f74f2a9564863159defce02ef..f0155a2f7e26f17e84e93eab2b99ab72f31d297d 100644 ---- a/src/tests/intg/test_files_provider.py -+++ b/src/tests/intg/test_files_provider.py -@@ -32,7 +32,6 @@ import ent - import sssd_id - from sssd_nss import NssReturnCode - from sssd_passwd import (call_sssd_getpwnam, -- call_sssd_enumeration, - call_sssd_getpwuid) - from sssd_group import call_sssd_getgrnam, call_sssd_getgrgid - from files_ops import passwd_ops_setup, group_ops_setup, PasswdOps, GroupOps -@@ -633,27 +632,6 @@ def test_mod_user_shell(add_user_with_canary, files_domain_only): - check_user(moduser) - - --def test_enum_users(setup_pw_with_canary, files_domain_only): -- """ -- Test that enumerating all users works with the default configuration. Also -- test that removing all entries and then enumerating again returns an empty -- set -- """ -- num_users = 10 -- for i in range(1, num_users+1): -- user = user_generator(i) -- setup_pw_with_canary.useradd(**user) -- -- # syncing with the help of the canary is not reliable after adding -- # multiple users because the canary might still be in some caches so that -- # the data is not refreshed properly. -- subprocess.call(["sss_cache", "-E"]) -- sssd_getpwnam_sync(CANARY["name"]) -- user_list = call_sssd_enumeration() -- # +1 because the canary is added -- assert len(user_list) == num_users+1 -- -- - def incomplete_user_setup(pwd_ops, del_field, exp_field): - adduser = dict(USER1) - del adduser[del_field] --- -2.14.4 - diff --git a/SOURCES/0050-pam-keep-pin-on-the-PAM-stack-for-forward_pass.patch b/SOURCES/0050-pam-keep-pin-on-the-PAM-stack-for-forward_pass.patch new file mode 100644 index 0000000..0bfa18b --- /dev/null +++ b/SOURCES/0050-pam-keep-pin-on-the-PAM-stack-for-forward_pass.patch @@ -0,0 +1,135 @@ +From e989620bd2b4f7094dee3ef740ba92d0cf45d0c8 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Mon, 19 Aug 2019 17:38:04 +0200 +Subject: [PATCH] pam: keep pin on the PAM stack for forward_pass +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently only the password or the long-term part of a two-factor +authentication was kept on the PM stack if pam_sss.so has the option +forward_pass. With this patch the Smartcard PIN can be forwarded to +other PAM modules as well. + +Related https://pagure.io/SSSD/sssd/issue/4067 + +Reviewed-by: Pavel Březina +--- + src/sss_client/pam_sss.c | 11 ++++++++++- + src/tests/cmocka/test_authtok.c | 5 +++++ + src/util/authtok-utils.c | 33 +++++++++++++++++++++++++++++++++ + src/util/authtok-utils.h | 10 ++++++++++ + 4 files changed, 58 insertions(+), 1 deletion(-) + +diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c +index cfd3e3731..e36407b72 100644 +--- a/src/sss_client/pam_sss.c ++++ b/src/sss_client/pam_sss.c +@@ -2116,6 +2116,7 @@ static int get_authtok_for_authentication(pam_handle_t *pamh, + uint32_t flags) + { + int ret; ++ const char *pin = NULL; + + if ((flags & PAM_CLI_FLAGS_USE_FIRST_PASS) + || ( pi->pamstack_authtok != NULL +@@ -2166,11 +2167,19 @@ static int get_authtok_for_authentication(pam_handle_t *pamh, + if (flags & PAM_CLI_FLAGS_FORWARD_PASS) { + if (pi->pam_authtok_type == SSS_AUTHTOK_TYPE_PASSWORD) { + ret = pam_set_item(pamh, PAM_AUTHTOK, pi->pam_authtok); ++ } else if (pi->pam_authtok_type == SSS_AUTHTOK_TYPE_SC_PIN) { ++ pin = sss_auth_get_pin_from_sc_blob((uint8_t *) pi->pam_authtok, ++ pi->pam_authtok_size); ++ if (pin != NULL) { ++ ret = pam_set_item(pamh, PAM_AUTHTOK, pin); ++ } else { ++ ret = PAM_SYSTEM_ERR; ++ } + } else if (pi->pam_authtok_type == SSS_AUTHTOK_TYPE_2FA + && pi->first_factor != NULL) { + ret = pam_set_item(pamh, PAM_AUTHTOK, pi->first_factor); + } else { +- ret = EINVAL; ++ ret = PAM_SYSTEM_ERR; + } + if (ret != PAM_SUCCESS) { + D(("Failed to set PAM_AUTHTOK [%s], " +diff --git a/src/tests/cmocka/test_authtok.c b/src/tests/cmocka/test_authtok.c +index 84e209783..a8f5bdee7 100644 +--- a/src/tests/cmocka/test_authtok.c ++++ b/src/tests/cmocka/test_authtok.c +@@ -473,6 +473,11 @@ void test_sss_authtok_sc_blobs(void **state) + needed_size); + #endif + ++ pin = sss_auth_get_pin_from_sc_blob(buf, needed_size); ++ assert_non_null(pin); ++ assert_string_equal(pin, "abc"); ++ pin = NULL; ++ + ret = sss_authtok_set(ts->authtoken, SSS_AUTHTOK_TYPE_SC_PIN, buf, + needed_size); + assert_int_equal(ret, EOK); +diff --git a/src/util/authtok-utils.c b/src/util/authtok-utils.c +index e7123df34..e50f86741 100644 +--- a/src/util/authtok-utils.c ++++ b/src/util/authtok-utils.c +@@ -163,3 +163,36 @@ errno_t sss_auth_pack_sc_blob(const char *pin, size_t pin_len, + + return 0; + } ++ ++const char *sss_auth_get_pin_from_sc_blob(uint8_t *blob, size_t blob_len) ++{ ++ size_t c = 0; ++ uint32_t pin_len; ++ uint32_t token_name_len; ++ uint32_t module_name_len; ++ uint32_t key_id_len; ++ ++ if (blob == NULL || blob_len == 0) { ++ return NULL; ++ } ++ ++ SAFEALIGN_COPY_UINT32(&pin_len, blob, &c); ++ if (pin_len == 0) { ++ return NULL; ++ } ++ ++ SAFEALIGN_COPY_UINT32(&token_name_len, blob + c, &c); ++ SAFEALIGN_COPY_UINT32(&module_name_len, blob + c, &c); ++ SAFEALIGN_COPY_UINT32(&key_id_len, blob + c, &c); ++ ++ if (blob_len != 4 * sizeof(uint32_t) + pin_len + token_name_len ++ + module_name_len + key_id_len) { ++ return NULL; ++ } ++ ++ if (blob[c + pin_len - 1] != '\0') { ++ return NULL; ++ } ++ ++ return (const char *) blob + c; ++} +diff --git a/src/util/authtok-utils.h b/src/util/authtok-utils.h +index c5aace39f..714c8187e 100644 +--- a/src/util/authtok-utils.h ++++ b/src/util/authtok-utils.h +@@ -123,4 +123,14 @@ errno_t sss_auth_unpack_sc_blob(TALLOC_CTX *mem_ctx, + char **token_name, size_t *_token_name_len, + char **module_name, size_t *_module_name_len, + char **key_id, size_t *_key_id_len); ++ ++/** ++ * @brief Return a pointer to the PIN string in the memory buffer ++ * ++ * @param[in] blob Memory buffer containing the 2FA data ++ * @param[in] blob_len Size of the memory buffer ++ * ++ * @return pointer to 0-terminate PIN string in the memory buffer ++ */ ++const char *sss_auth_get_pin_from_sc_blob(uint8_t *blob, size_t blob_len); + #endif /* __AUTHTOK_UTILS_H__ */ +-- +2.20.1 + diff --git a/SOURCES/0051-BE-Invalid-oprator-used-in-condition.patch b/SOURCES/0051-BE-Invalid-oprator-used-in-condition.patch new file mode 100644 index 0000000..2bd6778 --- /dev/null +++ b/SOURCES/0051-BE-Invalid-oprator-used-in-condition.patch @@ -0,0 +1,40 @@ +From 7fcd0a70d6dcaab3aa8f2a84ce9dc939ec350415 Mon Sep 17 00:00:00 2001 +From: Tomas Halman +Date: Wed, 21 Aug 2019 17:00:44 +0200 +Subject: [PATCH] BE: Invalid oprator used in condition +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is wrong binary or used in condition. We have to use & here + +Related to https://bugzilla.redhat.com/show_bug.cgi?id=1744134 + +Reviewed-by: Pavel Březina +--- + src/providers/be_ptask.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/providers/be_ptask.c b/src/providers/be_ptask.c +index 8d75d51d1..319e44aa8 100644 +--- a/src/providers/be_ptask.c ++++ b/src/providers/be_ptask.c +@@ -228,13 +228,13 @@ static void be_ptask_schedule(struct be_ptask *task, + delay = delay + (sss_rand() % task->random_offset); + } + +- if(from | BE_PTASK_SCHEDULE_FROM_NOW) { ++ if(from & BE_PTASK_SCHEDULE_FROM_NOW) { + tv = tevent_timeval_current_ofs(delay, 0); + + DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: scheduling task %lu seconds " + "from now [%lu]\n", task->name, delay, tv.tv_sec); + } +- else if (from | BE_PTASK_SCHEDULE_FROM_LAST) { ++ else if (from & BE_PTASK_SCHEDULE_FROM_LAST) { + tv = tevent_timeval_set(task->last_execution + delay, 0); + + DEBUG(SSSDBG_TRACE_FUNC, "Task [%s]: scheduling task %lu seconds " +-- +2.20.1 + diff --git a/SOURCES/0051-p11_child-add-OCSP-check-ot-the-OpenSSL-version.patch b/SOURCES/0051-p11_child-add-OCSP-check-ot-the-OpenSSL-version.patch deleted file mode 100644 index e04bad1..0000000 --- a/SOURCES/0051-p11_child-add-OCSP-check-ot-the-OpenSSL-version.patch +++ /dev/null @@ -1,490 +0,0 @@ -From 0606a40ed924f4c1793946365076b5d1277395a4 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 10 Oct 2018 15:37:16 +0200 -Subject: [PATCH 51/57] p11_child: add OCSP check ot the OpenSSL version - -Related to https://pagure.io/SSSD/sssd/issue/3489 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 91c608d0eb48435b5b5d2f3631a4bb2a40b8d519) ---- - src/man/sssd.conf.5.xml | 26 ++- - src/p11_child/p11_child_openssl.c | 346 ++++++++++++++++++++++++++++++++++++++ - src/tests/cmocka/test_utils.c | 3 + - src/util/util.c | 2 + - 4 files changed, 370 insertions(+), 7 deletions(-) - -diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml -index c8d53f01f3eedea1e37f6593d02ce1eeaf11d2de..5e3ae48d04cc38ea54547a63c6c31795e12544c2 100644 ---- a/src/man/sssd.conf.5.xml -+++ b/src/man/sssd.conf.5.xml -@@ -479,8 +479,8 @@ - be replaced with the URL of the OCSP - default responder e.g. - http://example.com:80/ocsp. -- This option must be used together -- with -+ (NSS Version) This option must be -+ used together with - ocsp_default_responder_signing_cert. - - -@@ -489,17 +489,29 @@ - - ocsp_default_responder_signing_cert=NAME - -- The nickname of the cert to trust -- (expected) to sign the OCSP responses. -- The certificate with the given nickname -- must be available in the systems NSS -- database. -+ (NSS Version) The nickname of the -+ cert to trust (expected) to sign the -+ OCSP responses. The certificate with -+ the given nickname must be available in -+ the systems NSS database. - This option must be used together - with ocsp_default_responder. -+ (OpenSSL version) This option is -+ currently ignored. All needed -+ certificates must be available in the -+ PEM file given by -+ pam_cert_db_path. - - - - -+ -+ This man page was generated for the NSS version. -+ -+ -+ This man page was generated for the OpenSSL -+ version. -+ - - Unknown options are reported but ignored. - -diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c -index 000e1c94f11edc32abceafb39e98b16ca0664c50..d66a2f82becfa24eae867a2f3df3e23263a5273c 100644 ---- a/src/p11_child/p11_child_openssl.c -+++ b/src/p11_child/p11_child_openssl.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -42,8 +43,344 @@ struct p11_ctx { - X509_STORE *x509_store; - const char *ca_db; - bool wait_for_card; -+ struct cert_verify_opts *cert_verify_opts; - }; - -+static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, -+ const char *path, -+ OCSP_REQUEST *req, int req_timeout) -+{ -+ int fd; -+ int rv; -+ OCSP_REQ_CTX *ctx = NULL; -+ OCSP_RESPONSE *rsp = NULL; -+ fd_set confds; -+ struct timeval tv; -+ -+ if (req_timeout != -1) { -+ BIO_set_nbio(cbio, 1); -+ } -+ -+ rv = BIO_do_connect(cbio); -+ -+ if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(cbio))) { -+ DEBUG(SSSDBG_OP_FAILURE, "Error connecting BIO\n"); -+ return NULL; -+ } -+ -+ if (BIO_get_fd(cbio, &fd) < 0) { -+ DEBUG(SSSDBG_OP_FAILURE, "Can't get connection fd\n"); -+ goto err; -+ } -+ -+ if (req_timeout != -1 && rv <= 0) { -+ FD_ZERO(&confds); -+ FD_SET(fd, &confds); -+ tv.tv_usec = 0; -+ tv.tv_sec = req_timeout; -+ rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); -+ if (rv == 0) { -+ DEBUG(SSSDBG_OP_FAILURE, "Timeout on connect\n"); -+ return NULL; -+ } -+ } -+ -+ ctx = OCSP_sendreq_new(cbio, path, NULL, -1); -+ if (ctx == NULL) { -+ return NULL; -+ } -+ -+ if (OCSP_REQ_CTX_add1_header(ctx, "Host", host) == 0) { -+ goto err; -+ } -+ -+ if (!OCSP_REQ_CTX_set1_req(ctx, req)) { -+ goto err; -+ } -+ -+ for (;;) { -+ rv = OCSP_sendreq_nbio(&rsp, ctx); -+ if (rv != -1) -+ break; -+ if (req_timeout == -1) -+ continue; -+ FD_ZERO(&confds); -+ FD_SET(fd, &confds); -+ tv.tv_usec = 0; -+ tv.tv_sec = req_timeout; -+ if (BIO_should_read(cbio)) { -+ rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv); -+ } else if (BIO_should_write(cbio)) { -+ rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); -+ } else { -+ DEBUG(SSSDBG_OP_FAILURE, "Unexpected retry condition\n"); -+ goto err; -+ } -+ if (rv == 0) { -+ DEBUG(SSSDBG_OP_FAILURE, "Timeout on request\n"); -+ break; -+ } -+ if (rv == -1) { -+ DEBUG(SSSDBG_OP_FAILURE, "Select error\n"); -+ break; -+ } -+ -+ } -+ err: -+ OCSP_REQ_CTX_free(ctx); -+ -+ return rsp; -+} -+ -+#if OPENSSL_VERSION_NUMBER < 0x10100000L -+#define TLS_client_method SSLv23_client_method -+#define X509_STORE_get0_objects(store) (store->objs) -+#define X509_OBJECT_get_type(object) (object->type) -+#define X509_OBJECT_get0_X509(object) (object->data.x509) -+#endif -+ -+OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, -+ const char *host, const char *path, -+ const char *port, int use_ssl, -+ int req_timeout) -+{ -+ BIO *cbio = NULL; -+ SSL_CTX *ctx = NULL; -+ OCSP_RESPONSE *resp = NULL; -+ -+ cbio = BIO_new_connect(host); -+ if (cbio == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "Error creating connect BIO\n"); -+ goto end; -+ } -+ if (port != NULL) -+ BIO_set_conn_port(cbio, port); -+ if (use_ssl == 1) { -+ BIO *sbio; -+ ctx = SSL_CTX_new(TLS_client_method()); -+ if (ctx == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "Error creating SSL context.\n"); -+ goto end; -+ } -+ SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); -+ sbio = BIO_new_ssl(ctx, 1); -+ cbio = BIO_push(sbio, cbio); -+ } -+ -+ resp = query_responder(cbio, host, path, req, req_timeout); -+ if (resp == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "Error querying OCSP responder\n"); -+ } -+ -+ end: -+ BIO_free_all(cbio); -+ SSL_CTX_free(ctx); -+ return resp; -+} -+ -+static errno_t do_ocsp(struct p11_ctx *p11_ctx, X509 *cert) -+{ -+ OCSP_REQUEST *ocsp_req = NULL; -+ OCSP_RESPONSE *ocsp_resp = NULL; -+ OCSP_BASICRESP *ocsp_basic = NULL; -+ OCSP_CERTID *cid = NULL; -+ STACK_OF(OPENSSL_STRING) *ocsp_urls = NULL; -+ char *url_str; -+ X509 *issuer = NULL; -+ int req_timeout = -1; -+ int status; -+ int ret = EIO; -+ int reason; -+ ASN1_GENERALIZEDTIME *revtime; -+ ASN1_GENERALIZEDTIME *thisupd; -+ ASN1_GENERALIZEDTIME *nextupd; -+ long grace_time = (5 * 60); /* Allow 5 minutes time difference when -+ * checking the validity of the OCSP response */ -+ char *host = NULL; -+ char *path = NULL; -+ char *port = NULL; -+ int use_ssl; -+ X509_NAME *issuer_name = NULL; -+ X509_OBJECT *x509_obj; -+ STACK_OF(X509_OBJECT) *store_objects; -+ -+ ocsp_urls = X509_get1_ocsp(cert); -+ if (ocsp_urls == NULL -+ && p11_ctx->cert_verify_opts->ocsp_default_responder == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "No OCSP URL in certificate and no default responder defined, " -+ "skipping OCSP check.\n"); -+ return EOK; -+ } -+ -+ if (p11_ctx->cert_verify_opts->ocsp_default_responder != NULL) { -+ url_str = p11_ctx->cert_verify_opts->ocsp_default_responder; -+ } else { -+ if (sk_OPENSSL_STRING_num(ocsp_urls) > 1) { -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "Found more than 1 OCSP URLs, just using the first.\n"); -+ } -+ -+ url_str = sk_OPENSSL_STRING_value(ocsp_urls, 0); -+ } -+ -+ DEBUG(SSSDBG_TRACE_ALL, "Using OCSP URL [%s].\n", url_str); -+ -+ ret = OCSP_parse_url(url_str, &host, &port, &path, &use_ssl); -+ if (ret != 1) { -+ DEBUG(SSSDBG_OP_FAILURE, "OCSP_parse_url failed to parse [%s].\n", -+ url_str); -+ ret = EIO; -+ goto done; -+ } -+ -+ issuer_name = X509_get_issuer_name(cert); -+ if (issuer_name == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Certificate has no issuer, " -+ "cannot run OCSP check.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ store_objects = X509_STORE_get0_objects(p11_ctx->x509_store); -+ if (store_objects == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "No objects found in certificate store, OCSP failed.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ x509_obj = X509_OBJECT_retrieve_by_subject(store_objects, X509_LU_X509, -+ issuer_name); -+ if (x509_obj == NULL || X509_OBJECT_get_type(x509_obj) != X509_LU_X509) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Issuer not found.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ issuer = X509_OBJECT_get0_X509(x509_obj); -+ -+ ocsp_req = OCSP_REQUEST_new(); -+ if (ocsp_req == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "OCSP_REQUEST_new failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ cid = OCSP_cert_to_id(EVP_sha1(), cert, issuer); -+ if (cid == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "OCSP_cert_to_id failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ if (OCSP_request_add0_id(ocsp_req, cid) == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "OCSP_request_add0_id failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ OCSP_request_add1_nonce(ocsp_req, NULL, -1); -+ -+ ocsp_resp = process_responder(ocsp_req, host, path, port, use_ssl, -+ req_timeout); -+ if (ocsp_resp == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "process_responder failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ status = OCSP_response_status(ocsp_resp); -+ if (status != OCSP_RESPONSE_STATUS_SUCCESSFUL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "OCSP response error: [%d][%s].\n", -+ status, OCSP_response_status_str(status)); -+ ret = EIO; -+ goto done; -+ } -+ -+ ocsp_basic = OCSP_response_get1_basic(ocsp_resp); -+ if (ocsp_resp == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "OCSP_response_get1_basic failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ switch (OCSP_check_nonce(ocsp_req, ocsp_basic)) { -+ case -1: -+ DEBUG(SSSDBG_CRIT_FAILURE, "No nonce in OCSP response. This might " -+ "indicate a replay attack or an OCSP responder which does not " -+ "support nonces. Accepting response.\n"); -+ break; -+ case 0: -+ DEBUG(SSSDBG_CRIT_FAILURE, "Nonce in OCSP response does not match the " -+ "one used in the request.\n"); -+ ret = EIO; -+ goto done; -+ break; -+ case 1: -+ DEBUG(SSSDBG_TRACE_ALL, "Nonce in OCSP response is the same as the one " -+ "used in the request.\n"); -+ break; -+ case 2: -+ case 3: -+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing nonce in OCSP request, this should" -+ "never happen.\n"); -+ ret = EIO; -+ goto done; -+ break; -+ default: -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected result of OCSP_check_nonce.\n"); -+ } -+ -+ status = OCSP_basic_verify(ocsp_basic, NULL, p11_ctx->x509_store, 0); -+ if (status != 1) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "OCSP_base_verify failed to verify OCSP " -+ "response.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ ret = OCSP_resp_find_status(ocsp_basic, cid, &status, &reason, -+ &revtime, &thisupd, &nextupd); -+ if (ret != 1) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "OCSP response does not contain status of " -+ "our certificate.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ if (status != V_OCSP_CERTSTATUS_GOOD) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "OCSP check failed with [%d][%s].\n", -+ status, OCSP_cert_status_str(status)); -+ if (status == V_OCSP_CERTSTATUS_REVOKED) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Certificate is revoked [%d][%s].\n", -+ reason, OCSP_crl_reason_str(reason)); -+ } -+ ret = EIO; -+ goto done; -+ } -+ -+ if (OCSP_check_validity(thisupd, nextupd, grace_time, -1) != 1) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "OCSP response is not valid anymore.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ DEBUG(SSSDBG_TRACE_ALL, "OCSP check was successful.\n"); -+ ret = EOK; -+ -+done: -+ OCSP_BASICRESP_free(ocsp_basic); -+ OCSP_RESPONSE_free(ocsp_resp); -+ OCSP_REQUEST_free(ocsp_req); -+ -+ OPENSSL_free(host); -+ OPENSSL_free(port); -+ OPENSSL_free(path); -+ X509_email_free(ocsp_urls); -+ -+ return ret; -+} - - static char *get_pkcs11_uri(TALLOC_CTX *mem_ctx, CK_INFO *module_info, - CK_SLOT_INFO *slot_info, CK_SLOT_ID slot_id, -@@ -191,6 +528,7 @@ errno_t init_verification(struct p11_ctx *p11_ctx, - } - - p11_ctx->x509_store = store; -+ p11_ctx->cert_verify_opts = cert_verify_opts; - talloc_set_destructor(p11_ctx, talloc_free_x509_store); - - ret = EOK; -@@ -262,6 +600,14 @@ bool do_verification(struct p11_ctx *p11_ctx, X509 *cert) - goto done; - } - -+ if (p11_ctx->cert_verify_opts->do_ocsp) { -+ ret = do_ocsp(p11_ctx, cert); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "do_ocsp failed.\n"); -+ goto done; -+ } -+ } -+ - res = true; - - done: -diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c -index 1a8699a2a87d57ab43c70ceebf9bc71da4def4d4..c86e526e8299122c1c613c8459d3df0d9e4fc878 100644 ---- a/src/tests/cmocka/test_utils.c -+++ b/src/tests/cmocka/test_utils.c -@@ -1612,6 +1612,8 @@ static void test_parse_cert_verify_opts(void **state) - &cv_opts); - assert_int_equal(ret, EINVAL); - -+/* Only NSS requires that both are set */ -+#ifdef HAVE_NSS - ret = parse_cert_verify_opts(global_talloc_context, - "ocsp_default_responder=abc", &cv_opts); - assert_int_equal(ret, EINVAL); -@@ -1620,6 +1622,7 @@ static void test_parse_cert_verify_opts(void **state) - "ocsp_default_responder_signing_cert=def", - &cv_opts); - assert_int_equal(ret, EINVAL); -+#endif - - ret = parse_cert_verify_opts(global_talloc_context, - "ocsp_default_responder=abc," -diff --git a/src/util/util.c b/src/util/util.c -index 53dd9a13ab8597b1fec61f10d641c14bf1cedd29..7f475fa9b5f5ddd69e80d5639380824cef82562c 100644 ---- a/src/util/util.c -+++ b/src/util/util.c -@@ -1123,6 +1123,7 @@ errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts, - } - } - -+#ifdef HAVE_NSS - if ((cert_verify_opts->ocsp_default_responder == NULL - && cert_verify_opts->ocsp_default_responder_signing_cert != NULL) - || (cert_verify_opts->ocsp_default_responder != NULL -@@ -1135,6 +1136,7 @@ errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts, - ret = EINVAL; - goto done; - } -+#endif - - ret = EOK; - --- -2.14.4 - diff --git a/SOURCES/0052-TESTS-Sync.-multihost-kcm-tests-with-master.patch b/SOURCES/0052-TESTS-Sync.-multihost-kcm-tests-with-master.patch new file mode 100644 index 0000000..fd8028d --- /dev/null +++ b/SOURCES/0052-TESTS-Sync.-multihost-kcm-tests-with-master.patch @@ -0,0 +1,192 @@ +From 4c77f1d5172b427aad0124d7970fb6905fb0a14a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20=C5=BDidek?= +Date: Mon, 2 Sep 2019 02:01:54 +0200 +Subject: [PATCH] TESTS: Sync. multihost kcm tests with master + +--- + src/tests/multihost/basic/conftest.py | 8 ++ + src/tests/multihost/basic/test_kcm.py | 138 ++++++++++++++++++++++++++ + 2 files changed, 146 insertions(+) + +diff --git a/src/tests/multihost/basic/conftest.py b/src/tests/multihost/basic/conftest.py +index 87f74031c..dd3c6f001 100644 +--- a/src/tests/multihost/basic/conftest.py ++++ b/src/tests/multihost/basic/conftest.py +@@ -397,6 +397,14 @@ def create_posix_usersgroups(session_multihost): + assert ret == 'Success' + + ++@pytest.fixture(scope='session') ++def create_many_user_principals(session_multihost): ++ krb = krb5srv(session_multihost.master[0], 'EXAMPLE.TEST') ++ for i in range(1, 65): ++ username = "user%04d" % i ++ krb.add_principal(username, 'user', 'Secret123') ++ ++ + @pytest.fixture(scope="session", autouse=True) + def setup_session(request, session_multihost, + package_install, +diff --git a/src/tests/multihost/basic/test_kcm.py b/src/tests/multihost/basic/test_kcm.py +index 54b3f7ecd..f18748af7 100644 +--- a/src/tests/multihost/basic/test_kcm.py ++++ b/src/tests/multihost/basic/test_kcm.py +@@ -3,6 +3,7 @@ from sssd.testlib.common.utils import SSHClient + import paramiko + import pytest + import os ++import re + from utils_config import set_param, remove_section + + +@@ -38,6 +39,11 @@ class TestSanityKCM(object): + os.remove(local_kcm_log_file) + return nlines + ++ def _remove_secret_db(self, multihost): ++ multihost.master[0].run_command( ++ 'rm -f /var/lib/sss/secrets/secrets.ldb') ++ self._restart_kcm(multihost) ++ + def test_kinit_kcm(self, multihost, enable_kcm): + """ + @Title: kcm: Run kinit with KRB5CCNAME=KCM +@@ -175,3 +181,135 @@ class TestSanityKCM(object): + if 'KCM:14583109' in line: + has_cache = True + assert has_cache is True ++ ++ def test_kvno_display(self, multihost, enable_kcm): ++ """ ++ @Title: kcm: Test kvno correctly displays vesion numbers of principals ++ #https://pagure.io/SSSD/sssd/issue/3757 ++ """ ++ ssh = SSHClient(multihost.master[0].sys_hostname, ++ username='foo4', password='Secret123') ++ host_princ = 'host/%s@%s' % (multihost.master[0].sys_hostname, ++ 'EXAMPLE.TEST') ++ kvno_cmd = 'kvno %s' % (host_princ) ++ (stdout, _, exit_status) = ssh.execute_cmd(kvno_cmd) ++ for line in stdout.readlines(): ++ kvno_check = re.search(r'%s: kvno = (\d+)' % host_princ, line) ++ if kvno_check: ++ print(kvno_check.group()) ++ else: ++ pytest.fail("kvno display was improper") ++ ssh.close() ++ ++ def test_kcm_peruid_quota(self, ++ multihost, ++ enable_kcm, ++ create_many_user_principals): ++ """ ++ @Title: kcm: Make sure the quota limits a client, but only that client ++ """ ++ # It is easier to keep these tests stable and independent from others ++ # if they start from a clean slate ++ self._remove_secret_db(multihost) ++ ++ ssh_foo2 = SSHClient(multihost.master[0].sys_hostname, ++ username='foo2', password='Secret123') ++ ssh_foo3 = SSHClient(multihost.master[0].sys_hostname, ++ username='foo3', password='Secret123') ++ ++ # The loop would request 63 users, plus there is foo3 we authenticated ++ # earlier, so this should exactly deplete the quota, but should succeed ++ for i in range(1, 64): ++ username = "user%04d" % i ++ (_, _, exit_status) = ssh_foo3.execute_cmd('kinit %s' % username, ++ stdin='Secret123') ++ assert exit_status == 0 ++ ++ # this kinit should be exactly one over the peruid limit ++ (_, _, exit_status) = ssh_foo3.execute_cmd('kinit user0064', ++ stdin='Secret123') ++ assert exit_status != 0 ++ ++ # Since this is a per-uid limit, another user should be able to kinit ++ # just fine ++ (_, _, exit_status) = ssh_foo2.execute_cmd('kinit user0064', ++ stdin='Secret123') ++ assert exit_status == 0 ++ ++ # kdestroy as the original user, the quota should allow a subsequent ++ # kinit ++ ssh_foo3.execute_cmd('kdestroy -A') ++ (_, _, exit_status) = ssh_foo3.execute_cmd('kinit user0064', ++ stdin='Secret123') ++ assert exit_status == 0 ++ ++ ssh_foo2.execute_cmd('kdestroy -A') ++ ssh_foo2.close() ++ ssh_foo3.execute_cmd('kdestroy -A') ++ ssh_foo3.close() ++ ++ def test_kcm_peruid_quota_increase(self, ++ multihost, ++ enable_kcm, ++ create_many_user_principals): ++ """ ++ @Title: kcm: Quota increase ++ ++ Increasing the peruid quota allows a client to store more ++ data ++ """ ++ # It is easier to keep these tests stable and independent from others ++ # if they start from a clean slate ++ self._remove_secret_db(multihost) ++ ++ ssh_foo3 = SSHClient(multihost.master[0].sys_hostname, ++ username='foo3', password='Secret123') ++ ++ # The loop would request 63 users, plus there is foo3 we authenticated ++ # earlier, so this should exactly deplete the quota, but should succeed ++ for i in range(1, 64): ++ username = "user%04d" % i ++ (_, _, exit_status) = ssh_foo3.execute_cmd('kinit %s' % username, ++ stdin='Secret123') ++ assert exit_status == 0 ++ ++ # this kinit should be exactly one over the peruid limit ++ (_, _, exit_status) = ssh_foo3.execute_cmd('kinit user0064', ++ stdin='Secret123') ++ assert exit_status != 0 ++ ++ set_param(multihost, 'kcm', 'max_uid_ccaches', '65') ++ self._restart_kcm(multihost) ++ ++ # Now the kinit should work as we increased the limit ++ (_, _, exit_status) = ssh_foo3.execute_cmd('kinit user0064', ++ stdin='Secret123') ++ assert exit_status == 0 ++ ++ ssh_foo3.execute_cmd('kdestroy -A') ++ ssh_foo3.close() ++ ++ def test_kcm_payload_low_quota(self, ++ multihost, ++ enable_kcm): ++ """ ++ @Title: kcm: Quota enforcement ++ ++ Set a prohibitive quota for the per-ccache payload limit and ++ make sure it gets enforced ++ """ ++ # It is easier to keep these tests stable and independent from others ++ # if they start from a clean slate ++ self._remove_secret_db(multihost) ++ ++ ssh_foo3 = SSHClient(multihost.master[0].sys_hostname, ++ username='foo3', password='Secret123') ++ ssh_foo3.execute_cmd('kdestroy -A') ++ ssh_foo3.close() ++ ++ set_param(multihost, 'kcm', 'max_ccache_size', '1') ++ self._restart_kcm(multihost) ++ ++ with pytest.raises(paramiko.ssh_exception.AuthenticationException): ++ ssh_foo3 = SSHClient(multihost.master[0].sys_hostname, ++ username='foo3', password='Secret123') +-- +2.20.1 + diff --git a/SOURCES/0052-p11_child-add-crl_file-option-for-the-OpenSSL-build.patch b/SOURCES/0052-p11_child-add-crl_file-option-for-the-OpenSSL-build.patch deleted file mode 100644 index 31dc808..0000000 --- a/SOURCES/0052-p11_child-add-crl_file-option-for-the-OpenSSL-build.patch +++ /dev/null @@ -1,280 +0,0 @@ -From 1a8969bb1b3dbd1d5ef7f29dd0fa2ddc8a50fa8b Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 11 Oct 2018 17:35:24 +0200 -Subject: [PATCH 52/57] p11_child: add crl_file option for the OpenSSL build - -In the NSS build a Certificate Revocation List (CRL) can just be added -to the NSS database. For OpenSSL a separate file is needed. - -Related to https://pagure.io/SSSD/sssd/issue/3489 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 3c096c9ad6dad911d035cfdd802b5dda4710fc68) ---- - src/man/sssd.conf.5.xml | 24 ++++++++++++++++++++++++ - src/p11_child/p11_child_common.c | 12 ++++++------ - src/p11_child/p11_child_openssl.c | 26 +++++++++++++++++++++++++- - src/tests/cmocka/test_utils.c | 16 ++++++++++++++++ - src/util/util.c | 13 +++++++++++++ - src/util/util.h | 1 + - 6 files changed, 85 insertions(+), 7 deletions(-) - -diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml -index 5e3ae48d04cc38ea54547a63c6c31795e12544c2..bea25c62286fa638bec47cb7404341be6190f410 100644 ---- a/src/man/sssd.conf.5.xml -+++ b/src/man/sssd.conf.5.xml -@@ -503,6 +503,30 @@ - pam_cert_db_path. - - -+ -+ crl_file=/PATH/TO/CRL/FILE -+ -+ (NSS Version) This option is -+ ignored, please see -+ -+ crlutil -+ 1 -+ -+ how to import a Certificate Revocation -+ List (CRL) into a NSS database. -+ -+ (OpenSSL Version) Use the -+ Certificate Revocation List (CRL) from -+ the given file during the verification -+ of the certificate. The CRL must be -+ given in PEM format, see -+ -+ crl -+ 1ssl -+ -+ for details. -+ -+ - - - -diff --git a/src/p11_child/p11_child_common.c b/src/p11_child/p11_child_common.c -index 097e7fa07fb4d90e087250aec9f971b4a2afdb52..b992aeb71ee6c8acc8792265aaa7bdcf0d06770d 100644 ---- a/src/p11_child/p11_child_common.c -+++ b/src/p11_child/p11_child_common.c -@@ -48,7 +48,7 @@ static const char *op_mode_str(enum op_mode mode) - return "pre-auth"; - break; - case OP_VERIFIY: -- return "verifiy"; -+ return "verify"; - break; - default: - return "unknown"; -@@ -219,7 +219,7 @@ int main(int argc, const char *argv[]) - case 'a': - if (mode != OP_NONE) { - fprintf(stderr, -- "\n--verifiy, --auth and --pre are mutually " \ -+ "\n--verify, --auth and --pre are mutually " \ - "exclusive and should be only used once.\n\n"); - poptPrintUsage(pc, stderr, 0); - _exit(-1); -@@ -229,7 +229,7 @@ int main(int argc, const char *argv[]) - case 'p': - if (mode != OP_NONE) { - fprintf(stderr, -- "\n--verifiy, --auth and --pre are mutually " \ -+ "\n--verify, --auth and --pre are mutually " \ - "exclusive and should be only used once.\n\n"); - poptPrintUsage(pc, stderr, 0); - _exit(-1); -@@ -239,7 +239,7 @@ int main(int argc, const char *argv[]) - case 'v': - if (mode != OP_NONE) { - fprintf(stderr, -- "\n--verifiy, --auth and --pre are mutually " \ -+ "\n--verify, --auth and --pre are mutually " \ - "exclusive and should be only used once.\n\n"); - poptPrintUsage(pc, stderr, 0); - _exit(-1); -@@ -283,7 +283,7 @@ int main(int argc, const char *argv[]) - - if (mode == OP_NONE) { - fprintf(stderr, "\nMissing operation mode, either " \ -- "--verifiy, --auth or --pre must be specified.\n\n"); -+ "--verify, --auth or --pre must be specified.\n\n"); - poptPrintUsage(pc, stderr, 0); - _exit(-1); - } else if (mode == OP_AUTH && pin_mode == PIN_NONE) { -@@ -350,7 +350,7 @@ int main(int argc, const char *argv[]) - - 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"); -+ DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse verify option.\n"); - goto fail; - } - -diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c -index d66a2f82becfa24eae867a2f3df3e23263a5273c..9defdfc5a7acc70d0cea06d4919b06b93eb33c7b 100644 ---- a/src/p11_child/p11_child_openssl.c -+++ b/src/p11_child/p11_child_openssl.c -@@ -501,6 +501,7 @@ errno_t init_verification(struct p11_ctx *p11_ctx, - X509_STORE *store = NULL; - unsigned long err; - X509_LOOKUP *lookup = NULL; -+ X509_VERIFY_PARAM *verify_param = NULL; - - store = X509_STORE_new(); - if (store == NULL) { -@@ -527,6 +528,30 @@ errno_t init_verification(struct p11_ctx *p11_ctx, - goto done; - } - -+ if (cert_verify_opts->crl_file != NULL) { -+ verify_param = X509_VERIFY_PARAM_new(); -+ if (verify_param == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "X509_VERIFY_PARAM_new failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ X509_VERIFY_PARAM_set_flags(verify_param, (X509_V_FLAG_CRL_CHECK -+ | X509_V_FLAG_CRL_CHECK_ALL)); -+ -+ X509_STORE_set1_param(store, verify_param); -+ -+ ret = X509_load_crl_file(lookup, cert_verify_opts->crl_file, -+ X509_FILETYPE_PEM); -+ if (ret == 0) { -+ err = ERR_get_error(); -+ DEBUG(SSSDBG_OP_FAILURE, "X509_load_crl_file failed [%lu][%s].\n", -+ err, ERR_error_string(err, NULL)); -+ ret = EIO; -+ goto done; -+ } -+ } -+ - p11_ctx->x509_store = store; - p11_ctx->cert_verify_opts = cert_verify_opts; - talloc_set_destructor(p11_ctx, talloc_free_x509_store); -@@ -536,7 +561,6 @@ errno_t init_verification(struct p11_ctx *p11_ctx, - done: - if (ret != EOK) { - X509_STORE_free(store); -- X509_LOOKUP_free(lookup); - } - - return ret; -diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c -index c86e526e8299122c1c613c8459d3df0d9e4fc878..cf1c2ae6787cd1b011089b57d6bac320dadd60de 100644 ---- a/src/tests/cmocka/test_utils.c -+++ b/src/tests/cmocka/test_utils.c -@@ -1567,6 +1567,7 @@ static void test_parse_cert_verify_opts(void **state) - assert_true(cv_opts->do_ocsp); - assert_null(cv_opts->ocsp_default_responder); - assert_null(cv_opts->ocsp_default_responder_signing_cert); -+ assert_null(cv_opts->crl_file); - talloc_free(cv_opts); - - ret = parse_cert_verify_opts(global_talloc_context, "wedfkwefjk", &cv_opts); -@@ -1575,6 +1576,7 @@ static void test_parse_cert_verify_opts(void **state) - assert_true(cv_opts->do_ocsp); - assert_null(cv_opts->ocsp_default_responder); - assert_null(cv_opts->ocsp_default_responder_signing_cert); -+ assert_null(cv_opts->crl_file); - talloc_free(cv_opts); - - ret = parse_cert_verify_opts(global_talloc_context, "no_ocsp", &cv_opts); -@@ -1583,6 +1585,7 @@ static void test_parse_cert_verify_opts(void **state) - assert_false(cv_opts->do_ocsp); - assert_null(cv_opts->ocsp_default_responder); - assert_null(cv_opts->ocsp_default_responder_signing_cert); -+ assert_null(cv_opts->crl_file); - talloc_free(cv_opts); - - ret = parse_cert_verify_opts(global_talloc_context, "no_verification", -@@ -1592,6 +1595,7 @@ static void test_parse_cert_verify_opts(void **state) - assert_true(cv_opts->do_ocsp); - assert_null(cv_opts->ocsp_default_responder); - assert_null(cv_opts->ocsp_default_responder_signing_cert); -+ assert_null(cv_opts->crl_file); - talloc_free(cv_opts); - - ret = parse_cert_verify_opts(global_talloc_context, -@@ -1601,6 +1605,7 @@ static void test_parse_cert_verify_opts(void **state) - assert_false(cv_opts->do_ocsp); - assert_null(cv_opts->ocsp_default_responder); - assert_null(cv_opts->ocsp_default_responder_signing_cert); -+ assert_null(cv_opts->crl_file); - talloc_free(cv_opts); - - ret = parse_cert_verify_opts(global_talloc_context, -@@ -1633,6 +1638,17 @@ static void test_parse_cert_verify_opts(void **state) - assert_true(cv_opts->do_ocsp); - assert_string_equal(cv_opts->ocsp_default_responder, "abc"); - assert_string_equal(cv_opts->ocsp_default_responder_signing_cert, "def"); -+ assert_null(cv_opts->crl_file); -+ talloc_free(cv_opts); -+ -+ ret = parse_cert_verify_opts(global_talloc_context, "crl_file=hij", -+ &cv_opts); -+ assert_int_equal(ret, EOK); -+ assert_true(cv_opts->do_verification); -+ assert_true(cv_opts->do_ocsp); -+ assert_null(cv_opts->ocsp_default_responder); -+ assert_null(cv_opts->ocsp_default_responder_signing_cert); -+ assert_string_equal(cv_opts->crl_file, "hij"); - talloc_free(cv_opts); - } - -diff --git a/src/util/util.c b/src/util/util.c -index 7f475fa9b5f5ddd69e80d5639380824cef82562c..cbe6a2870c302c51770ef5b526bd5bf8cc8df0e0 100644 ---- a/src/util/util.c -+++ b/src/util/util.c -@@ -1024,6 +1024,7 @@ static struct cert_verify_opts *init_cert_verify_opts(TALLOC_CTX *mem_ctx) - cert_verify_opts->do_verification = true; - cert_verify_opts->ocsp_default_responder = NULL; - cert_verify_opts->ocsp_default_responder_signing_cert = NULL; -+ cert_verify_opts->crl_file = NULL; - - return cert_verify_opts; - } -@@ -1035,6 +1036,8 @@ static struct cert_verify_opts *init_cert_verify_opts(TALLOC_CTX *mem_ctx) - "ocsp_default_responder_signing_cert=" - #define OCSP_DEFAUL_RESPONDER_SIGNING_CERT_LEN \ - (sizeof(OCSP_DEFAUL_RESPONDER_SIGNING_CERT) - 1) -+#define CRL_FILE "crl_file=" -+#define CRL_FILE_LEN (sizeof(CRL_FILE) -1) - - errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts, - struct cert_verify_opts **_cert_verify_opts) -@@ -1116,6 +1119,16 @@ errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts, - DEBUG(SSSDBG_TRACE_ALL, - "Using OCSP default responder signing cert nickname [%s]\n", - cert_verify_opts->ocsp_default_responder_signing_cert); -+ } else if (strncasecmp(opts[c], CRL_FILE, CRL_FILE_LEN) == 0) { -+ cert_verify_opts->crl_file = talloc_strdup(cert_verify_opts, -+ &opts[c][CRL_FILE_LEN]); -+ if (cert_verify_opts->crl_file == NULL -+ || *cert_verify_opts->crl_file == '\0') { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to parse crl_file option [%s].\n", opts[c]); -+ ret = EINVAL; -+ goto done; -+ } - } else { - DEBUG(SSSDBG_CRIT_FAILURE, - "Unsupported certificate verification option [%s], " \ -diff --git a/src/util/util.h b/src/util/util.h -index e3e91009728cd8a5a92701220c06e8c378f47431..7e9b3d6a6fe323606ab9646b9757e725b5a4ef74 100644 ---- a/src/util/util.h -+++ b/src/util/util.h -@@ -371,6 +371,7 @@ struct cert_verify_opts { - bool do_verification; - char *ocsp_default_responder; - char *ocsp_default_responder_signing_cert; -+ char *crl_file; - }; - - errno_t parse_cert_verify_opts(TALLOC_CTX *mem_ctx, const char *verify_opts, --- -2.14.4 - diff --git a/SOURCES/0053-KCM-Add-a-forgotten-return.patch b/SOURCES/0053-KCM-Add-a-forgotten-return.patch new file mode 100644 index 0000000..6ddf5ba --- /dev/null +++ b/SOURCES/0053-KCM-Add-a-forgotten-return.patch @@ -0,0 +1,28 @@ +From 80cf912405c06254008e3c3766f438b8e0f03af7 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 27 Aug 2019 14:27:21 +0200 +Subject: [PATCH 53/55] KCM: Add a forgotten return +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Reviewed-by: Michal Židek +--- + src/responder/kcm/kcmsrv_ops.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c +index 1160c93f9..d8a7b03c5 100644 +--- a/src/responder/kcm/kcmsrv_ops.c ++++ b/src/responder/kcm/kcmsrv_ops.c +@@ -1685,6 +1685,7 @@ static void kcm_op_set_default_ccache_getbyname_done(struct tevent_req *subreq) + DEBUG(SSSDBG_TRACE_LIBS, + "The ccache does not exist, creating a new one\n"); + kcm_op_set_default_create_step(req); ++ return; + } else if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Cannot get ccache by name [%d]: %s\n", +-- +2.20.1 + diff --git a/SOURCES/0053-p11-Fix-two-instances-of-Wmaybe-uninitialized-in-p11.patch b/SOURCES/0053-p11-Fix-two-instances-of-Wmaybe-uninitialized-in-p11.patch deleted file mode 100644 index 831330d..0000000 --- a/SOURCES/0053-p11-Fix-two-instances-of-Wmaybe-uninitialized-in-p11.patch +++ /dev/null @@ -1,38 +0,0 @@ -From cc285823b8966fc03a511c5aa7332a385d8c47c1 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Fri, 12 Oct 2018 09:32:11 +0200 -Subject: [PATCH 53/57] p11: Fix two instances of -Wmaybe-uninitialized in - p11_child_openssl.c - -If uri_str was passed to the p11_child and parsing the URI failed, then -modules would be uninitialized, but freed in the done handler with -p11_kit_modules_finalize_and_release() - -Also, another warning is suppressed by setting the 's' variable to zero. -While it cannot happen that the variable will be uninitialized, we -should help the compiler by setting a value explicitly. - -Reviewed-by: Sumit Bose -(cherry picked from commit 7794caec36e7142423491d90aaade7e49b9df1c1) ---- - src/p11_child/p11_child_openssl.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c -index 9defdfc5a7acc70d0cea06d4919b06b93eb33c7b..adfe272e069bd0742caa1584153eb483e737e45b 100644 ---- a/src/p11_child/p11_child_openssl.c -+++ b/src/p11_child/p11_child_openssl.c -@@ -1036,8 +1036,8 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - { - int ret; - size_t c; -- size_t s; -- CK_FUNCTION_LIST **modules; -+ size_t s = 0; -+ CK_FUNCTION_LIST **modules = NULL; - CK_FUNCTION_LIST *module = NULL; - char *mod_name; - char *mod_file_name; --- -2.14.4 - diff --git a/SOURCES/0054-KCM-Allow-modifications-of-ccache-s-principal.patch b/SOURCES/0054-KCM-Allow-modifications-of-ccache-s-principal.patch new file mode 100644 index 0000000..c60f90c --- /dev/null +++ b/SOURCES/0054-KCM-Allow-modifications-of-ccache-s-principal.patch @@ -0,0 +1,188 @@ +From 436cf4c15b7659b21205affd6743aa6159c55b5c Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 28 Aug 2019 14:22:49 +0200 +Subject: [PATCH 54/55] KCM: Allow modifications of ccache's principal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Related: +https://pagure.io/SSSD/sssd/issue/4017 + +This patch will be useful to fix credential delegation. + +Reviewed-by: Michal Židek +--- + src/responder/kcm/kcmsrv_ccache.c | 37 +++++++++++++++++++++-- + src/responder/kcm/kcmsrv_ccache.h | 5 +-- + src/responder/kcm/kcmsrv_ccache_mem.c | 8 ++++- + src/responder/kcm/kcmsrv_ccache_secdb.c | 8 ++++- + src/responder/kcm/kcmsrv_ccache_secrets.c | 9 +++++- + src/responder/kcm/kcmsrv_ops.c | 4 +-- + 6 files changed, 60 insertions(+), 11 deletions(-) + +diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c +index 085cc4464..e24da9aa2 100644 +--- a/src/responder/kcm/kcmsrv_ccache.c ++++ b/src/responder/kcm/kcmsrv_ccache.c +@@ -1089,25 +1089,56 @@ errno_t kcm_ccdb_create_cc_recv(struct tevent_req *req) + return EOK; + } + +-void kcm_mod_ctx_clear(struct kcm_mod_ctx *mod_ctx) ++static void kcm_mod_ctx_clear(struct kcm_mod_ctx *mod_ctx) + { + if (mod_ctx == NULL) { + return; + } + + mod_ctx->kdc_offset = INT32_MAX; ++ if (mod_ctx->client != NULL) { ++ krb5_free_principal(NULL, mod_ctx->client); ++ mod_ctx->client = NULL; ++ } ++ ++ return; ++} ++ ++struct kcm_mod_ctx *kcm_mod_ctx_new(TALLOC_CTX *mem_ctx) ++{ ++ struct kcm_mod_ctx *mod_ctx; ++ ++ mod_ctx = talloc_zero(mem_ctx, struct kcm_mod_ctx); ++ if (mod_ctx == NULL) { ++ return NULL; ++ } ++ ++ kcm_mod_ctx_clear(mod_ctx); ++ return mod_ctx; + } + +-void kcm_mod_cc(struct kcm_ccache *cc, struct kcm_mod_ctx *mod_ctx) ++errno_t kcm_mod_cc(struct kcm_ccache *cc, struct kcm_mod_ctx *mod_ctx) + { + if (cc == NULL || mod_ctx == NULL) { +- return; ++ return EINVAL; + } + + if (mod_ctx->kdc_offset != INT32_MAX) { + cc->kdc_offset = mod_ctx->kdc_offset; + } + ++ if (mod_ctx->client != NULL) { ++ krb5_error_code kret; ++ ++ kret = krb5_copy_principal(NULL, mod_ctx->client, &cc->client); ++ if (kret != 0) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "krb5_copy_principal failed: %d\n", kret); ++ return ERR_INTERNAL; ++ } ++ } ++ ++ return EOK; + } + + struct kcm_ccdb_mod_cc_state { +diff --git a/src/responder/kcm/kcmsrv_ccache.h b/src/responder/kcm/kcmsrv_ccache.h +index 199b75b16..220220ca9 100644 +--- a/src/responder/kcm/kcmsrv_ccache.h ++++ b/src/responder/kcm/kcmsrv_ccache.h +@@ -257,13 +257,14 @@ errno_t kcm_ccdb_create_cc_recv(struct tevent_req *req); + */ + struct kcm_mod_ctx { + int32_t kdc_offset; ++ krb5_principal client; + /* More settable properties (like name, when we support renames + * will be added later + */ + }; + +-void kcm_mod_ctx_clear(struct kcm_mod_ctx *mod_ctx); +-void kcm_mod_cc(struct kcm_ccache *cc, struct kcm_mod_ctx *mod_ctx); ++struct kcm_mod_ctx *kcm_mod_ctx_new(TALLOC_CTX *mem_ctx); ++errno_t kcm_mod_cc(struct kcm_ccache *cc, struct kcm_mod_ctx *mod_ctx); + + struct tevent_req *kcm_ccdb_mod_cc_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, +diff --git a/src/responder/kcm/kcmsrv_ccache_mem.c b/src/responder/kcm/kcmsrv_ccache_mem.c +index 35955b2f4..18c3878ad 100644 +--- a/src/responder/kcm/kcmsrv_ccache_mem.c ++++ b/src/responder/kcm/kcmsrv_ccache_mem.c +@@ -676,7 +676,13 @@ static struct tevent_req *ccdb_mem_mod_send(TALLOC_CTX *mem_ctx, + goto immediate; + } + +- kcm_mod_cc(ccwrap->cc, mod_cc); ++ ret = kcm_mod_cc(ccwrap->cc, mod_cc); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Cannot modify ccache [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ goto immediate; ++ } + + ret = EOK; + immediate: +diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c +index 26ee1032d..32137a66e 100644 +--- a/src/responder/kcm/kcmsrv_ccache_secdb.c ++++ b/src/responder/kcm/kcmsrv_ccache_secdb.c +@@ -1290,7 +1290,13 @@ static struct tevent_req *ccdb_secdb_mod_send(TALLOC_CTX *mem_ctx, + goto immediate; + } + +- kcm_mod_cc(cc, mod_cc); ++ ret = kcm_mod_cc(cc, mod_cc); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Cannot modify ccache [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ goto immediate; ++ } + + ret = kcm_ccache_to_sec_input(state, cc, client, &payload); + if (ret != EOK) { +diff --git a/src/responder/kcm/kcmsrv_ccache_secrets.c b/src/responder/kcm/kcmsrv_ccache_secrets.c +index 7b019fded..83c16974d 100644 +--- a/src/responder/kcm/kcmsrv_ccache_secrets.c ++++ b/src/responder/kcm/kcmsrv_ccache_secrets.c +@@ -1846,7 +1846,14 @@ static void ccdb_sec_mod_cred_get_done(struct tevent_req *subreq) + return; + } + +- kcm_mod_cc(cc, state->mod_cc); ++ ret = kcm_mod_cc(cc, state->mod_cc); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Cannot modify ccache [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ tevent_req_error(req, ret); ++ return; ++ } + + ret = kcm_ccache_to_sec_kv(state, cc, state->client, &url, &payload); + if (ret != EOK) { +diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c +index d8a7b03c5..8bd63165b 100644 +--- a/src/responder/kcm/kcmsrv_ops.c ++++ b/src/responder/kcm/kcmsrv_ops.c +@@ -1990,13 +1990,11 @@ static void kcm_op_set_kdc_offset_getbyname_done(struct tevent_req *subreq) + return; + } + +- mod_ctx = talloc(state, struct kcm_mod_ctx); ++ mod_ctx = kcm_mod_ctx_new(state); + if (mod_ctx == NULL) { + tevent_req_error(req, ENOMEM); + return; + } +- +- kcm_mod_ctx_clear(mod_ctx); + mod_ctx->kdc_offset = be32toh(offset_be); + + subreq = kcm_ccdb_mod_cc_send(state, +-- +2.20.1 + diff --git a/SOURCES/0054-sudo-use-correct-sbus-interface.patch b/SOURCES/0054-sudo-use-correct-sbus-interface.patch deleted file mode 100644 index 7122888..0000000 --- a/SOURCES/0054-sudo-use-correct-sbus-interface.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 7c4b21ff0b9cf12ff520b4eace848ac83b3b47d2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Mon, 15 Oct 2018 12:46:35 +0200 -Subject: [PATCH 54/57] sudo: use correct sbus interface - -Internal dbus interfaces were renamed to shorter names in sbus2. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3854 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 250e82252b53991e2902b292cfa6029ab28a10fb) ---- - src/responder/sudo/sudosrv_dp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/responder/sudo/sudosrv_dp.c b/src/responder/sudo/sudosrv_dp.c -index 2c6b26eae1d5d6a1a16658101c6ef526608513cb..78dd296ecdd8dc8389fcf6bce804926d3522e692 100644 ---- a/src/responder/sudo/sudosrv_dp.c -+++ b/src/responder/sudo/sudosrv_dp.c -@@ -66,7 +66,7 @@ sss_dp_get_sudoers_msg(TALLOC_CTX *mem_ctx, - - msg = dbus_message_new_method_call(bus_name, - SSS_BUS_PATH, -- "org.freedesktop.sssd.dataprovider", -+ "sssd.dataprovider", - "sudoHandler"); - if (msg == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); --- -2.14.4 - diff --git a/SOURCES/0055-KCM-Fill-empty-cache-do-not-initialize-a-new-one.patch b/SOURCES/0055-KCM-Fill-empty-cache-do-not-initialize-a-new-one.patch new file mode 100644 index 0000000..1a7d461 --- /dev/null +++ b/SOURCES/0055-KCM-Fill-empty-cache-do-not-initialize-a-new-one.patch @@ -0,0 +1,160 @@ +From dbcd8411643a641316696f221860517ab06879ba Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 28 Aug 2019 14:23:18 +0200 +Subject: [PATCH 55/55] KCM: Fill empty cache, do not initialize a new one +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Related: +https://pagure.io/SSSD/sssd/issue/4017 + +openssh uses this sequence of calls: + gen_new() + switch() + initialize() + +What happened before was that if there was already some cache, gen_new +would create a new empty cache, then switch would set it as the default. +But then, during the initialize call, the cache that used to be the +default was deleted, another one created and used as the default. This +meant. Afterwards, KCM would store the credentials in the previous +cache, which would no longer be the default. + +The logic behind was that KCM didn't anticipate the client generating +the new and setting the default on its own. + +Reviewed-by: Michal Židek +--- + src/responder/kcm/kcmsrv_ops.c | 84 +++++++++++++++++++++++++++++++++- + 1 file changed, 82 insertions(+), 2 deletions(-) + +diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c +index 8bd63165b..2181ec6e6 100644 +--- a/src/responder/kcm/kcmsrv_ops.c ++++ b/src/responder/kcm/kcmsrv_ops.c +@@ -367,6 +367,8 @@ struct kcm_op_initialize_state { + static void kcm_op_initialize_got_byname(struct tevent_req *subreq); + static void kcm_op_initialize_cc_create_done(struct tevent_req *subreq); + static void kcm_op_initialize_cc_delete_done(struct tevent_req *subreq); ++static void kcm_op_initialize_fill_princ_step(struct tevent_req *req); ++static void kcm_op_initialize_fill_princ_done(struct tevent_req *subreq); + static void kcm_op_initialize_create_step(struct tevent_req *req); + static void kcm_op_initialize_got_default(struct tevent_req *subreq); + static void kcm_op_initialize_set_default_done(struct tevent_req *subreq); +@@ -450,6 +452,15 @@ static void kcm_op_initialize_got_byname(struct tevent_req *subreq) + } + + if (state->new_cc != NULL) { ++ if (kcm_cc_get_client_principal(state->new_cc) == NULL) { ++ /* This is a cache that was pre-created w/o a principal (sshd does this), ++ * let's fill in the principal and set the cache as default if not ++ * already ++ */ ++ kcm_op_initialize_fill_princ_step(req); ++ return; ++ } ++ + ok = kcm_cc_access(state->new_cc, state->op_ctx->client); + if (!ok) { + state->op_ret = EACCES; +@@ -501,6 +512,70 @@ static void kcm_op_initialize_cc_delete_done(struct tevent_req *subreq) + kcm_op_initialize_create_step(req); + } + ++static void kcm_op_initialize_fill_princ_step(struct tevent_req *req) ++{ ++ struct tevent_req *subreq; ++ struct kcm_op_initialize_state *state = tevent_req_data(req, ++ struct kcm_op_initialize_state); ++ errno_t ret; ++ struct kcm_mod_ctx *mod_ctx; ++ uuid_t uuid; ++ ++ mod_ctx = kcm_mod_ctx_new(state); ++ if (mod_ctx == NULL) { ++ tevent_req_error(req, ENOMEM); ++ return; ++ } ++ mod_ctx->client = state->princ; ++ ++ ret = kcm_cc_get_uuid(state->new_cc, uuid); ++ if (ret != EOK) { ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ subreq = kcm_ccdb_mod_cc_send(state, ++ state->ev, ++ state->op_ctx->kcm_data->db, ++ state->op_ctx->client, ++ uuid, ++ mod_ctx); ++ if (subreq == NULL) { ++ tevent_req_error(req, ENOMEM); ++ return; ++ } ++ tevent_req_set_callback(subreq, kcm_op_initialize_fill_princ_done, req); ++} ++ ++static void kcm_op_initialize_fill_princ_done(struct tevent_req *subreq) ++{ ++ struct tevent_req *req = tevent_req_callback_data(subreq, ++ struct tevent_req); ++ struct kcm_op_initialize_state *state = tevent_req_data(req, ++ struct kcm_op_initialize_state); ++ errno_t ret; ++ ++ ret = kcm_ccdb_mod_cc_recv(subreq); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Cannot modify ccache [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ /* Make sure the cache we just initialized is the default one */ ++ subreq = kcm_ccdb_get_default_send(state, state->ev, ++ state->op_ctx->kcm_data->db, ++ state->op_ctx->client); ++ if (subreq == NULL) { ++ tevent_req_error(req, ret); ++ return; ++ } ++ tevent_req_set_callback(subreq, kcm_op_initialize_got_default, req); ++} ++ + static void kcm_op_initialize_create_step(struct tevent_req *req) + { + struct tevent_req *subreq; +@@ -588,11 +663,14 @@ static void kcm_op_initialize_got_default(struct tevent_req *subreq) + ret = kcm_cc_get_uuid(state->new_cc, dfl_uuid); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +- "Cannot get new ccache UUID [%d]: %s\n", +- ret, sss_strerror(ret)); ++ "Cannot get new ccache UUID [%d]: %s\n", ++ ret, sss_strerror(ret)); + return; + } + ++ DEBUG(SSSDBG_TRACE_FUNC, ++ "The default ccached was not set, switching to the " ++ "initialized\n"); + subreq = kcm_ccdb_set_default_send(state, + state->ev, + state->op_ctx->kcm_data->db, +@@ -1756,6 +1834,8 @@ static void kcm_op_set_default_create_step_done(struct tevent_req *subreq) + return; + } + ++ DEBUG(SSSDBG_TRACE_FUNC, "The ccache was created, switching to it"); ++ + ret = kcm_cc_get_uuid(state->new_cc, state->dfl_uuid); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +-- +2.20.1 + diff --git a/SOURCES/0055-sudo-fix-error-handling-in-sudosrv_refresh_rules_don.patch b/SOURCES/0055-sudo-fix-error-handling-in-sudosrv_refresh_rules_don.patch deleted file mode 100644 index c7ca404..0000000 --- a/SOURCES/0055-sudo-fix-error-handling-in-sudosrv_refresh_rules_don.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 402f63b5a3b42797ec2b3e2ad53e50d198eb98b4 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Mon, 15 Oct 2018 13:01:34 +0200 -Subject: [PATCH 55/57] sudo: fix error handling in sudosrv_refresh_rules_done - -If sbus returns non-zero code then the output variables are not set and -therefore we access uninitialized memory. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3854 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 8fbaf224193b9ca8b82a290bd52265c2f9b40315) ---- - src/responder/sudo/sudosrv_get_sudorules.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c -index 14bd824775fea47fd28ca4880d31cfc67b03d0da..76faef0f566235324999a9a85246dd960119cab3 100644 ---- a/src/responder/sudo/sudosrv_get_sudorules.c -+++ b/src/responder/sudo/sudosrv_get_sudorules.c -@@ -576,10 +576,15 @@ static void sudosrv_refresh_rules_done(struct tevent_req *subreq) - ret = sss_dp_get_sudoers_recv(state, subreq, &err_maj, &err_min, &err_msg); - talloc_zfree(subreq); - if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to refresh rules [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ goto done; -+ } else if (err_maj != 0 || err_min != 0) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Unable to get information from Data Provider, " - "Error: %u, %u, %s\n", -- (unsigned int)err_maj, (unsigned int)err_min, err_msg); -+ (unsigned int)err_maj, (unsigned int)err_min, -+ (err_msg == NULL ? "(null)" : err_msg)); - goto done; - } - --- -2.14.4 - diff --git a/SOURCES/0056-files-add-session-recording-flag.patch b/SOURCES/0056-files-add-session-recording-flag.patch deleted file mode 100644 index 440e9b7..0000000 --- a/SOURCES/0056-files-add-session-recording-flag.patch +++ /dev/null @@ -1,136 +0,0 @@ -From 21087821ab7942a54168d545ea2f96a6f7582344 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 15 Oct 2018 20:05:09 +0200 -Subject: [PATCH 56/57] files: add session recording flag - -If session recording is configured for a group the NSS ans PAM -responder rely on a attribute in the cache set by the backend to -determine is session recording is configured for the user or not. This -flag is typically set during the initgroups request. - -Since the files provider does not have a dedicated initgroups request -the attribute must be set otherwise. This patch sets is for all users -after the files are reloaded. - -Related to https://pagure.io/SSSD/sssd/issue/3855 - -Reviewed-by: Jakub Hrozek ---- - src/providers/data_provider/dp_iface.h | 3 ++ - src/providers/data_provider/dp_target_id.c | 62 ++++++++++++++++++++++++++++++ - src/providers/files/files_ops.c | 7 ++++ - 3 files changed, 72 insertions(+) - -diff --git a/src/providers/data_provider/dp_iface.h b/src/providers/data_provider/dp_iface.h -index 0b0855da6c62d01d523486fe65e9920578ba58e5..8f6b2076c1adb8ad046a0d03ae5ae8a0600a5707 100644 ---- a/src/providers/data_provider/dp_iface.h -+++ b/src/providers/data_provider/dp_iface.h -@@ -188,4 +188,7 @@ errno_t - dp_access_control_refresh_rules_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req); - -+ -+errno_t -+dp_add_sr_attribute(struct be_ctx *be_ctx); - #endif /* DP_IFACE_H_ */ -diff --git a/src/providers/data_provider/dp_target_id.c b/src/providers/data_provider/dp_target_id.c -index 265788be9b032fcdf0f354f9c66a98241aa17916..748d886748f34e6b99c6bfc0f7607e048cbd2425 100644 ---- a/src/providers/data_provider/dp_target_id.c -+++ b/src/providers/data_provider/dp_target_id.c -@@ -328,6 +328,68 @@ done: - talloc_free(tmp_ctx); - } - -+errno_t dp_add_sr_attribute(struct be_ctx *be_ctx) -+{ -+ int ret; -+ struct dp_initgr_ctx *dp_initgr_ctx = NULL; -+ TALLOC_CTX *tmp_ctx = NULL; -+ struct dp_id_data *data; -+ size_t msgs_count; -+ struct ldb_message **msgs = NULL; -+ const char *attrs[] = {SYSDB_NAME, NULL}; -+ size_t c; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); -+ return ENOMEM; -+ } -+ -+ ret = sysdb_search_users(tmp_ctx, be_ctx->domain, "("SYSDB_NAME "=*)", attrs, -+ &msgs_count, &msgs); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_users failed.\n"); -+ goto done; -+ } -+ -+ data = talloc_zero(tmp_ctx, struct dp_id_data); -+ if (data == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ data->entry_type = BE_REQ_INITGROUPS; -+ data->filter_type = BE_FILTER_NAME; -+ data->filter_value = NULL; -+ data->extra_value = NULL; -+ data->domain = be_ctx->domain->name; -+ -+ for (c = 0; c < msgs_count; c++) { -+ data->filter_value = ldb_msg_find_attr_as_string(msgs[c], SYSDB_NAME, -+ NULL); -+ if (data->filter_value == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Cache object [%s] does not have a name, skipping.\n", -+ ldb_dn_get_linearized(msgs[c]->dn)); -+ continue; -+ } -+ -+ talloc_free(dp_initgr_ctx); -+ ret = dp_create_initgroups_ctx(tmp_ctx, be_ctx, data, &dp_initgr_ctx); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "dp_create_initgroups_ctx failed.\n"); -+ goto done; -+ } -+ -+ dp_req_initgr_pp_sr_overlay(be_ctx->provider, dp_initgr_ctx); -+ } -+ -+done: -+ talloc_free(tmp_ctx); -+ -+ return ret; -+} -+ - static errno_t set_initgroups_expire_attribute(struct sss_domain_info *domain, - const char *name) - { -diff --git a/src/providers/files/files_ops.c b/src/providers/files/files_ops.c -index f5a40297a7cd1eb4ec66315250556ddaf6cc8cfc..74f77b5395285818d049eaa521b4afd8a9c89dde 100644 ---- a/src/providers/files/files_ops.c -+++ b/src/providers/files/files_ops.c -@@ -26,6 +26,7 @@ - #include "db/sysdb.h" - #include "util/inotify.h" - #include "util/util.h" -+#include "providers/data_provider/dp_iface.h" - - /* When changing this constant, make sure to also adjust the files integration - * test for reallocation branch -@@ -771,6 +772,12 @@ static errno_t sf_enum_files(struct files_id_ctx *id_ctx, - } - } - -+ ret = dp_add_sr_attribute(id_ctx->be); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to add session recording attribute, ignored.\n"); -+ } -+ - ret = sysdb_transaction_commit(id_ctx->domain->sysdb); - if (ret != EOK) { - goto done; --- -2.14.4 - diff --git a/SOURCES/0057-UTIL-Suppress-Coverity-warning.patch b/SOURCES/0057-UTIL-Suppress-Coverity-warning.patch deleted file mode 100644 index dff7c19..0000000 --- a/SOURCES/0057-UTIL-Suppress-Coverity-warning.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 4a9c9aa6dcfa09ca9ff24b7d22a37f2fdba4ee3f Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 16 Oct 2018 10:42:43 +0200 -Subject: [PATCH 57/57] UTIL: Suppress Coverity warning - -We recently added this code: - if (domain_name != NULL - && is_files_provider(find_domain_by_name(dom, - domain_name, - false))) - -find_domain_by_name returns NULL if the domain_name can't be found. This -of course makes mostly sense for trusted domains that can appear and -disappear. And is_files_provider() didn't handle the situation where the -domain pointer was NULL and would directly dereference it. - -This commit just adds a NULL check for the domain pointer so that -is_files_provider() returns 'false' if the domain pointer was NULL. - -Another alternative might be to check the return value of -find_domain_by_name(), but I don't think it's worth the trouble. - -Reviewed-by: Sumit Bose ---- - src/util/domain_info_utils.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c -index 8bef6c9af382ad55e14368b76dd4af7a53ea809b..ffb8cdf102c3ef92b4e8059d846f6b15b835ce69 100644 ---- a/src/util/domain_info_utils.c -+++ b/src/util/domain_info_utils.c -@@ -931,6 +931,7 @@ bool sss_domain_info_get_output_fqnames(struct sss_domain_info *domain) - - bool is_files_provider(struct sss_domain_info *domain) - { -- return domain->provider != NULL && -+ return domain != NULL && -+ domain->provider != NULL && - strcasecmp(domain->provider, "files") == 0; - } --- -2.14.4 - diff --git a/SOURCES/0058-PYSSS-Re-add-the-pysss.getgrouplist-interface.patch b/SOURCES/0058-PYSSS-Re-add-the-pysss.getgrouplist-interface.patch deleted file mode 100644 index 399c5c7..0000000 --- a/SOURCES/0058-PYSSS-Re-add-the-pysss.getgrouplist-interface.patch +++ /dev/null @@ -1,121 +0,0 @@ -From f0603645f5ea5f707875807b4f815400f4b79e41 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Wed, 24 Oct 2018 09:41:44 +0200 -Subject: [PATCH] PYSSS: Re-add the pysss.getgrouplist() interface - -Related: -https://pagure.io/SSSD/sssd/issue/3493 - -Commit 0e211b8ba30c3adcdeef21ca1339b194cbfffb04 was supposed to remove -only the parts of the pysss API that relate to the local domain. But it -removed also the getgrouplist() method by accident. This method is very -important to IPA, so we need to add it back. - -Reviewed-by: Alexander Bokovoy ---- - src/python/pysss.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 83 insertions(+) - -diff --git a/src/python/pysss.c b/src/python/pysss.c -index e92653a9e4cb4fdfef14b0ab3e297b1d469ad1dc..78b8de0739f8184bd5411e51d99c2baf5ce48057 100644 ---- a/src/python/pysss.c -+++ b/src/python/pysss.c -@@ -215,12 +215,95 @@ static PyTypeObject pysss_password_type = { - .tp_doc = sss_py_const_p(char, "SSS password obfuscation"), - }; - -+/* -+ * Get list of groups user belongs to -+ */ -+PyDoc_STRVAR(py_sss_getgrouplist__doc__, -+ "Get list of groups user belongs to.\n\n" -+ "NOTE: The interface uses the system NSS calls and is not limited to " -+ "users served by the SSSD!\n" -+ ":param username: name of user to get list for\n"); -+ -+static PyObject *py_sss_getgrouplist(PyObject *self, PyObject *args) -+{ -+ char *username = NULL; -+ gid_t *groups = NULL; -+ struct passwd *pw; -+ struct group *gr; -+ int ngroups; -+ int ret; -+ Py_ssize_t i, idx; -+ PyObject *groups_tuple; -+ -+ if(!PyArg_ParseTuple(args, discard_const_p(char, "s"), &username)) { -+ goto fail; -+ } -+ -+ pw = getpwnam(username); -+ if (pw == NULL) { -+ goto fail; -+ } -+ -+ ngroups = 32; -+ groups = malloc(sizeof(gid_t) * ngroups); -+ if (groups == NULL) { -+ goto fail; -+ } -+ -+ do { -+ ret = getgrouplist(username, pw->pw_gid, groups, &ngroups); -+ if (ret < ngroups) { -+ gid_t *tmp_groups = realloc(groups, ngroups * sizeof(gid_t)); -+ if (tmp_groups == NULL) { -+ goto fail; -+ } -+ groups = tmp_groups; -+ } -+ } while (ret != ngroups); -+ -+ groups_tuple = PyTuple_New((Py_ssize_t) ngroups); -+ if (groups_tuple == NULL) { -+ goto fail; -+ } -+ -+ /* Populate a tuple with names of groups -+ * In unlikely case of group not being able to resolve, skip it -+ * We also need to resize resulting tuple to avoid empty elements there */ -+ idx = 0; -+ for (i = 0; i < ngroups; i++) { -+ gr = getgrgid(groups[i]); -+ if (gr) { -+ PyTuple_SetItem(groups_tuple, idx, -+#ifdef IS_PY3K -+ PyUnicode_FromString(gr->gr_name) -+#else -+ PyString_FromString(gr->gr_name) -+#endif -+ ); -+ idx++; -+ } -+ } -+ free(groups); -+ groups = NULL; -+ -+ if (i != idx) { -+ _PyTuple_Resize(&groups_tuple, idx); -+ } -+ -+ return groups_tuple; -+ -+fail: -+ free(groups); -+ return NULL; -+} -+ - /* ==================== the sss module initialization =======================*/ - - /* - * Module methods - */ - static PyMethodDef module_methods[] = { -+ {"getgrouplist", py_sss_getgrouplist, METH_VARARGS, py_sss_getgrouplist__doc__}, - {NULL, NULL, 0, NULL} /* Sentinel */ - }; - --- -2.14.4 - diff --git a/SOURCES/0059-ifp-fix-typo-causing-a-crash-in-FindByNameAndCertifi.patch b/SOURCES/0059-ifp-fix-typo-causing-a-crash-in-FindByNameAndCertifi.patch deleted file mode 100644 index 7509f03..0000000 --- a/SOURCES/0059-ifp-fix-typo-causing-a-crash-in-FindByNameAndCertifi.patch +++ /dev/null @@ -1,46 +0,0 @@ -From b4063b2d3f1c700aa074f71d5db501e1bdfd6d2a Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 24 Oct 2018 17:27:21 +0200 -Subject: [PATCH] ifp: fix typo causing a crash in FindByNameAndCertificate - -Due to a typo in the recent refactoring the InfoPipe crashes in the -FindByNameAndCertificate request. - -Additionally a state variable in set to the expected value. - -Related to https://pagure.io/SSSD/sssd/issue/3863 - -Reviewed-by: Jakub Hrozek ---- - src/responder/ifp/ifp_users.c | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c -index dd44afcc45df5c29e3a9926bf42cd416e3445d77..5dd34d68808fa0230d77de1fd3805b5971cb9aa6 100644 ---- a/src/responder/ifp/ifp_users.c -+++ b/src/responder/ifp/ifp_users.c -@@ -584,6 +584,12 @@ ifp_users_find_by_name_and_cert_send(TALLOC_CTX *mem_ctx, - } - - if (!SBUS_REQ_STRING_IS_EMPTY(pem_cert)) { -+ state->pem_cert = talloc_strdup(state, pem_cert); -+ if (state->pem_cert == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ - ret = sss_cert_pem_to_derb64(state, pem_cert, &state->derb64); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sss_cert_pem_to_derb64 failed.\n"); -@@ -741,7 +747,7 @@ static void ifp_users_find_by_name_and_cert_done(struct tevent_req *subreq) - return; - } - -- ret = ifp_users_list_by_cert_step(req); -+ ret = ifp_users_find_by_name_and_cert_step(req); - if (ret == EOK) { - tevent_req_done(req); - } else if (ret != EAGAIN) { --- -2.14.4 - diff --git a/SOURCES/0060-IFP-Use-subreq-not-req-when-calling-RefreshRules_rec.patch b/SOURCES/0060-IFP-Use-subreq-not-req-when-calling-RefreshRules_rec.patch deleted file mode 100644 index 0c5e349..0000000 --- a/SOURCES/0060-IFP-Use-subreq-not-req-when-calling-RefreshRules_rec.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0882793e4ba018073c2db9ab390bcdf16276b65f Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 5 Nov 2018 10:53:24 +0100 -Subject: [PATCH] IFP: Use subreq, not req when calling RefreshRules_recv -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This emits a failure when refreshing access control rules from e.g. -sssctl access-report. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3874 - -Reviewed-by: Pavel Březina ---- - src/responder/ifp/ifp_domains.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/responder/ifp/ifp_domains.c b/src/responder/ifp/ifp_domains.c -index ac09f23c6..2020b7580 100644 ---- a/src/responder/ifp/ifp_domains.c -+++ b/src/responder/ifp/ifp_domains.c -@@ -1001,7 +1001,7 @@ static void ifp_domains_domain_refresh_access_rules_done(struct tevent_req *subr - - req = tevent_req_callback_data(subreq, struct tevent_req); - -- ret = sbus_call_dp_access_RefreshRules_recv(req); -+ ret = sbus_call_dp_access_RefreshRules_recv(subreq); - talloc_zfree(subreq); - if (ret != EOK) { - tevent_req_error(req, ret); --- -2.19.1 - diff --git a/SOURCES/0061-INI-Return-errno-not-1-on-failure-from-sss_ini_get_s.patch b/SOURCES/0061-INI-Return-errno-not-1-on-failure-from-sss_ini_get_s.patch deleted file mode 100644 index 2452780..0000000 --- a/SOURCES/0061-INI-Return-errno-not-1-on-failure-from-sss_ini_get_s.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 8007d6150a37c39881418e7f2b32129a5e4cb9e7 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 23 Oct 2018 23:12:20 +0200 -Subject: [PATCH 61/66] INI: Return errno, not -1 on failure from - sss_ini_get_stat -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -sss_ini_get_stat() has two branches for two libini versions. The newer -version directly returns EIO on failure, but the old version would have -returned the return value from fstat() directly. And fstat() returns -1 -on failure but sets errno. This patch returns errno on failure and EOK -on success. - -Reviewed-by: Michal Židek ---- - src/util/sss_ini.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/src/util/sss_ini.c b/src/util/sss_ini.c -index 175a4cfab..9a059fc00 100644 ---- a/src/util/sss_ini.c -+++ b/src/util/sss_ini.c -@@ -156,8 +156,13 @@ int sss_ini_get_stat(struct sss_ini_initdata *init_data) - - return EOK; - #else -+ int ret; - -- return fstat(init_data->file, &init_data->cstat); -+ ret = fstat(init_data->file, &init_data->cstat); -+ if (ret != 0) { -+ return errno; -+ } -+ return EOK; - #endif - } - --- -2.19.1 - diff --git a/SOURCES/0062-MONITOR-Don-t-check-for-pidfile-if-SSSD-is-already-r.patch b/SOURCES/0062-MONITOR-Don-t-check-for-pidfile-if-SSSD-is-already-r.patch deleted file mode 100644 index 824a2a6..0000000 --- a/SOURCES/0062-MONITOR-Don-t-check-for-pidfile-if-SSSD-is-already-r.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 4b52ed0610e399a0fe27cfab3601419acb6aff3d Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Fri, 5 Oct 2018 13:50:37 +0200 -Subject: [PATCH 62/66] MONITOR: Don't check for pidfile if SSSD is already - running -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related: -https://pagure.io/SSSD/sssd/issue/3862 - -The --genconf option of sssd is meant to be used to reload configuration from a -systemd socket-activated service. But it would only work if sssd was not -running, which defies its purpose. - -Reviewed-by: Michal Židek ---- - src/monitor/monitor.c | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) - -diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c -index 335b2070b..ea689c604 100644 ---- a/src/monitor/monitor.c -+++ b/src/monitor/monitor.c -@@ -2514,13 +2514,17 @@ int main(int argc, const char *argv[]) - } - } - -- /* Check if the SSSD is already running */ -- ret = check_file(SSSD_PIDFILE, 0, 0, S_IFREG|0600, 0, NULL, false); -- if (ret == EOK) { -- DEBUG(SSSDBG_FATAL_FAILURE, -- "pidfile exists at %s\n", SSSD_PIDFILE); -- ERROR("SSSD is already running\n"); -- return 2; -+ /* Check if the SSSD is already running unless we're only interested -+ * in re-reading the configuration -+ */ -+ if (opt_genconf == 0) { -+ ret = check_file(SSSD_PIDFILE, 0, 0, S_IFREG|0600, 0, NULL, false); -+ if (ret == EOK) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "pidfile exists at %s\n", SSSD_PIDFILE); -+ ERROR("SSSD is already running\n"); -+ return 2; -+ } - } - - /* Parse config file, fail if cannot be done */ --- -2.19.1 - diff --git a/SOURCES/0063-SSSD-Allow-refreshing-only-certain-section-with-genc.patch b/SOURCES/0063-SSSD-Allow-refreshing-only-certain-section-with-genc.patch deleted file mode 100644 index 6af1af1..0000000 --- a/SOURCES/0063-SSSD-Allow-refreshing-only-certain-section-with-genc.patch +++ /dev/null @@ -1,399 +0,0 @@ -From 92b8f8d404bfe72abe8cd324f5569be5ba2c6db1 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 9 Oct 2018 15:32:12 +0200 -Subject: [PATCH 63/66] SSSD: Allow refreshing only certain section with - --genconf -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related: -https://pagure.io/SSSD/sssd/issue/3862 - -Adds a new option --genconf-section for the sssd binary. If this new -option --genconf-section is used, then only the section passed as this -option's value is refreshed. - -Conversely, if this section no longer exists in the config file, then it -is removed from the confdb - -Reviewed-by: Michal Židek ---- - src/confdb/confdb_setup.c | 80 +++++++++++++++++++++++++++--------- - src/confdb/confdb_setup.h | 1 + - src/man/sssd.8.xml | 27 ++++++++++++ - src/monitor/monitor.c | 17 +++++++- - src/tools/common/sss_tools.c | 1 + - src/util/sss_ini.c | 54 ++++++++++++++++++++++++ - src/util/sss_ini.h | 1 + - 7 files changed, 160 insertions(+), 21 deletions(-) - -diff --git a/src/confdb/confdb_setup.c b/src/confdb/confdb_setup.c -index c2b7f9f73..7acefbe6b 100644 ---- a/src/confdb/confdb_setup.c -+++ b/src/confdb/confdb_setup.c -@@ -138,6 +138,7 @@ static int confdb_create_base(struct confdb_ctx *cdb) - static int confdb_ldif_from_ini_file(TALLOC_CTX *mem_ctx, - const char *config_file, - const char *config_dir, -+ const char *only_section, - struct sss_ini_initdata *init_data, - const char **_timestr, - const char **_ldif) -@@ -222,7 +223,7 @@ static int confdb_ldif_from_ini_file(TALLOC_CTX *mem_ctx, - } - } - -- ret = sss_confdb_create_ldif(mem_ctx, init_data, _ldif); -+ ret = sss_confdb_create_ldif(mem_ctx, init_data, only_section, _ldif); - if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, "Could not create LDIF for confdb\n"); - return ret; -@@ -249,7 +250,50 @@ static int confdb_fallback_ldif(TALLOC_CTX *mem_ctx, - return EOK; - } - --static int confdb_init_db(const char *config_file, const char *config_dir, -+static int confdb_write_ldif(struct confdb_ctx *cdb, -+ const char *config_ldif, -+ bool replace_whole_db) -+{ -+ int ret; -+ struct ldb_ldif *ldif; -+ -+ while ((ldif = ldb_ldif_read_string(cdb->ldb, &config_ldif))) { -+ if (ldif->changetype == LDB_CHANGETYPE_DELETE) { -+ /* We should remove this section */ -+ ret = ldb_delete(cdb->ldb, ldif->msg->dn); -+ if (ret == LDB_ERR_NO_SUCH_OBJECT) { -+ /* Removing a non-existing section is not an error */ -+ ret = LDB_SUCCESS; -+ } -+ } else { -+ ret = ldb_add(cdb->ldb, ldif->msg); -+ if (ret != LDB_SUCCESS && replace_whole_db == false) { -+ /* This section already existed, remove and re-add it. We -+ * really want to replace the whole thing instead of messing -+ * around with changetypes and flags on individual elements -+ */ -+ ret = ldb_delete(cdb->ldb, ldif->msg->dn); -+ if (ret == LDB_SUCCESS) { -+ ret = ldb_add(cdb->ldb, ldif->msg); -+ } -+ } -+ } -+ -+ if (ret != LDB_SUCCESS) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "Failed to initialize DB (%d,[%s]), aborting!\n", -+ ret, ldb_errstring(cdb->ldb)); -+ return EIO; -+ } -+ ldb_ldif_read_free(cdb->ldb, ldif); -+ } -+ -+ return EOK; -+} -+ -+static int confdb_init_db(const char *config_file, -+ const char *config_dir, -+ const char *only_section, - struct confdb_ctx *cdb) - { - TALLOC_CTX *tmp_ctx; -@@ -259,7 +303,6 @@ static int confdb_init_db(const char *config_file, const char *config_dir, - const char *timestr = NULL; - const char *config_ldif; - const char *vals[2] = { NULL, NULL }; -- struct ldb_ldif *ldif; - struct sss_ini_initdata *init_data; - - tmp_ctx = talloc_new(cdb); -@@ -281,6 +324,7 @@ static int confdb_init_db(const char *config_file, const char *config_dir, - ret = confdb_ldif_from_ini_file(tmp_ctx, - config_file, - config_dir, -+ only_section, - init_data, - ×tr, - &config_ldif); -@@ -318,24 +362,21 @@ static int confdb_init_db(const char *config_file, const char *config_dir, - } - in_transaction = true; - -- /* Purge existing database */ -- ret = confdb_purge(cdb); -- if (ret != EOK) { -- DEBUG(SSSDBG_FATAL_FAILURE, -- "Could not purge existing configuration\n"); -- goto done; -- } -- -- while ((ldif = ldb_ldif_read_string(cdb->ldb, &config_ldif))) { -- ret = ldb_add(cdb->ldb, ldif->msg); -- if (ret != LDB_SUCCESS) { -+ /* Purge existing database, if we are reinitializing the confdb completely */ -+ if (only_section == NULL) { -+ ret = confdb_purge(cdb); -+ if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, -- "Failed to initialize DB (%d,[%s]), aborting!\n", -- ret, ldb_errstring(cdb->ldb)); -- ret = EIO; -+ "Could not purge existing configuration\n"); - goto done; - } -- ldb_ldif_read_free(cdb->ldb, ldif); -+ } -+ -+ ret = confdb_write_ldif(cdb, -+ config_ldif, -+ only_section == NULL ? true : false); -+ if (ret != EOK) { -+ goto done; - } - - /* now store the lastUpdate time so that we do not re-init if nothing -@@ -377,6 +418,7 @@ errno_t confdb_setup(TALLOC_CTX *mem_ctx, - const char *cdb_file, - const char *config_file, - const char *config_dir, -+ const char *only_section, - struct confdb_ctx **_cdb) - { - TALLOC_CTX *tmp_ctx; -@@ -432,7 +474,7 @@ errno_t confdb_setup(TALLOC_CTX *mem_ctx, - goto done; - } - -- ret = confdb_init_db(config_file, config_dir, cdb); -+ ret = confdb_init_db(config_file, config_dir, only_section, cdb); - if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, "ConfDB initialization has failed " - "[%d]: %s\n", ret, sss_strerror(ret)); -diff --git a/src/confdb/confdb_setup.h b/src/confdb/confdb_setup.h -index 9f647ec16..c7fe59541 100644 ---- a/src/confdb/confdb_setup.h -+++ b/src/confdb/confdb_setup.h -@@ -49,6 +49,7 @@ errno_t confdb_setup(TALLOC_CTX *mem_ctx, - const char *cdb_file, - const char *config_file, - const char *config_dir, -+ const char *only_section, - struct confdb_ctx **_cdb); - - #endif /* CONFDB_SETUP_H_ */ -diff --git a/src/man/sssd.8.xml b/src/man/sssd.8.xml -index f2cbe015b..ff3d8825d 100644 ---- a/src/man/sssd.8.xml -+++ b/src/man/sssd.8.xml -@@ -164,6 +164,33 @@ - - - -+ -+ -+ , -+ -+ -+ -+ Do not start the SSSD, but refresh the configuration -+ database from the contents of -+ /etc/sssd/sssd.conf and exit. -+ -+ -+ -+ -+ -+ , -+ -+ -+ -+ Similar to --genconf, but only refresh -+ a single section from the configuration file. This -+ option is useful mainly to be called from systemd -+ unit files to allow socket-activated responders -+ to refresh their configuration without requiring -+ the administrator to restart the whole SSSD. -+ -+ -+ - - - -diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c -index ea689c604..136cf8f27 100644 ---- a/src/monitor/monitor.c -+++ b/src/monitor/monitor.c -@@ -1579,6 +1579,7 @@ static int monitor_ctx_destructor(void *mem) - errno_t load_configuration(TALLOC_CTX *mem_ctx, - const char *config_file, - const char *config_dir, -+ const char *only_section, - struct mt_ctx **monitor) - { - errno_t ret; -@@ -1600,7 +1601,8 @@ errno_t load_configuration(TALLOC_CTX *mem_ctx, - goto done; - } - -- ret = confdb_setup(ctx, cdb_file, config_file, config_dir, &ctx->cdb); -+ ret = confdb_setup(ctx, cdb_file, config_file, config_dir, only_section, -+ &ctx->cdb); - if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, "Unable to setup ConfDB [%d]: %s\n", - ret, sss_strerror(ret)); -@@ -2329,6 +2331,7 @@ int main(int argc, const char *argv[]) - char *opt_config_file = NULL; - char *opt_logger = NULL; - char *config_file = NULL; -+ char *opt_genconf_section = NULL; - int flags = 0; - struct main_context *main_ctx; - TALLOC_CTX *tmp_ctx; -@@ -2352,6 +2355,9 @@ int main(int argc, const char *argv[]) - {"genconf", 'g', POPT_ARG_NONE, &opt_genconf, 0, \ - _("Refresh the configuration database, then exit"), \ - NULL}, \ -+ {"genconf-section", 's', POPT_ARG_STRING, &opt_genconf_section, 0, \ -+ _("Similar to --genconf, but only refreshes the given section"), \ -+ NULL}, \ - {"version", '\0', POPT_ARG_NONE, &opt_version, 0, \ - _("Print version number and exit"), NULL }, \ - POPT_TABLEEND -@@ -2378,6 +2384,13 @@ int main(int argc, const char *argv[]) - return EXIT_SUCCESS; - } - -+ if (opt_genconf_section) { -+ /* --genconf-section implies genconf, just restricted to a single -+ * section -+ */ -+ opt_genconf = 1; -+ } -+ - /* If the level or timestamps was passed at the command-line, we want - * to save it and pass it to the children later. - */ -@@ -2529,7 +2542,7 @@ int main(int argc, const char *argv[]) - - /* Parse config file, fail if cannot be done */ - ret = load_configuration(tmp_ctx, config_file, CONFDB_DEFAULT_CONFIG_DIR, -- &monitor); -+ opt_genconf_section, &monitor); - if (ret != EOK) { - switch (ret) { - case EPERM: -diff --git a/src/tools/common/sss_tools.c b/src/tools/common/sss_tools.c -index 701db2d93..0d918f164 100644 ---- a/src/tools/common/sss_tools.c -+++ b/src/tools/common/sss_tools.c -@@ -98,6 +98,7 @@ static errno_t sss_tool_confdb_init(TALLOC_CTX *mem_ctx, - - ret = confdb_setup(mem_ctx, path, - SSSD_CONFIG_FILE, CONFDB_DEFAULT_CONFIG_DIR, -+ NULL, - &confdb); - talloc_zfree(path); - if (ret != EOK) { -diff --git a/src/util/sss_ini.c b/src/util/sss_ini.c -index 9a059fc00..3c15b2809 100644 ---- a/src/util/sss_ini.c -+++ b/src/util/sss_ini.c -@@ -414,6 +414,7 @@ void sss_ini_config_destroy(struct sss_ini_initdata *init_data) - - int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx, - struct sss_ini_initdata *init_data, -+ const char *only_section, - const char **config_ldif) - { - int ret, i, j; -@@ -436,6 +437,14 @@ int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx, - #else - struct collection_item *obj = NULL; - #endif -+ bool section_handled = true; -+ -+ if (only_section != NULL) { -+ /* If the section is specified, we must handle it, either by adding -+ * its contents or by deleting the section if it doesn't exist -+ */ -+ section_handled = false; -+ } - - ldif_len = strlen(CONFDB_INTERNAL_LDIF); - ldif = talloc_array(mem_ctx, char, ldif_len+1); -@@ -466,6 +475,18 @@ int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx, - goto error; - } - -+ if (only_section != NULL) { -+ if (strcasecmp(only_section, sections[i])) { -+ DEBUG(SSSDBG_TRACE_FUNC, "Skipping section %s\n", sections[i]); -+ continue; -+ } else { -+ /* Mark the requested section as handled so that we don't -+ * try to re-add it later -+ */ -+ section_handled = true; -+ } -+ } -+ - dn = talloc_asprintf(tmp_ctx, - "dn: %s,cn=config\n" - "cn: %s\n", -@@ -552,6 +573,39 @@ int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx, - talloc_free(dn); - } - -+ -+ if (only_section != NULL && section_handled == false) { -+ /* If only a single section was supposed to be -+ * handled, but it wasn't found in the INI file, -+ * create an LDIF that would remove the section -+ */ -+ ret = parse_section(tmp_ctx, only_section, &sec_dn, NULL); -+ if (ret != EOK) { -+ goto error; -+ } -+ -+ dn = talloc_asprintf(tmp_ctx, -+ "dn: %s,cn=config\n" -+ "changetype: delete\n\n", -+ sec_dn); -+ if (dn == NULL) { -+ ret = ENOMEM; -+ goto error; -+ } -+ dn_size = strlen(dn); -+ -+ tmp_ldif = talloc_realloc(mem_ctx, ldif, char, -+ ldif_len+dn_size+1); -+ if (!tmp_ldif) { -+ ret = ENOMEM; -+ goto error; -+ } -+ -+ ldif = tmp_ldif; -+ memcpy(ldif+ldif_len, dn, dn_size); -+ ldif_len += dn_size; -+ } -+ - ldif[ldif_len] = '\0'; - - free_section_list(sections); -diff --git a/src/util/sss_ini.h b/src/util/sss_ini.h -index 0b173831d..470b88f99 100644 ---- a/src/util/sss_ini.h -+++ b/src/util/sss_ini.h -@@ -77,6 +77,7 @@ void sss_ini_config_destroy(struct sss_ini_initdata *init_data); - /* Create LDIF */ - int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx, - struct sss_ini_initdata *init_data, -+ const char *only_section, - const char **config_ldif); - - /* Validate sssd.conf if libini_config support it */ --- -2.19.1 - diff --git a/SOURCES/0064-SYSTEMD-Re-read-KCM-configuration-on-systemctl-resta.patch b/SOURCES/0064-SYSTEMD-Re-read-KCM-configuration-on-systemctl-resta.patch deleted file mode 100644 index e5f66ba..0000000 --- a/SOURCES/0064-SYSTEMD-Re-read-KCM-configuration-on-systemctl-resta.patch +++ /dev/null @@ -1,84 +0,0 @@ -From c53fc08a70679b181b0eff6422f199a51d527e67 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 9 Oct 2018 15:41:44 +0200 -Subject: [PATCH 64/66] SYSTEMD: Re-read KCM configuration on systemctl restart - kcm -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related: -https://pagure.io/SSSD/sssd/issue/3862 - -Uses the sssd command together with the --genconf-section=kcm option to -refresh the kcm configuration when the sssd-kcm systemd service is -restarted. - -This allows the administrator to e.g. just drop a snippet to -/etc/sssd.conf.d/ or create the [kcm] section directly in the main sssd -config file, then just restart the sssd-kcm service for the changes to -apply. - -Reviewed-by: Michal Židek ---- - src/man/sssd-kcm.8.xml | 33 ++++++++++++++++++++++++++++ - src/sysv/systemd/sssd-kcm.service.in | 1 + - 2 files changed, 34 insertions(+) - -diff --git a/src/man/sssd-kcm.8.xml b/src/man/sssd-kcm.8.xml -index ec27aa57b..fff8b0a16 100644 ---- a/src/man/sssd-kcm.8.xml -+++ b/src/man/sssd-kcm.8.xml -@@ -127,6 +127,39 @@ systemctl enable sssd-kcm.socket - - - -+ -+ OBTAINING DEBUG LOGS -+ -+ The sssd-kcm service is typically socket-activated -+ -+ systemd -+ 1 -+ . To generate debug logs, add the following -+ either to the /etc/sssd/sssd.conf -+ file directly or as a configuration snippet to -+ /etc/sssd/conf.d/ directory: -+ -+[kcm] -+debug_level = 10 -+ -+ Then, restart the sssd-kcm service: -+ -+systemctl restart sssd-kcm.service -+ -+ Finally, run whatever use-case doesn't work for you. The KCM -+ logs will be generated at -+ /var/log/sssd/sssd_kcm.log. It is -+ recommended to disable the debug logs when you no longer need -+ the debugging to be enabled as the sssd-kcm service can generate -+ quite a large amount of debugging information. -+ -+ -+ Please note that configuration snippets are, at the moment, -+ only processed if the main configuration file at -+ /etc/sssd/sssd.conf exists at all. -+ -+ -+ - - CONFIGURATION OPTIONS - -diff --git a/src/sysv/systemd/sssd-kcm.service.in b/src/sysv/systemd/sssd-kcm.service.in -index 8d689bfd7..5c82bee7d 100644 ---- a/src/sysv/systemd/sssd-kcm.service.in -+++ b/src/sysv/systemd/sssd-kcm.service.in -@@ -9,4 +9,5 @@ Also=sssd-kcm.socket - - [Service] - Environment=DEBUG_LOGGER=--logger=files -+ExecStartPre=-@sbindir@/sssd --genconf-section=kcm - ExecStart=@libexecdir@/sssd/sssd_kcm --uid 0 --gid 0 ${DEBUG_LOGGER} --- -2.19.1 - diff --git a/SOURCES/0065-pam_sss-return-PAM_AUTHINFO_UNAVAIL-if-sc-options-ar.patch b/SOURCES/0065-pam_sss-return-PAM_AUTHINFO_UNAVAIL-if-sc-options-ar.patch deleted file mode 100644 index 700b249..0000000 --- a/SOURCES/0065-pam_sss-return-PAM_AUTHINFO_UNAVAIL-if-sc-options-ar.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 55470b17eacdf97696b4736e9eb8bd2618601475 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 7 Nov 2018 11:49:11 +0100 -Subject: [PATCH] pam_sss: return PAM_AUTHINFO_UNAVAIL if sc options are set - -If pam_sss is called for PAM_USER root it currently returns -PAM_USER_UNKNOWN since SSSD does not handle root. To meet the documented -behavior if one to the sc options is used pam_sss should return -PAM_AUTHINFO_UNAVAIL in this case as well. - -Related to https://pagure.io/SSSD/sssd/issue/3876 - -Reviewed-by: Jakub Hrozek ---- - src/sss_client/pam_sss.c | 4 ++++ - src/tests/intg/test_pam_responder.py | 28 ++++++++++++++++++++++++++++ - 2 files changed, 32 insertions(+) - -diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c -index b4c1036ad..69dc50dfd 100644 ---- a/src/sss_client/pam_sss.c -+++ b/src/sss_client/pam_sss.c -@@ -2378,6 +2378,10 @@ static int pam_sss(enum sss_cli_command task, pam_handle_t *pamh, - ret = get_pam_items(pamh, flags, &pi); - if (ret != PAM_SUCCESS) { - D(("get items returned error: %s", pam_strerror(pamh,ret))); -+ if ((flags & PAM_CLI_FLAGS_TRY_CERT_AUTH) -+ || (flags & PAM_CLI_FLAGS_REQUIRE_CERT_AUTH) ) { -+ return PAM_AUTHINFO_UNAVAIL; -+ } - if (flags & PAM_CLI_FLAGS_IGNORE_UNKNOWN_USER && ret == PAM_USER_UNKNOWN) { - ret = PAM_IGNORE; - } -diff --git a/src/tests/intg/test_pam_responder.py b/src/tests/intg/test_pam_responder.py -index 06f69a3d8..d1ad9affd 100644 ---- a/src/tests/intg/test_pam_responder.py -+++ b/src/tests/intg/test_pam_responder.py -@@ -388,3 +388,31 @@ def test_try_sc_auth(simple_pam_cert_auth, env_for_sssctl): - raise Exception("sssctl failed") - - assert err.find("pam_authenticate for user [user1]: Success") != -1 -+ -+ -+def test_try_sc_auth_root(simple_pam_cert_auth, env_for_sssctl): -+ """ -+ Make sure pam_sss returns PAM_AUTHINFO_UNAVAIL even for root if -+ try_cert_auth is set. -+ """ -+ sssctl = subprocess.Popen(["sssctl", "user-checks", "root", -+ "--action=auth", -+ "--service=pam_sss_try_sc"], -+ universal_newlines=True, -+ env=env_for_sssctl, stdin=subprocess.PIPE, -+ stdout=subprocess.PIPE, stderr=subprocess.PIPE) -+ -+ try: -+ out, err = sssctl.communicate(input="123456") -+ except: -+ sssctl.kill() -+ out, err = sssctl.communicate() -+ -+ sssctl.stdin.close() -+ sssctl.stdout.close() -+ -+ if sssctl.wait() != 0: -+ raise Exception("sssctl failed") -+ -+ assert err.find("pam_authenticate for user [root]: Authentication " + -+ "service cannot retrieve authentication info") != -1 --- -2.19.1 - diff --git a/SOURCES/0066-p11_child-NSS-print-key-type-in-a-debug-message.patch b/SOURCES/0066-p11_child-NSS-print-key-type-in-a-debug-message.patch deleted file mode 100644 index e9e73dd..0000000 --- a/SOURCES/0066-p11_child-NSS-print-key-type-in-a-debug-message.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 6286f8120ac9986b418f4f08f26d6808cf028a9b Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 9 Nov 2018 13:34:33 +0100 -Subject: [PATCH 66/74] p11_child(NSS): print key type in a debug message - -NSS can handle EC keys automatically but a debug message indicating -which key type is used might be useful. - -Related to https://pagure.io/SSSD/sssd/issue/3887 - -Reviewed-by: Jakub Hrozek ---- - src/p11_child/p11_child_nss.c | 36 +++++++++++++++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index f9cbf3f37..d3064ff98 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -477,6 +477,40 @@ bool do_verification_b64(struct p11_ctx *p11_ctx, const char *cert_b64) - return res; - } - -+static const char *keytype2str(KeyType keyType) { -+ switch (keyType) { -+ case nullKey: -+ return "nullKey"; -+ break; -+ case rsaKey: -+ return "rsaKey"; -+ break; -+ case dsaKey: -+ return "dsaKey"; -+ break; -+ case fortezzaKey: -+ return "fortezzaKey"; -+ break; -+ case dhKey: -+ return "dhKey"; -+ break; -+ case keaKey: -+ return "keaKey"; -+ break; -+ case ecKey: -+ return "ecKey"; -+ break; -+ case rsaPssKey: -+ return "rsaPssKey"; -+ break; -+ case rsaOaepKey: -+ return "rsaOaepKey"; -+ break; -+ default: -+ return "Unknown key type"; -+ } -+} -+ - errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - enum op_mode mode, const char *pin, - const char *module_name_in, const char *token_name_in, -@@ -798,6 +832,8 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, - goto done; - } - -+ DEBUG(SSSDBG_TRACE_ALL, "Private key has type [%s].\n", -+ keytype2str(priv_key->keyType)); - algtag = SEC_GetSignatureAlgorithmOidTag(priv_key->keyType, - SEC_OID_SHA1); - if (algtag == SEC_OID_UNKNOWN) { --- -2.19.1 - diff --git a/SOURCES/0067-pam_test_srv-set-default-value-for-SOFTHSM2_CONF.patch b/SOURCES/0067-pam_test_srv-set-default-value-for-SOFTHSM2_CONF.patch deleted file mode 100644 index 6662610..0000000 --- a/SOURCES/0067-pam_test_srv-set-default-value-for-SOFTHSM2_CONF.patch +++ /dev/null @@ -1,47 +0,0 @@ -From ef631f9e61e7a0e168cce9071470839a4c04114c Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 9 Nov 2018 14:04:38 +0100 -Subject: [PATCH 67/74] pam_test_srv: set default value for SOFTHSM2_CONF - -Currently the SOFTHSM2_CONF is not set by any fixture but some tests -sets them and other might rely on the setting done by a previous test. -This means that the tests have to run in a given order and depend on -each other. - -To remove this dependency SOFTHSM2_CONF is set in the fixture to the -"default" SoftHSM2 configuration with one valid certificate. Any test -which needs a different setup must now set SOFTHSM2_CONF explicitly. - -Related to https://pagure.io/SSSD/sssd/issue/3887 - -Reviewed-by: Jakub Hrozek ---- - src/tests/cmocka/test_pam_srv.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c -index 7fc9224e1..b29961255 100644 ---- a/src/tests/cmocka/test_pam_srv.c -+++ b/src/tests/cmocka/test_pam_srv.c -@@ -356,6 +356,10 @@ static void pam_test_setup_common(void) - { - errno_t ret; - -+#ifndef HAVE_NSS -+ putenv(discard_const("SOFTHSM2_CONF=" ABS_BUILD_DIR "/src/tests/test_CA/softhsm2_one.conf")); -+#endif -+ - pam_test_ctx->pam_user_fqdn = \ - sss_create_internal_fqname(pam_test_ctx, - "pamuser", -@@ -1926,6 +1930,7 @@ void test_pam_preauth_cert_nocert(void **state) - set_cert_auth_param(pam_test_ctx->pctx, "/no/path"); - #else - set_cert_auth_param(pam_test_ctx->pctx, CA_DB); -+ unsetenv("SOFTHSM2_CONF"); - #endif - - --- -2.19.1 - diff --git a/SOURCES/0068-tests-add-ECC-CA.patch b/SOURCES/0068-tests-add-ECC-CA.patch deleted file mode 100644 index a8f0717..0000000 --- a/SOURCES/0068-tests-add-ECC-CA.patch +++ /dev/null @@ -1,276 +0,0 @@ -From a0cdc3bdf0e7f8ef15997f269b6f1ca5cab85825 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 9 Nov 2018 14:06:03 +0100 -Subject: [PATCH 68/74] tests: add ECC CA - -To be able to test certificates with elliptic curve (EC) keys a new test -CA with this kind of keys is added. - -Related to https://pagure.io/SSSD/sssd/issue/3887 - -Reviewed-by: Jakub Hrozek ---- - Makefile.am | 6 +- - configure.ac | 1 + - src/tests/test_ECC_CA/Makefile.am | 95 +++++++++++++++++++ - src/tests/test_ECC_CA/SSSD_test_ECC_CA.config | 47 +++++++++ - .../test_ECC_CA/SSSD_test_ECC_CA_key.pem | 9 ++ - .../SSSD_test_ECC_cert_0001.config | 20 ++++ - .../SSSD_test_ECC_cert_key_0001.pem | 9 ++ - 7 files changed, 185 insertions(+), 2 deletions(-) - create mode 100644 src/tests/test_ECC_CA/Makefile.am - create mode 100644 src/tests/test_ECC_CA/SSSD_test_ECC_CA.config - create mode 100644 src/tests/test_ECC_CA/SSSD_test_ECC_CA_key.pem - create mode 100644 src/tests/test_ECC_CA/SSSD_test_ECC_cert_0001.config - create mode 100644 src/tests/test_ECC_CA/SSSD_test_ECC_cert_key_0001.pem - -diff --git a/Makefile.am b/Makefile.am -index 3667856c6..430506028 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -21,7 +21,8 @@ if HAVE_MANPAGES - SUBDIRS += src/man - endif - --SUBDIRS += . src/tests/cwrap src/tests/intg src/tests/test_CA -+SUBDIRS += . src/tests/cwrap src/tests/intg src/tests/test_CA \ -+ src/tests/test_ECC_CA - - # Some old versions of automake don't define builddir - builddir ?= . -@@ -5394,8 +5395,9 @@ CLEANFILES += *.X */*.X */*/*.X - - test_CA: test_CA.stamp - --test_CA.stamp: $(srcdir)/src/tests/test_CA/* -+test_CA.stamp: $(srcdir)/src/tests/test_CA/* $(srcdir)/src/tests/test_ECC_CA/* - $(MAKE) -C src/tests/test_CA ca_all -+ $(MAKE) -C src/tests/test_ECC_CA ca_all - touch $@ - - if BUILD_TEST_CA -diff --git a/configure.ac b/configure.ac -index 5816b04c6..fb01a7c3b 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -521,6 +521,7 @@ AC_CONFIG_FILES([Makefile contrib/sssd.spec src/examples/rwtab src/doxy.config - src/sysv/sssd src/sysv/gentoo/sssd src/sysv/SUSE/sssd - po/Makefile.in src/man/Makefile src/tests/cwrap/Makefile - src/tests/intg/Makefile src/tests/test_CA/Makefile -+ src/tests/test_ECC_CA/Makefile - src/lib/ipa_hbac/ipa_hbac.pc src/lib/ipa_hbac/ipa_hbac.doxy - src/lib/idmap/sss_idmap.pc src/lib/idmap/sss_idmap.doxy - src/lib/certmap/sss_certmap.pc src/lib/certmap/sss_certmap.doxy -diff --git a/src/tests/test_ECC_CA/Makefile.am b/src/tests/test_ECC_CA/Makefile.am -new file mode 100644 -index 000000000..47af991c3 ---- /dev/null -+++ b/src/tests/test_ECC_CA/Makefile.am -@@ -0,0 +1,95 @@ -+dist_noinst_DATA = \ -+ SSSD_test_ECC_CA.config \ -+ SSSD_test_ECC_CA_key.pem \ -+ SSSD_test_ECC_cert_0001.config \ -+ SSSD_test_ECC_cert_key_0001.pem -+ -+openssl_ecc_ca_config = $(srcdir)/SSSD_test_ECC_CA.config -+openssl_ecc_ca_key = $(srcdir)/SSSD_test_ECC_CA_key.pem -+pwdfile = pwdfile -+ -+configs := $(notdir $(wildcard $(srcdir)/SSSD_test_ECC_cert_*.config)) -+ids := $(subst SSSD_test_ECC_cert_,,$(basename $(configs))) -+certs = $(addprefix SSSD_test_ECC_cert_x509_,$(addsuffix .pem,$(ids))) -+certs_h = $(addprefix SSSD_test_ECC_cert_x509_,$(addsuffix .h,$(ids))) -+pubkeys = $(addprefix SSSD_test_ECC_cert_pubsshkey_,$(addsuffix .pub,$(ids))) -+pubkeys_h = $(addprefix SSSD_test_ECC_cert_pubsshkey_,$(addsuffix .h,$(ids))) -+pkcs12 = $(addprefix SSSD_test_ECC_cert_pkcs12_,$(addsuffix .pem,$(ids))) -+ -+if HAVE_NSS -+extra = p11_ecc_nssdb -+else -+extra = softhsm2_ecc_one p11_ecc_nssdb -+endif -+ -+# If openssl is run in parallel there might be conflicts with the serial -+.NOTPARALLEL: -+ -+ca_all: clean serial SSSD_test_ECC_CA.pem $(certs) $(certs_h) $(pubkeys) $(pubkeys_h) $(pkcs12) $(extra) -+ -+$(pwdfile): -+ @echo "123456" > $@ -+ -+SSSD_test_ECC_CA.pem: $(openssl_ecc_ca_key) $(openssl_ecc_ca_config) serial -+ $(OPENSSL) req -batch -config ${openssl_ecc_ca_config} -x509 -new -nodes -key $< -sha384 -days 1024 -set_serial 0 -extensions v3_ca -out $@ -+ -+ -+SSSD_test_ECC_cert_req_%.pem: $(srcdir)/SSSD_test_ECC_cert_key_%.pem $(srcdir)/SSSD_test_ECC_cert_%.config -+ $(OPENSSL) req -new -nodes -key $< -reqexts req_exts -config $(srcdir)/SSSD_test_ECC_cert_$*.config -out $@ -+ -+SSSD_test_ECC_cert_x509_%.pem: SSSD_test_ECC_cert_req_%.pem $(openssl_ecc_ca_config) SSSD_test_ECC_CA.pem -+ $(OPENSSL) ca -config ${openssl_ecc_ca_config} -batch -notext -keyfile $(openssl_ecc_ca_key) -in $< -days 200 -extensions usr_cert -out $@ -+ -+SSSD_test_ECC_cert_pkcs12_%.pem: SSSD_test_ECC_cert_x509_%.pem $(srcdir)/SSSD_test_ECC_cert_key_%.pem $(pwdfile) -+ $(OPENSSL) pkcs12 -export -in SSSD_test_ECC_cert_x509_$*.pem -inkey $(srcdir)/SSSD_test_ECC_cert_key_$*.pem -nodes -passout file:$(pwdfile) -out $@ -+ -+SSSD_test_ECC_cert_pubkey_%.pem: SSSD_test_ECC_cert_x509_%.pem -+ $(OPENSSL) x509 -in $< -pubkey -noout > $@ -+ -+SSSD_test_ECC_cert_pubsshkey_%.pub: SSSD_test_ECC_cert_pubkey_%.pem -+ $(SSH_KEYGEN) -i -m PKCS8 -f $< > $@ -+ -+SSSD_test_ECC_cert_x509_%.h: SSSD_test_ECC_cert_x509_%.pem -+ @echo "#define SSSD_TEST_ECC_CERT_$* \""$(shell cat $< |openssl x509 -outform der | base64 -w 0)"\"" > $@ -+ -+SSSD_test_ECC_cert_pubsshkey_%.h: SSSD_test_ECC_cert_pubsshkey_%.pub -+ @echo "#define SSSD_TEST_ECC_CERT_SSH_KEY_$* \""$(shell cut -d' ' -f2 $<)"\"" > $@ -+ -+ -+p11_ecc_nssdb: SSSD_test_ECC_cert_pkcs12_0001.pem SSSD_test_ECC_CA.pem $(pwdfile) -+ mkdir $@ -+ $(CERTUTIL) -d sql:./$@ -N -f $(pwdfile) -+ $(CERTUTIL) -d sql:./$@ -A -n 'SSSD test ECC CA' -t CT,CT,CT -a -i SSSD_test_ECC_CA.pem -f $(pwdfile) -+ $(PK12UTIL) -d sql:./$@ -i SSSD_test_ECC_cert_pkcs12_0001.pem -w $(pwdfile) -k $(pwdfile) -+ -+ -+softhsm2_ecc_one: softhsm2_ecc_one.conf -+ mkdir $@ -+ SOFTHSM2_CONF=./$< $(SOFTHSM2_UTIL) --init-token --label "SSSD Test ECC Token" --pin 123456 --so-pin 123456 --free -+ GNUTLS_PIN=123456 SOFTHSM2_CONF=./$< $(P11TOOL) --provider=$(SOFTHSM2_PATH) --write --no-mark-private --load-certificate=SSSD_test_ECC_cert_x509_0001.pem --login --label 'SSSD test ECC cert 0001' --id '190E513C9A3DFAACDE5D2D0592F0FDFF559C10CB' -+ GNUTLS_PIN=123456 SOFTHSM2_CONF=./$< $(P11TOOL) --provider=$(SOFTHSM2_PATH) --write --load-privkey=$(srcdir)/SSSD_test_ECC_cert_key_0001.pem --login --label 'SSSD test ECC cert 0001' --id '190E513C9A3DFAACDE5D2D0592F0FDFF559C10CB' -+ -+softhsm2_ecc_one.conf: -+ @echo "directories.tokendir = "$(abs_top_builddir)"/src/tests/test_ECC_CA/softhsm2_ecc_one" > $@ -+ @echo "objectstore.backend = file" >> $@ -+ @echo "slots.removable = true" >> $@ -+ -+CLEANFILES = \ -+ index.txt index.txt.attr \ -+ index.txt.attr.old index.txt.old \ -+ serial serial.old \ -+ SSSD_test_ECC_CA.pem $(pwdfile) \ -+ $(certs) $(certs_h) $(pubkeys) $(pubkeys_h) $(pkcs12) \ -+ softhsm2_*.conf \ -+ $(NULL) -+ -+clean-local: -+ rm -rf newcerts -+ rm -rf p11_ecc_nssdb -+ rm -rf softhsm* -+ -+serial: clean -+ touch index.txt -+ touch index.txt.attr -+ mkdir newcerts -+ echo -n 01 > serial -diff --git a/src/tests/test_ECC_CA/SSSD_test_ECC_CA.config b/src/tests/test_ECC_CA/SSSD_test_ECC_CA.config -new file mode 100644 -index 000000000..c1e4e22a6 ---- /dev/null -+++ b/src/tests/test_ECC_CA/SSSD_test_ECC_CA.config -@@ -0,0 +1,47 @@ -+[ ca ] -+default_ca = ECC_CA_default -+ -+[ ECC_CA_default ] -+dir = . -+database = $dir/index.txt -+new_certs_dir = $dir/newcerts -+ -+certificate = $dir/SSSD_test_ECC_CA.pem -+serial = $dir/serial -+private_key = $dir/SSSD_test_ECC_CA_key.pem -+RANDFILE = $dir/rand -+ -+default_days = 365 -+default_crl_days = 30 -+default_md = sha256 -+ -+policy = policy_any -+email_in_dn = no -+ -+name_opt = ca_default -+cert_opt = ca_default -+copy_extensions = copy -+ -+[ usr_cert ] -+authorityKeyIdentifier = keyid, issuer -+ -+[ v3_ca ] -+subjectKeyIdentifier = hash -+authorityKeyIdentifier = keyid:always,issuer:always -+basicConstraints = CA:true -+keyUsage = critical, digitalSignature, cRLSign, keyCertSign -+ -+[ policy_any ] -+organizationName = supplied -+organizationalUnitName = supplied -+commonName = supplied -+emailAddress = optional -+ -+[ req ] -+distinguished_name = req_distinguished_name -+prompt = no -+ -+[ req_distinguished_name ] -+O = SSSD -+OU = SSSD test -+CN = SSSD test ECC CA -diff --git a/src/tests/test_ECC_CA/SSSD_test_ECC_CA_key.pem b/src/tests/test_ECC_CA/SSSD_test_ECC_CA_key.pem -new file mode 100644 -index 000000000..c5cb3ef42 ---- /dev/null -+++ b/src/tests/test_ECC_CA/SSSD_test_ECC_CA_key.pem -@@ -0,0 +1,9 @@ -+-----BEGIN EC PARAMETERS----- -+BgUrgQQAIg== -+-----END EC PARAMETERS----- -+-----BEGIN EC PRIVATE KEY----- -+MIGkAgEBBDBKk+ue3IyidXo3+befiqrcKrpVpy/pWz9CMTIALHMBc/a83Q3h9yEB -+CNpdsF8B2zegBwYFK4EEACKhZANiAAR/mCPIYxyT4tbjgpJT+oKCGfGjfs3FVnRr -+GLnNnT/L2b9PACMjjugM/1RNOuLdzRFBVWlQ80ISH5w17R2uhbiDJ/Q254Ele4Ak -+5e2nR/9x0ZIAqc05tkBDhsXfJ3id3/0= -+-----END EC PRIVATE KEY----- -diff --git a/src/tests/test_ECC_CA/SSSD_test_ECC_cert_0001.config b/src/tests/test_ECC_CA/SSSD_test_ECC_cert_0001.config -new file mode 100644 -index 000000000..17c9192d4 ---- /dev/null -+++ b/src/tests/test_ECC_CA/SSSD_test_ECC_cert_0001.config -@@ -0,0 +1,20 @@ -+# This certificate is used in -+# - src/tests/cmocka/test_cert_utils.c -+# - src/tests/cmocka/test_pam_srv.c -+[ req ] -+distinguished_name = req_distinguished_name -+prompt = no -+ -+[ req_distinguished_name ] -+O = SSSD -+OU = SSSD test ECC -+CN = SSSD test ECC cert 0001 -+ -+[ req_exts ] -+basicConstraints = CA:FALSE -+nsCertType = client, email -+nsComment = "SSSD test Certificate" -+subjectKeyIdentifier = hash -+keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment -+extendedKeyUsage = clientAuth, emailProtection -+subjectAltName = email:sssd-devel@lists.fedorahosted.org,URI:https://pagure.io/SSSD/sssd// -diff --git a/src/tests/test_ECC_CA/SSSD_test_ECC_cert_key_0001.pem b/src/tests/test_ECC_CA/SSSD_test_ECC_cert_key_0001.pem -new file mode 100644 -index 000000000..8c9321048 ---- /dev/null -+++ b/src/tests/test_ECC_CA/SSSD_test_ECC_cert_key_0001.pem -@@ -0,0 +1,9 @@ -+-----BEGIN EC PARAMETERS----- -+BgUrgQQAIg== -+-----END EC PARAMETERS----- -+-----BEGIN EC PRIVATE KEY----- -+MIGkAgEBBDDVZu1S6+U+1Fs1eAn/6O1iX7LH2w4AaToxqutXtkrdEpuTX7SZskTQ -+UCL0Lf5oQjigBwYFK4EEACKhZANiAAQheZFBntzcARA52Gba7c01BElFRds1F439 -+KotFOoDx4fJf67hmD69bKuTbWLvc7l3Lf2TKdI5GCp/u9SPhGtve0CaYm9Hcoxwp -+2yYnhq3stoW+far//4h3mQxU/hG9pj0= -+-----END EC PRIVATE KEY----- --- -2.19.1 - diff --git a/SOURCES/0069-test_pam_srv-add-test-for-certificate-with-EC-keys.patch b/SOURCES/0069-test_pam_srv-add-test-for-certificate-with-EC-keys.patch deleted file mode 100644 index f9e9d92..0000000 --- a/SOURCES/0069-test_pam_srv-add-test-for-certificate-with-EC-keys.patch +++ /dev/null @@ -1,198 +0,0 @@ -From a7421b5260cd2edd07ec5c0fefd240e76c5a0f03 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 9 Nov 2018 14:01:20 +0100 -Subject: [PATCH 69/74] test_pam_srv: add test for certificate with EC keys - -Add an authentication test with a certificate with EC keys. - -Related to https://pagure.io/SSSD/sssd/issue/3887 - -Reviewed-by: Jakub Hrozek ---- - src/tests/cmocka/test_pam_srv.c | 114 ++++++++++++++++++++++++++++++++ - 1 file changed, 114 insertions(+) - -diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c -index b29961255..f55e6222e 100644 ---- a/src/tests/cmocka/test_pam_srv.c -+++ b/src/tests/cmocka/test_pam_srv.c -@@ -42,9 +42,13 @@ - #ifdef HAVE_TEST_CA - #include "tests/test_CA/SSSD_test_cert_x509_0001.h" - #include "tests/test_CA/SSSD_test_cert_x509_0002.h" -+ -+#include "tests/test_ECC_CA/SSSD_test_ECC_cert_x509_0001.h" - #else - #define SSSD_TEST_CERT_0001 "" - #define SSSD_TEST_CERT_0002 "" -+ -+#define SSSD_TEST_ECC_CERT_0001 "" - #endif - - #define TESTS_PATH "tp_" BASE_FILE_STEM -@@ -58,10 +62,16 @@ - - #define NSS_DB_PATH_2CERTS TESTS_PATH "_2certs" - #define NSS_DB_2CERTS "sql:"NSS_DB_PATH_2CERTS -+ -+#define NSS_DB_PATH_ECC TESTS_PATH "_ecc" -+#define NSS_DB_ECC "sql:"NSS_DB_PATH_ECC -+ - #ifdef HAVE_NSS - #define CA_DB NSS_DB -+#define ECC_CA_DB NSS_DB_ECC - #else - #define CA_DB ABS_BUILD_DIR"/src/tests/test_CA/SSSD_test_CA.pem" -+#define ECC_CA_DB ABS_BUILD_DIR"/src/tests/test_ECC_CA/SSSD_test_ECC_CA.pem" - #endif - - #define TEST_TOKEN_NAME "SSSD Test Token" -@@ -122,6 +132,13 @@ static errno_t setup_nss_db(void) - return ret; - } - -+ ret = mkdir(NSS_DB_PATH_ECC, 0775); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "Failed to create " NSS_DB_PATH_ECC ".\n"); -+ return ret; -+ } -+ - child_pid = fork(); - if (child_pid == 0) { /* child */ - ret = execlp("certutil", "certutil", "-N", "--empty-password", "-d", -@@ -154,6 +171,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_ECC, 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"); -@@ -196,6 +229,27 @@ static errno_t setup_nss_db(void) - return ret; - } - -+ fp = fopen(NSS_DB_PATH_ECC"/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/test_ECC_CA/p11_ecc_nssdb' dbSlotDescription='SSSD Test ECC Slot' dbTokenDescription='SSSD Test ECC Token' secmod='secmod.db' flags=readOnly \n\n", ABS_BUILD_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; - } - -@@ -242,6 +296,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_ECC"/cert9.db"); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove cert9.db.\n"); -+ } -+ -+ ret = unlink(NSS_DB_PATH_ECC"/key4.db"); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove key4.db.\n"); -+ } -+ -+ ret = unlink(NSS_DB_PATH_ECC"/pkcs11.txt"); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove pkcs11.db.\n"); -+ } -+ -+ ret = rmdir(NSS_DB_PATH_ECC); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove " NSS_DB_PATH "\n"); -+ } - } - - struct pam_ctx *mock_pctx(TALLOC_CTX *mem_ctx) -@@ -2347,6 +2421,44 @@ void test_pam_cert_auth(void **state) - assert_int_equal(ret, EOK); - } - -+void test_pam_ecc_cert_auth(void **state) -+{ -+ int ret; -+ -+#ifndef HAVE_NSS -+ putenv(discard_const("SOFTHSM2_CONF=" ABS_BUILD_DIR "/src/tests/test_ECC_CA/softhsm2_ecc_one.conf")); -+#endif -+ set_cert_auth_param(pam_test_ctx->pctx, ECC_CA_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, "pamuser", "123456", -+ "SSSD Test ECC Token", -+ TEST_MODULE_NAME, -+ "190E513C9A3DFAACDE5D2D0592F0FDFF559C10CB", NULL, -+ test_lookup_by_cert_cb, SSSD_TEST_ECC_CERT_0001, true); -+ -+ 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_simple_check_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(void **state) - { - int ret; -@@ -3022,6 +3134,8 @@ int main(int argc, const char *argv[]) - cmocka_unit_test_setup_teardown(test_pam_cert_auth, - pam_test_setup_no_verification, - pam_test_teardown), -+ cmocka_unit_test_setup_teardown(test_pam_ecc_cert_auth, -+ pam_test_setup, 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_preauth_2certs_one_mapping, --- -2.19.1 - diff --git a/SOURCES/0070-p11_child-openssl-add-support-for-EC-keys.patch b/SOURCES/0070-p11_child-openssl-add-support-for-EC-keys.patch deleted file mode 100644 index 3b3f29e..0000000 --- a/SOURCES/0070-p11_child-openssl-add-support-for-EC-keys.patch +++ /dev/null @@ -1,409 +0,0 @@ -From d64d9cfbe9dc44db04b253aa08c05e645e10708a Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 9 Nov 2018 14:01:46 +0100 -Subject: [PATCH 70/74] p11_child(openssl): add support for EC keys - -Add support for EC keys to the OpenSSL version of p11_child. Please see -comments in the code for some technical details. - -Related to https://pagure.io/SSSD/sssd/issue/3887 - -Reviewed-by: Jakub Hrozek ---- - src/p11_child/p11_child_openssl.c | 319 +++++++++++++++++++++++++++++- - 1 file changed, 309 insertions(+), 10 deletions(-) - -diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c -index af55523a7..0f8ba3d3c 100644 ---- a/src/p11_child/p11_child_openssl.c -+++ b/src/p11_child/p11_child_openssl.c -@@ -137,6 +137,7 @@ static OCSP_RESPONSE *query_responder(BIO *cbio, const char *host, - #define X509_STORE_get0_objects(store) (store->objs) - #define X509_OBJECT_get_type(object) (object->type) - #define X509_OBJECT_get0_X509(object) (object->data.x509) -+#define EVP_MD_CTX_free EVP_MD_CTX_destroy - #endif - - OCSP_RESPONSE *process_responder(OCSP_REQUEST *req, -@@ -860,6 +861,243 @@ done: - return ret; - } - -+/* Currently this funtion is only used the print the curve type in the debug -+ * messages. */ -+static void get_ec_curve_type(CK_FUNCTION_LIST *module, -+ CK_SESSION_HANDLE session, -+ CK_OBJECT_HANDLE key_handle) -+{ -+ CK_ATTRIBUTE attribute; -+ CK_RV rv; -+ EC_GROUP *ec_group; -+ const unsigned char *p; -+ int len; -+ char der_buf[128]; /* FIXME: any other size ?? */ -+ char oid_buf[128]; /* FIXME: any other size ?? */ -+ -+ attribute.type = CKA_ECDSA_PARAMS; -+ attribute.pValue = &der_buf; -+ attribute.ulValueLen = sizeof(der_buf); -+ -+ rv = module->C_GetAttributeValue(session, key_handle, &attribute, 1); -+ if (rv != CKR_OK) { -+ free(attribute.pValue); -+ DEBUG(SSSDBG_OP_FAILURE, -+ "C_GetAttributeValue failed [%lu][%s].\n", -+ rv, p11_kit_strerror(rv)); -+ return; -+ } -+ -+ p = (const unsigned char *) attribute.pValue; -+ ec_group = d2i_ECPKParameters(NULL, &p, attribute.ulValueLen); -+ len = OBJ_obj2txt(oid_buf, sizeof(oid_buf), -+ OBJ_nid2obj(EC_GROUP_get_curve_name(ec_group)), 1); -+ DEBUG(SSSDBG_TRACE_ALL, "Curve name [%s][%s][%.*s].\n", -+ OBJ_nid2sn(EC_GROUP_get_curve_name(ec_group)), -+ OBJ_nid2ln(EC_GROUP_get_curve_name(ec_group)), -+ len, oid_buf); -+ -+ return; -+} -+ -+static CK_KEY_TYPE get_key_type(CK_FUNCTION_LIST *module, -+ CK_SESSION_HANDLE session, -+ CK_OBJECT_HANDLE key_handle) -+{ -+ CK_ATTRIBUTE attribute; -+ CK_RV rv; -+ CK_KEY_TYPE type; -+ -+ attribute.type = CKA_KEY_TYPE; -+ attribute.pValue = &type; -+ attribute.ulValueLen = sizeof(CK_KEY_TYPE); -+ -+ rv = module->C_GetAttributeValue(session, key_handle, &attribute, 1); -+ if (rv != CKR_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "C_GetAttributeValue failed [%lu][%s].\n", -+ rv, p11_kit_strerror(rv)); -+ return CK_UNAVAILABLE_INFORMATION; -+ } -+ -+ if (attribute.ulValueLen == -1) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Key type attribute cannot be read.\n"); -+ return CK_UNAVAILABLE_INFORMATION; -+ } -+ -+ if (type == CKK_EC && DEBUG_IS_SET(SSSDBG_TRACE_ALL)) { -+ get_ec_curve_type(module, session, key_handle); -+ } -+ -+ return type; -+} -+ -+static int do_hash(TALLOC_CTX *mem_ctx, const EVP_MD *evp_md, -+ CK_BYTE *in, size_t in_len, -+ CK_BYTE **hash, size_t *hash_len) -+{ -+ EVP_MD_CTX *md_ctx = NULL; -+ int ret; -+ unsigned char md_value[EVP_MAX_MD_SIZE]; -+ unsigned int md_len; -+ CK_BYTE *out = NULL; -+ -+ md_ctx = EVP_MD_CTX_create(); -+ if (md_ctx == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "EVP_MD_CTX_create failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = EVP_DigestInit(md_ctx, evp_md); -+ if (ret != 1) { -+ DEBUG(SSSDBG_OP_FAILURE, "EVP_DigestInit failed.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ ret = EVP_DigestUpdate(md_ctx, in, in_len); -+ if (ret != 1) { -+ DEBUG(SSSDBG_OP_FAILURE, "EVP_DigestUpdate failed.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ ret = EVP_DigestFinal_ex(md_ctx, md_value, &md_len); -+ if (ret != 1) { -+ DEBUG(SSSDBG_OP_FAILURE, "EVP_DigestFinal failed.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ out = talloc_size(mem_ctx, md_len * sizeof(CK_BYTE)); -+ if (out == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ memcpy(out, md_value, md_len); -+ -+ *hash = out; -+ *hash_len = md_len; -+ -+ ret = EOK; -+ -+done: -+ -+ if (ret != EOK) { -+ free(out); -+ EVP_MD_CTX_free(md_ctx); -+ } -+ -+ return ret; -+} -+ -+/* A ECDSA signature consists of 2 integer values r and s. According to the -+ * "PKCS #11 Cryptographic Token Interface Current Mechanisms Specification": -+ * -+ * """ -+ * For the purposes of these mechanisms, an ECDSA signature is an octet string -+ * of even length which is at most two times nLen octets, where nLen is the -+ * length in octets of the base point order n. The signature octets correspond -+ * to the concatenation of the ECDSA values r and s, both represented as an -+ * octet string of equal length of at most nLen with the most significant byte -+ * first. If r and s have different octet length, the shorter of both must be -+ * padded with leading zero octets such that both have the same octet length. -+ * Loosely spoken, the first half of the signature is r and the second half is -+ * s. For signatures created by a token, the resulting signature is always of -+ * length 2nLen. -+ * """ -+ * -+ * Unfortunately OpenSSL expects the 2 integer values r and s DER encoded as -+ * specified in X9.62 "Public Key Cryptography For The Financial Services -+ * Industry: The Elliptic Curve Digital Signature Algorithm (ECDSA)": -+ * -+ * """ -+ * When a digital signature is identified by the OID ecdsa-with-SHA1 , the -+ * digital signature shall be ASN.1 encoded using the following syntax: -+ * ECDSA-Sig-Value ::= SEQUENCE { -+ * r INTEGER, -+ * s INTEGER -+ * } -+ * """ -+ * -+ * The following function translates from the PKCS#11 to the X9.62 format by -+ * manually creating the DER sequence after splitting the PKCS#11 signature. -+ * Since r and s are positive values we have to make sure that the leading -+ * bit is not set in the DER encoding by prepending a 0-byte if needed. -+ */ -+static int rs_to_seq(TALLOC_CTX *mem_ctx, CK_BYTE *rs_sig, CK_ULONG rs_sig_len, -+ CK_BYTE **seq_sig, CK_ULONG *seq_sig_len) -+{ -+ CK_BYTE *r; -+ size_t r_len; -+ CK_BYTE *s; -+ size_t s_len; -+ size_t r_add = 0; -+ size_t s_add = 0; -+ CK_BYTE *out; -+ size_t out_len; -+ -+ if (rs_sig_len % 2 != 0) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected signature size [%lu].\n", -+ rs_sig_len); -+ return EINVAL; -+ } -+ -+ r_len = s_len = rs_sig_len / 2; -+ r = rs_sig; -+ s = rs_sig + r_len; -+ -+ /* Remove padding */ -+ while(r_len > 1 && *r == 0x00) { -+ r++; -+ r_len--; -+ } -+ while(s_len > 1 && *s == 0x00) { -+ s++; -+ s_len--; -+ } -+ -+ /* r and s are positive, check if the highest bit is set which would -+ * indicate a negative value. In this case a 0x00 must be added. */ -+ if ( *r & 0x80 ) { -+ r_add = 1; -+ } -+ if ( *s & 0x80 ) { -+ s_add = 1; -+ } -+ -+ out_len = r_len + r_add + s_len + s_add + 6; -+ out = talloc_size(mem_ctx, out_len * sizeof(CK_BYTE)); -+ if (out == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); -+ return ENOMEM; -+ } -+ -+ out[0] = 0x30; -+ out[1] = (CK_BYTE) (out_len - 2); -+ out[2] = 0x02; -+ out[3] = (CK_BYTE) (r_len + r_add); -+ if (r_add == 1) { -+ out[4] = 0x00; -+ } -+ memcpy(&out[4 + r_add], r, r_len); -+ out[4 + r_add + r_len] = 0x02; -+ out[5 + r_add + r_len] = (CK_BYTE) (s_len + s_add); -+ if (s_add == 1) { -+ out[6 + r_add + r_len] = 0x00; -+ } -+ memcpy(&out[6 + r_add + r_len + s_add], s, s_len); -+ -+ *seq_sig = out; -+ *seq_sig_len = out_len; -+ -+ return EOK; -+} -+ - static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, - struct cert_list *cert) - { -@@ -870,17 +1108,25 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, - {CKA_SIGN, &key_sign, sizeof(key_sign)}, - {CKA_ID, NULL, 0} - }; -- CK_MECHANISM mechanism = { CKM_SHA1_RSA_PKCS, NULL, 0 }; -+ CK_MECHANISM mechanism = { CK_UNAVAILABLE_INFORMATION, NULL, 0 }; - CK_OBJECT_HANDLE priv_key_object; - CK_ULONG object_count; - CK_BYTE random_value[128]; - CK_BYTE *signature = NULL; - CK_ULONG signature_size = 0; -+ CK_BYTE *seq_sig = NULL; -+ CK_ULONG seq_sig_size = 0; - CK_RV rv; - CK_RV rv_f; - EVP_PKEY *cert_pub_key = NULL; - EVP_MD_CTX *md_ctx; - int ret; -+ const EVP_MD *evp_md = NULL; -+ CK_BYTE *hash_val = NULL; -+ size_t hash_len = 0; -+ CK_BYTE *val_to_sign = NULL; -+ size_t val_to_sign_len = 0; -+ bool card_does_hash = false; - - key_template[2].pValue = cert->attributes[ATTR_ID].pValue; - key_template[2].ulValueLen = cert->attributes[ATTR_ID].ulValueLen; -@@ -910,9 +1156,31 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, - return EINVAL; - } - -+ switch (get_key_type(module, session, priv_key_object)) { -+ case CKK_RSA: -+ DEBUG(SSSDBG_TRACE_ALL, "Found RSA key using CKM_SHA1_RSA_PKCS.\n"); -+ mechanism.mechanism = CKM_SHA1_RSA_PKCS; -+ evp_md = EVP_sha1(); -+ card_does_hash = true; -+ break; -+ case CKK_EC: -+ DEBUG(SSSDBG_TRACE_ALL, "Found ECC key using CKM_ECDSA.\n"); -+ mechanism.mechanism = CKM_ECDSA; -+ evp_md = EVP_sha1(); -+ card_does_hash = false; -+ break; -+ case CK_UNAVAILABLE_INFORMATION: -+ DEBUG(SSSDBG_CRIT_FAILURE, "get_key_type failed.\n"); -+ return EIO; -+ break; -+ default: -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported key type.\n"); -+ return EIO; -+ } -+ - rv = module->C_SignInit(session, &mechanism, priv_key_object); - if (rv != CKR_OK) { -- DEBUG(SSSDBG_OP_FAILURE, "C_SignInit failed [%lu][%s].", -+ DEBUG(SSSDBG_OP_FAILURE, "C_SignInit failed [%lu][%s].\n", - rv, p11_kit_strerror(rv)); - return EIO; - } -@@ -923,7 +1191,22 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, - return EINVAL; - } - -- rv = module->C_Sign(session, random_value, sizeof(random_value), NULL, -+ if (card_does_hash) { -+ val_to_sign = random_value; -+ val_to_sign_len = sizeof(random_value); -+ } else { -+ ret = do_hash(cert, evp_md, random_value, sizeof(random_value), -+ &hash_val, &hash_len); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "do_hash failed.\n"); -+ return ret; -+ } -+ -+ val_to_sign = hash_val; -+ val_to_sign_len = hash_len; -+ } -+ -+ rv = module->C_Sign(session, val_to_sign, val_to_sign_len, NULL, - &signature_size); - if (rv != CKR_OK || signature_size == 0) { - DEBUG(SSSDBG_OP_FAILURE, "C_Sign failed [%lu][%s].\n", -@@ -937,7 +1220,7 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, - return ENOMEM; - } - -- rv = module->C_Sign(session, random_value, sizeof(random_value), signature, -+ rv = module->C_Sign(session, val_to_sign, val_to_sign_len, signature, - &signature_size); - if (rv != CKR_OK) { - DEBUG(SSSDBG_OP_FAILURE, "C_Sign failed [%lu][%s].\n", -@@ -958,7 +1241,7 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, - ret = ENOMEM; - goto done; - } -- ret = EVP_VerifyInit(md_ctx, EVP_sha1()); -+ ret = EVP_VerifyInit(md_ctx, evp_md); - if (ret != 1) { - DEBUG(SSSDBG_OP_FAILURE, "EVP_VerifyInit failed.\n"); - ret = EINVAL; -@@ -972,11 +1255,27 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session, - goto done; - } - -- ret = EVP_VerifyFinal(md_ctx, signature, signature_size, cert_pub_key); -- if (ret != 1) { -- DEBUG(SSSDBG_OP_FAILURE, "EVP_VerifyFinal failed.\n"); -- ret = EINVAL; -- goto done; -+ if (mechanism.mechanism == CKM_ECDSA) { -+ ret = rs_to_seq(signature, signature, signature_size, -+ &seq_sig, &seq_sig_size); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "rs_to_seq failed.\n"); -+ goto done; -+ } -+ -+ ret = EVP_VerifyFinal(md_ctx, seq_sig, seq_sig_size, cert_pub_key); -+ if (ret != 1) { -+ DEBUG(SSSDBG_OP_FAILURE, "EVP_VerifyFinal failed.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ } else { -+ ret = EVP_VerifyFinal(md_ctx, signature, signature_size, cert_pub_key); -+ if (ret != 1) { -+ DEBUG(SSSDBG_OP_FAILURE, "EVP_VerifyFinal failed.\n"); -+ ret = EINVAL; -+ goto done; -+ } - } - - ret = EOK; --- -2.19.1 - diff --git a/SOURCES/0071-utils-refactor-ssh-key-extraction-OpenSSL.patch b/SOURCES/0071-utils-refactor-ssh-key-extraction-OpenSSL.patch deleted file mode 100644 index 6d732d7..0000000 --- a/SOURCES/0071-utils-refactor-ssh-key-extraction-OpenSSL.patch +++ /dev/null @@ -1,133 +0,0 @@ -From ad3356d105835718f57edb7844e1fed911770610 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 14 Nov 2018 15:02:33 +0100 -Subject: [PATCH 71/74] utils: refactor ssh key extraction (OpenSSL) - -Prepare the current code to allow adding other key types. - -Related to https://pagure.io/SSSD/sssd/issue/3887 - -Reviewed-by: Jakub Hrozek ---- - src/util/cert/libcrypto/cert.c | 87 +++++++++++++++++++++------------- - 1 file changed, 53 insertions(+), 34 deletions(-) - -diff --git a/src/util/cert/libcrypto/cert.c b/src/util/cert/libcrypto/cert.c -index c8e07837f..d925c5c5b 100644 ---- a/src/util/cert/libcrypto/cert.c -+++ b/src/util/cert/libcrypto/cert.c -@@ -171,17 +171,13 @@ done: - #define SSH_RSA_HEADER "ssh-rsa" - #define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1) - --errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx, -- const uint8_t *der_blob, size_t der_size, -- uint8_t **key_blob, size_t *key_size) -+static errno_t rsa_pub_key_to_ssh(TALLOC_CTX *mem_ctx, EVP_PKEY *cert_pub_key, -+ uint8_t **key_blob, size_t *key_size) - { - int ret; -+ size_t c; - size_t size; -- const unsigned char *d; - uint8_t *buf = NULL; -- size_t c; -- X509 *cert = NULL; -- EVP_PKEY *cert_pub_key = NULL; - const BIGNUM *n; - const BIGNUM *e; - int modulus_len; -@@ -189,33 +185,6 @@ errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx, - int exponent_len; - unsigned char exponent[OPENSSL_RSA_MAX_PUBEXP_BITS/8]; - -- if (der_blob == NULL || der_size == 0) { -- return EINVAL; -- } -- -- d = (const unsigned char *) der_blob; -- -- cert = d2i_X509(NULL, &d, (int) der_size); -- if (cert == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n"); -- return EINVAL; -- } -- -- cert_pub_key = X509_get_pubkey(cert); -- if (cert_pub_key == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "X509_get_pubkey failed.\n"); -- ret = EIO; -- goto done; -- } -- -- if (EVP_PKEY_base_id(cert_pub_key) != EVP_PKEY_RSA) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "Expected RSA public key, found unsupported [%d].\n", -- EVP_PKEY_base_id(cert_pub_key)); -- ret = EINVAL; -- goto done; -- } -- - #if OPENSSL_VERSION_NUMBER >= 0x10100000L - RSA *rsa_pub_key = NULL; - rsa_pub_key = EVP_PKEY_get0_RSA(cert_pub_key); -@@ -268,6 +237,56 @@ done: - if (ret != EOK) { - talloc_free(buf); - } -+ -+ return ret; -+} -+ -+errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx, -+ const uint8_t *der_blob, size_t der_size, -+ uint8_t **key_blob, size_t *key_size) -+{ -+ int ret; -+ const unsigned char *d; -+ X509 *cert = NULL; -+ EVP_PKEY *cert_pub_key = NULL; -+ -+ if (der_blob == NULL || der_size == 0) { -+ return EINVAL; -+ } -+ -+ d = (const unsigned char *) der_blob; -+ -+ cert = d2i_X509(NULL, &d, (int) der_size); -+ if (cert == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n"); -+ return EINVAL; -+ } -+ -+ cert_pub_key = X509_get_pubkey(cert); -+ if (cert_pub_key == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "X509_get_pubkey failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ switch (EVP_PKEY_base_id(cert_pub_key)) { -+ case EVP_PKEY_RSA: -+ ret = rsa_pub_key_to_ssh(mem_ctx, cert_pub_key, key_blob, key_size); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "rsa_pub_key_to_ssh failed.\n"); -+ goto done; -+ } -+ break; -+ default: -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Expected RSA public key, found unsupported [%d].\n", -+ EVP_PKEY_base_id(cert_pub_key)); -+ ret = EINVAL; -+ goto done; -+ } -+ -+done: -+ - EVP_PKEY_free(cert_pub_key); - X509_free(cert); - --- -2.19.1 - diff --git a/SOURCES/0072-utils-add-ec_pub_key_to_ssh-OpenSSL.patch b/SOURCES/0072-utils-add-ec_pub_key_to_ssh-OpenSSL.patch deleted file mode 100644 index 2fa32d0..0000000 --- a/SOURCES/0072-utils-add-ec_pub_key_to_ssh-OpenSSL.patch +++ /dev/null @@ -1,265 +0,0 @@ -From 41c4661b6fd237b156606bfd0d8ca3edd5a16795 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 14 Nov 2018 21:13:53 +0100 -Subject: [PATCH 72/74] utils: add ec_pub_key_to_ssh() (OpenSSL) - -Add EC key support for the OpenSSL version of the ssh key extraction -code. - -Related to https://pagure.io/SSSD/sssd/issue/3887 - -Reviewed-by: Jakub Hrozek ---- - src/tests/cmocka/test_cert_utils.c | 70 ++++++++++++++++ - src/util/cert/libcrypto/cert.c | 126 ++++++++++++++++++++++++++++- - 2 files changed, 195 insertions(+), 1 deletion(-) - -diff --git a/src/tests/cmocka/test_cert_utils.c b/src/tests/cmocka/test_cert_utils.c -index 26fffb870..9273356eb 100644 ---- a/src/tests/cmocka/test_cert_utils.c -+++ b/src/tests/cmocka/test_cert_utils.c -@@ -40,11 +40,15 @@ - #include "tests/test_CA/SSSD_test_cert_x509_0001.h" - #include "tests/test_CA/SSSD_test_cert_pubsshkey_0002.h" - #include "tests/test_CA/SSSD_test_cert_x509_0002.h" -+#include "tests/test_ECC_CA/SSSD_test_ECC_cert_pubsshkey_0001.h" -+#include "tests/test_ECC_CA/SSSD_test_ECC_cert_x509_0001.h" - #else - #define SSSD_TEST_CERT_0001 "" - #define SSSD_TEST_CERT_SSH_KEY_0001 "" - #define SSSD_TEST_CERT_0002 "" - #define SSSD_TEST_CERT_SSH_KEY_0002 "" -+#define SSSD_TEST_ECC_CERT_0001 "" -+#define SSSD_TEST_ECC_CERT_SSH_KEY_0001 "" - #endif - - /* When run under valgrind with --trace-children=yes we have to increase the -@@ -564,6 +568,70 @@ void test_cert_to_ssh_2keys_invalid_send(void **state) - talloc_free(ev); - } - -+void test_ec_cert_to_ssh_key_done(struct tevent_req *req) -+{ -+ int ret; -+ struct test_state *ts = tevent_req_callback_data(req, struct test_state); -+ struct ldb_val *keys; -+ uint8_t *exp_key; -+ size_t exp_key_size; -+ size_t valid_keys; -+ -+ assert_non_null(ts); -+ ts->done = true; -+ -+ ret = cert_to_ssh_key_recv(req, ts, &keys, &valid_keys); -+ talloc_free(req); -+ assert_int_equal(ret, 0); -+ assert_non_null(keys[0].data); -+ assert_int_equal(valid_keys, 1); -+ -+ exp_key = sss_base64_decode(ts, SSSD_TEST_ECC_CERT_SSH_KEY_0001, -+ &exp_key_size); -+ assert_non_null(exp_key); -+ assert_int_equal(keys[0].length, exp_key_size); -+ assert_memory_equal(keys[0].data, exp_key, exp_key_size); -+ -+ talloc_free(exp_key); -+ talloc_free(keys); -+} -+ -+void test_ec_cert_to_ssh_key_send(void **state) -+{ -+ struct tevent_context *ev; -+ struct tevent_req *req; -+ struct ldb_val val[1]; -+ -+ struct test_state *ts = talloc_get_type_abort(*state, struct test_state); -+ assert_non_null(ts); -+ ts->done = false; -+ -+ val[0].data = sss_base64_decode(ts, SSSD_TEST_ECC_CERT_0001, -+ &val[0].length); -+ assert_non_null(val[0].data); -+ -+ ev = tevent_context_init(ts); -+ assert_non_null(ev); -+ -+ req = cert_to_ssh_key_send(ts, ev, -1, P11_CHILD_TIMEOUT, -+#ifdef HAVE_NSS -+ "sql:" ABS_BUILD_DIR "/src/tests/test_ECC_CA/p11_ecc_nssdb", -+#else -+ ABS_BUILD_DIR "/src/tests/test_ECC_CA/SSSD_test_ECC_CA.pem", -+#endif -+ 1, &val[0], NULL); -+ assert_non_null(req); -+ -+ tevent_req_set_callback(req, test_ec_cert_to_ssh_key_done, ts); -+ -+ while (!ts->done) { -+ tevent_loop_once(ev); -+ } -+ -+ talloc_free(val[0].data); -+ talloc_free(ev); -+} -+ - int main(int argc, const char *argv[]) - { - poptContext pc; -@@ -595,6 +663,8 @@ int main(int argc, const char *argv[]) - setup, teardown), - cmocka_unit_test_setup_teardown(test_cert_to_ssh_2keys_invalid_send, - setup, teardown), -+ cmocka_unit_test_setup_teardown(test_ec_cert_to_ssh_key_send, -+ setup, teardown), - #endif - }; - -diff --git a/src/util/cert/libcrypto/cert.c b/src/util/cert/libcrypto/cert.c -index d925c5c5b..acca07dd0 100644 ---- a/src/util/cert/libcrypto/cert.c -+++ b/src/util/cert/libcrypto/cert.c -@@ -168,6 +168,123 @@ done: - - } - -+/* SSH EC keys are defined in https://tools.ietf.org/html/rfc5656 */ -+#define ECDSA_SHA2_HEADER "ecdsa-sha2-" -+/* Looks like OpenSSH currently only supports the following 3 required -+ * curves. */ -+#define IDENTIFIER_NISTP256 "nistp256" -+#define IDENTIFIER_NISTP384 "nistp384" -+#define IDENTIFIER_NISTP521 "nistp521" -+ -+static errno_t ec_pub_key_to_ssh(TALLOC_CTX *mem_ctx, EVP_PKEY *cert_pub_key, -+ uint8_t **key_blob, size_t *key_size) -+{ -+ int ret; -+ size_t c; -+ uint8_t *buf = NULL; -+ size_t buf_len; -+ EC_KEY *ec_key = NULL; -+ const EC_GROUP *ec_group = NULL; -+ const EC_POINT *ec_public_key = NULL; -+ BN_CTX *bn_ctx = NULL; -+ int key_len; -+ const char *identifier = NULL; -+ int identifier_len; -+ const char *header = NULL; -+ int header_len; -+ -+ ec_key = EVP_PKEY_get1_EC_KEY(cert_pub_key); -+ if (ec_key == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ec_group = EC_KEY_get0_group(ec_key); -+ -+ switch(EC_GROUP_get_curve_name(ec_group)) { -+ case NID_X9_62_prime256v1: -+ identifier = IDENTIFIER_NISTP256; -+ header = ECDSA_SHA2_HEADER IDENTIFIER_NISTP256; -+ break; -+ case NID_secp384r1: -+ identifier = IDENTIFIER_NISTP384; -+ header = ECDSA_SHA2_HEADER IDENTIFIER_NISTP384; -+ break; -+ case NID_secp521r1: -+ identifier = IDENTIFIER_NISTP521; -+ header = ECDSA_SHA2_HEADER IDENTIFIER_NISTP521; -+ break; -+ default: -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported curve [%s]\n", -+ OBJ_nid2sn(EC_GROUP_get_curve_name(ec_group))); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ header_len = strlen(header); -+ identifier_len = strlen(identifier); -+ -+ ec_public_key = EC_KEY_get0_public_key(ec_key); -+ -+ bn_ctx = BN_CTX_new(); -+ if (bn_ctx == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "BN_CTX_new failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ key_len = EC_POINT_point2oct(ec_group, ec_public_key, -+ POINT_CONVERSION_UNCOMPRESSED, NULL, 0, bn_ctx); -+ if (key_len == 0) { -+ DEBUG(SSSDBG_OP_FAILURE, "EC_POINT_point2oct failed.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ buf_len = header_len + identifier_len + key_len + 3 * sizeof(uint32_t); -+ buf = talloc_size(mem_ctx, buf_len * sizeof(uint8_t)); -+ if (buf == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ c = 0; -+ -+ SAFEALIGN_SET_UINT32(buf, htobe32(header_len), &c); -+ safealign_memcpy(&buf[c], header, header_len, &c); -+ -+ SAFEALIGN_SET_UINT32(&buf[c], htobe32(identifier_len), &c); -+ safealign_memcpy(&buf[c], identifier , identifier_len, &c); -+ -+ SAFEALIGN_SET_UINT32(&buf[c], htobe32(key_len), &c); -+ -+ if (EC_POINT_point2oct(ec_group, ec_public_key, -+ POINT_CONVERSION_UNCOMPRESSED, buf + c, key_len, -+ bn_ctx) -+ != key_len) { -+ DEBUG(SSSDBG_OP_FAILURE, "EC_POINT_point2oct failed.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ *key_size = buf_len; -+ *key_blob = buf; -+ -+ ret = EOK; -+ -+done: -+ if (ret != EOK) { -+ talloc_free(buf); -+ } -+ -+ BN_CTX_free(bn_ctx); -+ EC_KEY_free(ec_key); -+ -+ return ret; -+} -+ -+ - #define SSH_RSA_HEADER "ssh-rsa" - #define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1) - -@@ -277,9 +394,16 @@ errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx, - goto done; - } - break; -+ case EVP_PKEY_EC: -+ ret = ec_pub_key_to_ssh(mem_ctx, cert_pub_key, key_blob, key_size); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "rsa_pub_key_to_ssh failed.\n"); -+ goto done; -+ } -+ break; - default: - DEBUG(SSSDBG_CRIT_FAILURE, -- "Expected RSA public key, found unsupported [%d].\n", -+ "Expected RSA or EC public key, found unsupported [%d].\n", - EVP_PKEY_base_id(cert_pub_key)); - ret = EINVAL; - goto done; --- -2.19.1 - diff --git a/SOURCES/0073-utils-refactor-ssh-key-extraction-NSS.patch b/SOURCES/0073-utils-refactor-ssh-key-extraction-NSS.patch deleted file mode 100644 index c3e1ec7..0000000 --- a/SOURCES/0073-utils-refactor-ssh-key-extraction-NSS.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 4e627add38af409ec6a5023212677956babca1e7 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 16 Nov 2018 17:31:00 +0100 -Subject: [PATCH 73/74] utils: refactor ssh key extraction (NSS) - -Prepare the current code to allow adding other key types. - -Related to https://pagure.io/SSSD/sssd/issue/3887 - -Reviewed-by: Jakub Hrozek ---- - src/util/cert/nss/cert.c | 110 +++++++++++++++++++++++---------------- - 1 file changed, 65 insertions(+), 45 deletions(-) - -diff --git a/src/util/cert/nss/cert.c b/src/util/cert/nss/cert.c -index a8efef818..b5c4769a8 100644 ---- a/src/util/cert/nss/cert.c -+++ b/src/util/cert/nss/cert.c -@@ -223,14 +223,10 @@ done: - #define SSH_RSA_HEADER "ssh-rsa" - #define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1) - --errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx, -- uint8_t *der_blob, size_t der_size, -- uint8_t **key_blob, size_t *key_size) -+static errno_t rsa_pub_key_to_ssh(TALLOC_CTX *mem_ctx, -+ SECKEYPublicKey *cert_pub_key, -+ uint8_t **key_blob, size_t *key_size) - { -- CERTCertDBHandle *handle; -- CERTCertificate *cert = NULL; -- SECItem der_item; -- SECKEYPublicKey *cert_pub_key = NULL; - int ret; - size_t size; - uint8_t *buf = NULL; -@@ -238,44 +234,6 @@ errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx, - size_t exponent_prefix_len; - size_t modulus_prefix_len; - -- if (der_blob == NULL || der_size == 0) { -- return EINVAL; -- } -- -- /* initialize NSS if needed */ -- ret = nspr_nss_init(); -- if (ret != EOK) { -- ret = EIO; -- goto done; -- } -- -- handle = CERT_GetDefaultCertDB(); -- -- der_item.len = der_size; -- der_item.data = discard_const(der_blob); -- -- cert = CERT_NewTempCertificate(handle, &der_item, NULL, PR_FALSE, PR_TRUE); -- if (cert == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "CERT_NewTempCertificate failed.\n"); -- ret = EINVAL; -- goto done; -- } -- -- cert_pub_key = CERT_ExtractPublicKey(cert); -- if (cert_pub_key == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "CERT_ExtractPublicKey failed.\n"); -- ret = EIO; -- goto done; -- } -- -- if (cert_pub_key->keyType != rsaKey) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "Expected RSA public key, found unsupported [%d].\n", -- cert_pub_key->keyType); -- ret = EINVAL; -- goto done; -- } -- - /* Looks like nss drops the leading 00 which AFAIK is added to make sure - * the bigint is handled as positive number if the leading bit is set. */ - exponent_prefix_len = 0; -@@ -330,6 +288,68 @@ done: - if (ret != EOK) { - talloc_free(buf); - } -+ -+ return ret; -+} -+ -+errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx, -+ uint8_t *der_blob, size_t der_size, -+ uint8_t **key_blob, size_t *key_size) -+{ -+ CERTCertDBHandle *handle; -+ CERTCertificate *cert = NULL; -+ SECItem der_item; -+ SECKEYPublicKey *cert_pub_key = NULL; -+ int ret; -+ -+ if (der_blob == NULL || der_size == 0) { -+ return EINVAL; -+ } -+ -+ /* initialize NSS if needed */ -+ ret = nspr_nss_init(); -+ if (ret != EOK) { -+ ret = EIO; -+ goto done; -+ } -+ -+ handle = CERT_GetDefaultCertDB(); -+ -+ der_item.len = der_size; -+ der_item.data = discard_const(der_blob); -+ -+ cert = CERT_NewTempCertificate(handle, &der_item, NULL, PR_FALSE, PR_TRUE); -+ if (cert == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "CERT_NewTempCertificate failed.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ cert_pub_key = CERT_ExtractPublicKey(cert); -+ if (cert_pub_key == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "CERT_ExtractPublicKey failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ switch (cert_pub_key->keyType) { -+ case rsaKey: -+ ret = rsa_pub_key_to_ssh(mem_ctx, cert_pub_key, key_blob, key_size); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "rsa_pub_key_to_ssh failed.\n"); -+ goto done; -+ } -+ break; -+ default: -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Expected RSA public key, found unsupported [%d].\n", -+ cert_pub_key->keyType); -+ ret = EINVAL; -+ goto done; -+ } -+ -+done: -+ - SECKEY_DestroyPublicKey(cert_pub_key); - CERT_DestroyCertificate(cert); - --- -2.19.1 - diff --git a/SOURCES/0074-utils-add-ec_pub_key_to_ssh-NSS.patch b/SOURCES/0074-utils-add-ec_pub_key_to_ssh-NSS.patch deleted file mode 100644 index 6ad4d92..0000000 --- a/SOURCES/0074-utils-add-ec_pub_key_to_ssh-NSS.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 3906e5f41a00063127e07f5ca696a25eea2e8bb7 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 16 Nov 2018 18:15:32 +0100 -Subject: [PATCH 74/74] utils: add ec_pub_key_to_ssh() (NSS) - -Add EC key support for the NSS version of the ssh key extraction code. - -Related to https://pagure.io/SSSD/sssd/issue/3887 - -Reviewed-by: Jakub Hrozek ---- - src/util/cert/nss/cert.c | 121 ++++++++++++++++++++++++++++++++++++++- - 1 file changed, 120 insertions(+), 1 deletion(-) - -diff --git a/src/util/cert/nss/cert.c b/src/util/cert/nss/cert.c -index b5c4769a8..ad90da0da 100644 ---- a/src/util/cert/nss/cert.c -+++ b/src/util/cert/nss/cert.c -@@ -220,6 +220,118 @@ done: - return ret; - } - -+/* taken from NSS's lib/cryptohi/seckey.c */ -+static SECOidTag -+sss_SECKEY_GetECCOid(const SECKEYECParams *params) -+{ -+ SECItem oid = { siBuffer, NULL, 0 }; -+ SECOidData *oidData = NULL; -+ -+ /* -+ * params->data needs to contain the ASN encoding of an object ID (OID) -+ * representing a named curve. Here, we strip away everything -+ * before the actual OID and use the OID to look up a named curve. -+ */ -+ if (params->data[0] != SEC_ASN1_OBJECT_ID) -+ return 0; -+ oid.len = params->len - 2; -+ oid.data = params->data + 2; -+ if ((oidData = SECOID_FindOID(&oid)) == NULL) -+ return 0; -+ -+ return oidData->offset; -+} -+ -+/* SSH EC keys are defined in https://tools.ietf.org/html/rfc5656 */ -+#define ECDSA_SHA2_HEADER "ecdsa-sha2-" -+/* Looks like OpenSSH currently only supports the following 3 required -+ * curves. */ -+#define IDENTIFIER_NISTP256 "nistp256" -+#define IDENTIFIER_NISTP384 "nistp384" -+#define IDENTIFIER_NISTP521 "nistp521" -+ -+static errno_t ec_pub_key_to_ssh(TALLOC_CTX *mem_ctx, -+ SECKEYPublicKey *cert_pub_key, -+ uint8_t **key_blob, size_t *key_size) -+{ -+ int ret; -+ size_t c; -+ uint8_t *buf = NULL; -+ size_t buf_len; -+ SECOidTag curve_tag; -+ int key_len; -+ const char *identifier = NULL; -+ int identifier_len; -+ const char *header = NULL; -+ int header_len; -+ SECItem *ec_public_key; -+ -+ curve_tag = sss_SECKEY_GetECCOid(&cert_pub_key->u.ec.DEREncodedParams); -+ switch(curve_tag) { -+ case SEC_OID_ANSIX962_EC_PRIME256V1: -+ identifier = IDENTIFIER_NISTP256; -+ header = ECDSA_SHA2_HEADER IDENTIFIER_NISTP256; -+ break; -+ case SEC_OID_SECG_EC_SECP384R1: -+ identifier = IDENTIFIER_NISTP384; -+ header = ECDSA_SHA2_HEADER IDENTIFIER_NISTP384; -+ break; -+ case SEC_OID_SECG_EC_SECP521R1: -+ identifier = IDENTIFIER_NISTP521; -+ header = ECDSA_SHA2_HEADER IDENTIFIER_NISTP521; -+ break; -+ default: -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported curve [%s]\n", -+ SECOID_FindOIDTagDescription(curve_tag)); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ header_len = strlen(header); -+ identifier_len = strlen(identifier); -+ -+ ec_public_key = &cert_pub_key->u.ec.publicValue; -+ -+ key_len = ec_public_key->len; -+ if (key_len == 0) { -+ DEBUG(SSSDBG_OP_FAILURE, "EC_POINT_point2oct failed.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ buf_len = header_len + identifier_len + key_len + 3 * sizeof(uint32_t); -+ buf = talloc_size(mem_ctx, buf_len * sizeof(uint8_t)); -+ if (buf == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ c = 0; -+ -+ SAFEALIGN_SET_UINT32(buf, htobe32(header_len), &c); -+ safealign_memcpy(&buf[c], header, header_len, &c); -+ -+ SAFEALIGN_SET_UINT32(&buf[c], htobe32(identifier_len), &c); -+ safealign_memcpy(&buf[c], identifier , identifier_len, &c); -+ -+ SAFEALIGN_SET_UINT32(&buf[c], htobe32(key_len), &c); -+ -+ safealign_memcpy(&buf[c], ec_public_key->data, key_len, &c); -+ -+ *key_size = buf_len; -+ *key_blob = buf; -+ -+ ret = EOK; -+ -+done: -+ if (ret != EOK) { -+ talloc_free(buf); -+ } -+ -+ return ret; -+} -+ - #define SSH_RSA_HEADER "ssh-rsa" - #define SSH_RSA_HEADER_LEN (sizeof(SSH_RSA_HEADER) - 1) - -@@ -340,9 +452,16 @@ errno_t get_ssh_key_from_cert(TALLOC_CTX *mem_ctx, - goto done; - } - break; -+ case ecKey: -+ ret = ec_pub_key_to_ssh(mem_ctx, cert_pub_key, key_blob, key_size); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "rsa_pub_key_to_ssh failed.\n"); -+ goto done; -+ } -+ break; - default: - DEBUG(SSSDBG_CRIT_FAILURE, -- "Expected RSA public key, found unsupported [%d].\n", -+ "Expected RSA or EC public key, found unsupported [%d].\n", - cert_pub_key->keyType); - ret = EINVAL; - goto done; --- -2.19.1 - diff --git a/SOURCES/0075-SSSCTL-user-show-says-that-user-is-expired.patch b/SOURCES/0075-SSSCTL-user-show-says-that-user-is-expired.patch deleted file mode 100644 index b960eea..0000000 --- a/SOURCES/0075-SSSCTL-user-show-says-that-user-is-expired.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 291071cb3c04eda7606d62bbff123a0a125c7d60 Mon Sep 17 00:00:00 2001 -From: Tomas Halman -Date: Tue, 13 Nov 2018 12:21:16 +0100 -Subject: [PATCH] SSSCTL: user-show says that user is expired -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -sssctl user-show says that user is expired if the user comes from files -provider. This is ok because files user's expiration time is always set -to 0 but we should print a better, less confusing message. - -The same change apply to groups. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3858 - -Reviewed-by: Pavel Březina ---- - src/tools/sssctl/sssctl_cache.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/src/tools/sssctl/sssctl_cache.c b/src/tools/sssctl/sssctl_cache.c -index 42a2a60fd..e0d067cfb 100644 ---- a/src/tools/sssctl/sssctl_cache.c -+++ b/src/tools/sssctl/sssctl_cache.c -@@ -154,6 +154,11 @@ static errno_t get_attr_expire(TALLOC_CTX *mem_ctx, - return ret; - } - -+ if (is_files_provider(dom)) { -+ *_value = "Never"; -+ return EOK; -+ } -+ - if (value < time(NULL)) { - *_value = "Expired"; - return EOK; -@@ -179,6 +184,11 @@ static errno_t attr_initgr(TALLOC_CTX *mem_ctx, - return ret; - } - -+ if (is_files_provider(dom)) { -+ *_value = "Never"; -+ return EOK; -+ } -+ - if (value < time(NULL)) { - *_value = "Expired"; - return EOK; --- -2.19.1 - diff --git a/SOURCES/0076-sss_iface-prevent-from-using-invalid-names-that-star.patch b/SOURCES/0076-sss_iface-prevent-from-using-invalid-names-that-star.patch deleted file mode 100644 index a444b0c..0000000 --- a/SOURCES/0076-sss_iface-prevent-from-using-invalid-names-that-star.patch +++ /dev/null @@ -1,52 +0,0 @@ -From f47940356462a3f477fe462e71d7680c959300db Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Wed, 14 Nov 2018 11:48:08 +0100 -Subject: [PATCH] sss_iface: prevent from using invalid names that start with - digits - -https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names - -- Bus names that start with a colon (':') character are unique connection names. Other bus names are called well-known bus names. -- Bus names are composed of 1 or more elements separated by a period ('.') character. All elements must contain at least one character. -- Each element must only contain the ASCII characters "[A-Z][a-z][0-9]_-", with "-" discouraged in new bus names. Only elements that are part of a unique connection name may begin with a digit, elements in other bus names must not begin with a digit. -- Bus names must contain at least one '.' (period) character (and thus at least two elements). -- Bus names must not begin with a '.' (period) character. -- Bus names must not exceed the maximum name length (255). - -Resolves: -https://pagure.io/SSSD/sssd/issue/3872 - -Reviewed-by: Jakub Hrozek ---- - src/sss_iface/sss_iface.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/src/sss_iface/sss_iface.c b/src/sss_iface/sss_iface.c -index 644abd71c..e20c14fea 100644 ---- a/src/sss_iface/sss_iface.c -+++ b/src/sss_iface/sss_iface.c -@@ -56,7 +56,9 @@ sss_iface_domain_bus(TALLOC_CTX *mem_ctx, - return NULL; - } - -- bus_name = talloc_asprintf(mem_ctx, "sssd.domain.%s", safe_name); -+ /* Parts of bus names must not start with digit thus we concatenate -+ * the name with underscore instead of period. */ -+ bus_name = talloc_asprintf(mem_ctx, "sssd.domain_%s", safe_name); - talloc_free(safe_name); - - return bus_name; -@@ -66,7 +68,9 @@ char * - sss_iface_proxy_bus(TALLOC_CTX *mem_ctx, - uint32_t id) - { -- return talloc_asprintf(mem_ctx, "sssd.proxy.%"PRIu32, id); -+ /* Parts of bus names must not start with digit thus we concatenate -+ * the name with underscore instead of period. */ -+ return talloc_asprintf(mem_ctx, "sssd.proxy_%"PRIu32, id); - } - - errno_t --- -2.19.1 - diff --git a/SOURCES/0077-nss-use-enumeration-context-as-talloc-parent-for-cac.patch b/SOURCES/0077-nss-use-enumeration-context-as-talloc-parent-for-cac.patch deleted file mode 100644 index 3e2745e..0000000 --- a/SOURCES/0077-nss-use-enumeration-context-as-talloc-parent-for-cac.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 406b731ddfbeb62623640cc37a7adc76af0a4b22 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Tue, 30 Oct 2018 13:21:28 +0100 -Subject: [PATCH] nss: use enumeration context as talloc parent for cache req - result - -Otherwise we end up with memory leak since the result is never freed. - -We need to convert nctx->*ent structures into talloc pointer so -we can use enum_ctx as parent. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3870 - -Reviewed-by: Jakub Hrozek ---- - src/responder/nss/nss_cmd.c | 12 ++++++------ - src/responder/nss/nss_enum.c | 2 +- - src/responder/nss/nss_private.h | 6 +++--- - src/responder/nss/nsssrv.c | 21 +++++++++++++++++++++ - 4 files changed, 31 insertions(+), 10 deletions(-) - -diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c -index 9ee6ca805..25e663ed5 100644 ---- a/src/responder/nss/nss_cmd.c -+++ b/src/responder/nss/nss_cmd.c -@@ -942,7 +942,7 @@ static errno_t nss_cmd_setpwent(struct cli_ctx *cli_ctx) - - nss_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct nss_ctx); - -- return nss_setent(cli_ctx, CACHE_REQ_ENUM_USERS, &nss_ctx->pwent); -+ return nss_setent(cli_ctx, CACHE_REQ_ENUM_USERS, nss_ctx->pwent); - } - - static errno_t nss_cmd_getpwent(struct cli_ctx *cli_ctx) -@@ -955,7 +955,7 @@ static errno_t nss_cmd_getpwent(struct cli_ctx *cli_ctx) - - return nss_getent(cli_ctx, CACHE_REQ_ENUM_USERS, - &state_ctx->pwent, nss_protocol_fill_pwent, -- &nss_ctx->pwent); -+ nss_ctx->pwent); - } - - static errno_t nss_cmd_endpwent(struct cli_ctx *cli_ctx) -@@ -998,7 +998,7 @@ static errno_t nss_cmd_setgrent(struct cli_ctx *cli_ctx) - - nss_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct nss_ctx); - -- return nss_setent(cli_ctx, CACHE_REQ_ENUM_GROUPS, &nss_ctx->grent); -+ return nss_setent(cli_ctx, CACHE_REQ_ENUM_GROUPS, nss_ctx->grent); - } - - static errno_t nss_cmd_getgrent(struct cli_ctx *cli_ctx) -@@ -1011,7 +1011,7 @@ static errno_t nss_cmd_getgrent(struct cli_ctx *cli_ctx) - - return nss_getent(cli_ctx, CACHE_REQ_ENUM_GROUPS, - &state_ctx->grent, nss_protocol_fill_grent, -- &nss_ctx->grent); -+ nss_ctx->grent); - } - - static errno_t nss_cmd_endgrent(struct cli_ctx *cli_ctx) -@@ -1093,7 +1093,7 @@ static errno_t nss_cmd_setservent(struct cli_ctx *cli_ctx) - - nss_ctx = talloc_get_type(cli_ctx->rctx->pvt_ctx, struct nss_ctx); - -- return nss_setent(cli_ctx, CACHE_REQ_ENUM_SVC, &nss_ctx->svcent); -+ return nss_setent(cli_ctx, CACHE_REQ_ENUM_SVC, nss_ctx->svcent); - } - - static errno_t nss_cmd_getservent(struct cli_ctx *cli_ctx) -@@ -1106,7 +1106,7 @@ static errno_t nss_cmd_getservent(struct cli_ctx *cli_ctx) - - return nss_getent(cli_ctx, CACHE_REQ_ENUM_SVC, - &state_ctx->svcent, nss_protocol_fill_svcent, -- &nss_ctx->svcent); -+ nss_ctx->svcent); - } - - static errno_t nss_cmd_endservent(struct cli_ctx *cli_ctx) -diff --git a/src/responder/nss/nss_enum.c b/src/responder/nss/nss_enum.c -index a45b65233..9588943c9 100644 ---- a/src/responder/nss/nss_enum.c -+++ b/src/responder/nss/nss_enum.c -@@ -138,7 +138,7 @@ static void nss_setent_internal_done(struct tevent_req *subreq) - switch (ret) { - case EOK: - talloc_zfree(state->enum_ctx->result); -- state->enum_ctx->result = talloc_steal(state->nss_ctx, result); -+ state->enum_ctx->result = talloc_steal(state->enum_ctx, result); - - if (state->type == CACHE_REQ_NETGROUP_BY_NAME) { - /* We need to expand the netgroup into triples and members. */ -diff --git a/src/responder/nss/nss_private.h b/src/responder/nss/nss_private.h -index aa8d8e9cd..cd0d35517 100644 ---- a/src/responder/nss/nss_private.h -+++ b/src/responder/nss/nss_private.h -@@ -78,9 +78,9 @@ struct nss_ctx { - const char **extra_attributes; - - /* Enumeration. */ -- struct nss_enum_ctx pwent; -- struct nss_enum_ctx grent; -- struct nss_enum_ctx svcent; -+ struct nss_enum_ctx *pwent; -+ struct nss_enum_ctx *grent; -+ struct nss_enum_ctx *svcent; - hash_table_t *netgrent; - - /* Memory cache. */ -diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c -index 3c4edbb53..fb7326a02 100644 ---- a/src/responder/nss/nsssrv.c -+++ b/src/responder/nss/nsssrv.c -@@ -345,6 +345,27 @@ int nss_process_init(TALLOC_CTX *mem_ctx, - goto fail; - } - -+ nctx->pwent = talloc_zero(nctx, struct nss_enum_ctx); -+ if (nctx->pwent == NULL) { -+ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize pwent context!\n"); -+ ret = ENOMEM; -+ goto fail; -+ } -+ -+ nctx->grent = talloc_zero(nctx, struct nss_enum_ctx); -+ if (nctx->grent == NULL) { -+ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize grent context!\n"); -+ ret = ENOMEM; -+ goto fail; -+ } -+ -+ nctx->svcent = talloc_zero(nctx, struct nss_enum_ctx); -+ if (nctx->svcent == NULL) { -+ DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize svcent context!\n"); -+ ret = ENOMEM; -+ goto fail; -+ } -+ - nctx->netgrent = sss_ptr_hash_create(nctx, NULL, NULL); - if (nctx->netgrent == NULL) { - DEBUG(SSSDBG_FATAL_FAILURE, "Unable to initialize netgroups table!\n"); --- -2.19.1 - diff --git a/SOURCES/0078-LDAP-minor-refactoring-in-auth_send-to-conform-to-ou.patch b/SOURCES/0078-LDAP-minor-refactoring-in-auth_send-to-conform-to-ou.patch deleted file mode 100644 index d24017d..0000000 --- a/SOURCES/0078-LDAP-minor-refactoring-in-auth_send-to-conform-to-ou.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 09091b4b60456a989ecc8c3b6f76661a14c108ba Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Thu, 22 Nov 2018 12:51:14 +0100 -Subject: [PATCH 78/80] LDAP: minor refactoring in auth_send() to conform to - our coding style - -Related: -https://pagure.io/SSSD/sssd/issue/3451 - -A tevent _send() function should only return NULL on ENOMEM, otherwise -it should mark the request as failed but return the req pointer. This -was not much of an issue, before, but the next patch will add another -function call to the auth_send call which would make error handling -awkward. - -Reviewed-by: Sumit Bose ---- - src/providers/ldap/ldap_auth.c | 17 +++++++++++------ - 1 file changed, 11 insertions(+), 6 deletions(-) - -diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c -index d40bc9414..c409353d9 100644 ---- a/src/providers/ldap/ldap_auth.c -+++ b/src/providers/ldap/ldap_auth.c -@@ -636,6 +636,7 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, - { - struct tevent_req *req; - struct auth_state *state; -+ errno_t ret; - - req = tevent_req_create(memctx, &state, struct auth_state); - if (!req) return NULL; -@@ -645,11 +646,11 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, - if (sss_authtok_get_type(authtok) == SSS_AUTHTOK_TYPE_SC_PIN - || sss_authtok_get_type(authtok) == SSS_AUTHTOK_TYPE_SC_KEYPAD) { - /* Tell frontend that we do not support Smartcard authentication */ -- tevent_req_error(req, ERR_SC_AUTH_NOT_SUPPORTED); -+ ret = ERR_SC_AUTH_NOT_SUPPORTED; - } else { -- tevent_req_error(req, ERR_AUTH_FAILED); -+ ret = ERR_AUTH_FAILED; - } -- return tevent_req_post(req, ev); -+ goto fail; - } - - state->ev = ev; -@@ -663,13 +664,17 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, - state->sdap_service = ctx->service; - } - -- if (!auth_connect_send(req)) goto fail; -+ if (auth_connect_send(req) == NULL) { -+ ret = ENOMEM; -+ goto fail; -+ } - - return req; - - fail: -- talloc_zfree(req); -- return NULL; -+ tevent_req_error(req, ret); -+ tevent_req_post(req, ev); -+ return req; - } - - static struct tevent_req *auth_connect_send(struct tevent_req *req) --- -2.19.1 - diff --git a/SOURCES/0079-LDAP-Only-authenticate-the-auth-connection-if-we-nee.patch b/SOURCES/0079-LDAP-Only-authenticate-the-auth-connection-if-we-nee.patch deleted file mode 100644 index db77f7c..0000000 --- a/SOURCES/0079-LDAP-Only-authenticate-the-auth-connection-if-we-nee.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 57fc60c9dc77698cf824813c36eb0f90d767b315 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Thu, 22 Nov 2018 12:17:51 +0100 -Subject: [PATCH 79/80] LDAP: Only authenticate the auth connection if we need - to look up user information - -Related: -https://pagure.io/SSSD/sssd/issue/3451 - -Commit add72860c7a7a2c418f4d8b6790b5caeaf7dfb7b initially addressed #3451 by -using the full sdap_cli_connect() request during LDAP authentication. This -was a good idea as it addressed the case where the authentication connection -must also look up some user information (typically with id_provider=proxy -where you don't know the DN to bind as during authentication), but this -approach also broke the use-case of id_provider=ldap and auth_provider=ldap -with ldap_sasl_auth=gssapi. - -This is because (for reason I don't know) AD doesn't like if you use -both GSSAPI and startTLS on the same connection. But the code would -force TLS during the authentication as a general measure to not transmit -passwords in the clear, but then, the connection would also see that -ldap_sasl_auth=gssapi is set and also bind with GSSAPI. - -This patch checks if the user DN is already known and if yes, then -doesn't authenticate the connection as the connection will then only be -used for the user simple bind. - -Reviewed-by: Sumit Bose ---- - src/providers/ldap/ldap_auth.c | 53 +++++++++++++++++++++++++++------- - 1 file changed, 42 insertions(+), 11 deletions(-) - -diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c -index c409353d9..b4d045a65 100644 ---- a/src/providers/ldap/ldap_auth.c -+++ b/src/providers/ldap/ldap_auth.c -@@ -664,6 +664,18 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, - state->sdap_service = ctx->service; - } - -+ ret = get_user_dn(state, state->ctx->be->domain, -+ state->ctx->opts, state->username, &state->dn, -+ &state->pw_expire_type, &state->pw_expire_data); -+ if (ret == EAGAIN) { -+ DEBUG(SSSDBG_TRACE_FUNC, -+ "Need to look up the DN of %s later\n", state->username); -+ } else if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Cannot get user DN [%d]: %s\n", ret, sss_strerror(ret)); -+ goto fail; -+ } -+ - if (auth_connect_send(req) == NULL) { - ret = ENOMEM; - goto fail; -@@ -683,6 +695,8 @@ static struct tevent_req *auth_connect_send(struct tevent_req *req) - struct auth_state *state = tevent_req_data(req, - struct auth_state); - bool use_tls; -+ bool skip_conn_auth = false; -+ const char *sasl_mech; - - /* Check for undocumented debugging feature to disable TLS - * for authentication. This should never be used in production -@@ -695,10 +709,33 @@ static struct tevent_req *auth_connect_send(struct tevent_req *req) - "for debugging purposes only."); - } - -+ if (state->dn != NULL) { -+ /* In case the user's DN is known, the connection will only be used -+ * to bind as the user to perform the authentication. In that case, -+ * we don't need to authenticate the connection, because we're not -+ * looking up any information using the connection. This might be -+ * needed e.g. in case both ID and AUTH providers are set to LDAP -+ * and the server is AD, because otherwise the connection would -+ * both do a startTLS and later bind using GSSAPI which doesn't work -+ * well with AD. -+ */ -+ skip_conn_auth = true; -+ } -+ -+ if (skip_conn_auth == false) { -+ sasl_mech = dp_opt_get_string(state->ctx->opts->basic, -+ SDAP_SASL_MECH); -+ if (sasl_mech && strcasecmp(sasl_mech, "GSSAPI") == 0) { -+ /* Don't force TLS on if we're told to use GSSAPI */ -+ use_tls = false; -+ } -+ } -+ - 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); -+ use_tls ? CON_TLS_ON : CON_TLS_OFF, -+ skip_conn_auth); - - if (subreq == NULL) { - tevent_req_error(req, ENOMEM); -@@ -739,15 +776,7 @@ static void auth_connect_done(struct tevent_req *subreq) - return; - } - -- ret = get_user_dn(state, state->ctx->be->domain, -- state->ctx->opts, state->username, &state->dn, -- &state->pw_expire_type, &state->pw_expire_data); -- if (ret == EOK) { -- /* All required user data was pre-cached during an identity lookup. -- * We can proceed with the bind */ -- auth_do_bind(req); -- return; -- } else if (ret == EAGAIN) { -+ if (state->dn == NULL) { - /* The cached user entry was missing the bind DN. Need to look - * it up based on user name in order to perform the bind */ - subreq = get_user_dn_send(req, state->ev, state->ctx->be->domain, -@@ -760,7 +789,9 @@ static void auth_connect_done(struct tevent_req *subreq) - return; - } - -- tevent_req_error(req, ret); -+ /* All required user data was pre-cached during an identity lookup. -+ * We can proceed with the bind */ -+ auth_do_bind(req); - return; - } - --- -2.19.1 - diff --git a/SOURCES/0080-LDAP-Log-the-encryption-used-during-LDAP-authenticat.patch b/SOURCES/0080-LDAP-Log-the-encryption-used-during-LDAP-authenticat.patch deleted file mode 100644 index 435ecae..0000000 --- a/SOURCES/0080-LDAP-Log-the-encryption-used-during-LDAP-authenticat.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 6f113c7ddeaa5c82558e10118b499d22bf7a2b14 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 26 Nov 2018 12:38:40 +0100 -Subject: [PATCH 80/80] LDAP: Log the encryption used during LDAP - authentication - -Reviewed-by: Jakub Hrozek ---- - src/providers/ldap/ldap_auth.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c -index b4d045a65..4666dbfbb 100644 ---- a/src/providers/ldap/ldap_auth.c -+++ b/src/providers/ldap/ldap_auth.c -@@ -747,6 +747,31 @@ static struct tevent_req *auth_connect_send(struct tevent_req *req) - return subreq; - } - -+static void check_encryption(LDAP *ldap) -+{ -+ ber_len_t sasl_ssf = 0; -+ int tls_inplace = 0; -+ int ret; -+ -+ ret = ldap_get_option(ldap, LDAP_OPT_X_SASL_SSF, &sasl_ssf); -+ if (ret != LDAP_SUCCESS) { -+ DEBUG(SSSDBG_TRACE_LIBS, "ldap_get_option failed to get sasl ssf, " -+ "assuming SASL is not used.\n"); -+ } -+ -+ tls_inplace = ldap_tls_inplace(ldap); -+ -+ DEBUG(SSSDBG_TRACE_ALL, -+ "Encryption used: SASL SSF [%lu] tls_inplace [%s].\n", sasl_ssf, -+ tls_inplace == 1 ? "TLS inplace" : "TLS NOT inplace"); -+ -+ if (sasl_ssf <= 1 && tls_inplace != 1) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "No encryption detected on LDAP connection.\n"); -+ sss_log(SSS_LOG_CRIT, "No encryption detected on LDAP connection.\n"); -+ } -+} -+ - static void auth_connect_done(struct tevent_req *subreq) - { - struct tevent_req *req = tevent_req_callback_data(subreq, -@@ -776,6 +801,8 @@ static void auth_connect_done(struct tevent_req *subreq) - return; - } - -+ check_encryption(state->sh->ldap); -+ - if (state->dn == NULL) { - /* The cached user entry was missing the bind DN. Need to look - * it up based on user name in order to perform the bind */ --- -2.19.1 - diff --git a/SOURCES/0081-nss-sssd-returns-for-emtpy-home-directories.patch b/SOURCES/0081-nss-sssd-returns-for-emtpy-home-directories.patch deleted file mode 100644 index 6560880..0000000 --- a/SOURCES/0081-nss-sssd-returns-for-emtpy-home-directories.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 90f32399b4100ce39cf665649fde82d215e5eb49 Mon Sep 17 00:00:00 2001 -From: Tomas Halman -Date: Mon, 3 Dec 2018 14:11:31 +0100 -Subject: [PATCH] nss: sssd returns '/' for emtpy home directories - -For empty home directory in passwd file sssd returns "/". Sssd -should respect system behaviour and return the same as nsswitch -"files" module - return empty string. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3901 - -Reviewed-by: Simo Sorce -Reviewed-by: Jakub Hrozek ---- - src/confdb/confdb.c | 9 +++++++++ - src/man/include/ad_modified_defaults.xml | 19 +++++++++++++++++++ - src/responder/nss/nss_protocol_pwent.c | 2 +- - src/tests/intg/test_files_provider.py | 2 +- - 4 files changed, 30 insertions(+), 2 deletions(-) - -diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c -index b0d886c9d..d3fdd3199 100644 ---- a/src/confdb/confdb.c -+++ b/src/confdb/confdb.c -@@ -1301,6 +1301,15 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb, - ret = ENOMEM; - goto done; - } -+ } else { -+ if (strcasecmp(domain->provider, "ad") == 0) { -+ /* ad provider default */ -+ domain->fallback_homedir = talloc_strdup(domain, "/home/%d/%u"); -+ if (!domain->fallback_homedir) { -+ ret = ENOMEM; -+ goto done; -+ } -+ } - } - - tmp = ldb_msg_find_attr_as_string(res->msgs[0], -diff --git a/src/man/include/ad_modified_defaults.xml b/src/man/include/ad_modified_defaults.xml -index 818a2bf78..425b7e8ee 100644 ---- a/src/man/include/ad_modified_defaults.xml -+++ b/src/man/include/ad_modified_defaults.xml -@@ -76,4 +76,23 @@ - - - -+ -+ NSS configuration -+ -+ -+ -+ fallback_homedir = /home/%d/%u -+ -+ -+ The AD provider automatically sets -+ "fallback_homedir = /home/%d/%u" to provide personal -+ home directories for users without the homeDirectory -+ attribute. If your AD Domain is properly -+ populated with Posix attributes, and you want to avoid -+ this fallback behavior, you can explicitly -+ set "fallback_homedir = %o". -+ -+ -+ -+ - -diff --git a/src/responder/nss/nss_protocol_pwent.c b/src/responder/nss/nss_protocol_pwent.c -index af9e74fc8..86fa4ec46 100644 ---- a/src/responder/nss/nss_protocol_pwent.c -+++ b/src/responder/nss/nss_protocol_pwent.c -@@ -118,7 +118,7 @@ nss_get_homedir(TALLOC_CTX *mem_ctx, - - homedir = nss_get_homedir_override(mem_ctx, msg, nss_ctx, domain, &hd_ctx); - if (homedir == NULL) { -- return "/"; -+ return ""; - } - - return homedir; -diff --git a/src/tests/intg/test_files_provider.py b/src/tests/intg/test_files_provider.py -index f0155a2f7..b5e5c3fd9 100644 ---- a/src/tests/intg/test_files_provider.py -+++ b/src/tests/intg/test_files_provider.py -@@ -656,7 +656,7 @@ def test_user_no_dir(setup_pw_with_canary, files_domain_only): - Test that resolving a user without a homedir defined works and returns - a fallback value - """ -- check_user(incomplete_user_setup(setup_pw_with_canary, 'dir', '/')) -+ check_user(incomplete_user_setup(setup_pw_with_canary, 'dir', '')) - - - def test_user_no_gecos(setup_pw_with_canary, files_domain_only): --- -2.19.1 - diff --git a/SOURCES/0082-PROXY-Copy-the-response-to-the-caller.patch b/SOURCES/0082-PROXY-Copy-the-response-to-the-caller.patch deleted file mode 100644 index e619358..0000000 --- a/SOURCES/0082-PROXY-Copy-the-response-to-the-caller.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 807bbce25ffedb6f0d2d61831b5d5133e11aa84a Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 3 Dec 2018 23:26:46 +0100 -Subject: [PATCH] PROXY: Copy the response to the caller - -Resolves: -https://pagure.io/SSSD/sssd/issue/3892 - -Reviewed-by: Jakub Hrozek ---- - src/providers/proxy/proxy_auth.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/src/providers/proxy/proxy_auth.c b/src/providers/proxy/proxy_auth.c -index 3c5affeb5..926ce98f4 100644 ---- a/src/providers/proxy/proxy_auth.c -+++ b/src/providers/proxy/proxy_auth.c -@@ -570,6 +570,7 @@ done: - static void proxy_pam_conv_done(struct tevent_req *subreq) - { - struct pam_data *response; -+ struct response_data *resp; - struct proxy_conv_ctx *state; - struct tevent_req *req; - errno_t ret; -@@ -583,8 +584,6 @@ static void proxy_pam_conv_done(struct tevent_req *subreq) - /* Kill the child */ - kill(state->pid, SIGKILL); - -- // TODO copy response to pd -- - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get reply from child [%d]: %s\n", - ret, sss_strerror(ret)); -@@ -593,6 +592,19 @@ static void proxy_pam_conv_done(struct tevent_req *subreq) - return; - } - -+ state->pd->pam_status = response->pam_status; -+ state->pd->account_locked = response->account_locked; -+ -+ for (resp = response->resp_list; resp != NULL; resp = resp->next) { -+ talloc_steal(state->pd, resp); -+ -+ if (resp->next == NULL) { -+ resp->next = state->pd->resp_list; -+ state->pd->resp_list = response->resp_list; -+ break; -+ } -+ } -+ - DEBUG(SSSDBG_CONF_SETTINGS, "received: [%d][%s]\n", - state->pd->pam_status, - state->pd->domain); --- -2.19.1 - diff --git a/SOURCES/0083-Revert-IPA-use-forest-name-when-looking-up-the-Globa.patch b/SOURCES/0083-Revert-IPA-use-forest-name-when-looking-up-the-Globa.patch deleted file mode 100644 index 6b167a4..0000000 --- a/SOURCES/0083-Revert-IPA-use-forest-name-when-looking-up-the-Globa.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 9096fc01cca8fcaeb19c36a27f3a9fa09d60772a Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 4 Dec 2018 13:08:11 +0100 -Subject: [PATCH 83/84] Revert "IPA: use forest name when looking up the Global - Catalog" - -This reverts commit 149174acae677d1e72a0da431bf0850d55f2ccb4. - -Reviewed-by: Jakub Hrozek ---- - src/providers/ipa/ipa_subdomains_server.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c -index e5ea4bd02..43a3053cb 100644 ---- a/src/providers/ipa/ipa_subdomains_server.c -+++ b/src/providers/ipa/ipa_subdomains_server.c -@@ -266,7 +266,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx, - DEBUG(SSSDBG_TRACE_ALL, "No extra attrs set.\n"); - } - -- gc_service_name = talloc_asprintf(ad_options, "sd_gc_%s", subdom->forest); -+ gc_service_name = talloc_asprintf(ad_options, "sd_gc_%s", subdom->name); - if (gc_service_name == NULL) { - talloc_free(ad_options); - return ENOMEM; --- -2.19.1 - diff --git a/SOURCES/0084-ipa-use-only-the-global-catalog-service-of-the-fores.patch b/SOURCES/0084-ipa-use-only-the-global-catalog-service-of-the-fores.patch deleted file mode 100644 index 904a923..0000000 --- a/SOURCES/0084-ipa-use-only-the-global-catalog-service-of-the-fores.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 62d671b874a66101c0f4bff39fc6d7f49cb8fca6 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 4 Dec 2018 13:06:23 +0100 -Subject: [PATCH 84/84] ipa: use only the global catalog service of the forest - root - -While creating the domains and sub-domains each domain gets a global -catalog services assigned but only one should be used because the global -catalog is by definition responsible for the whole forest so it does not -make sense to use a global catalog service for each domain and in the -worst case connect to the same GC multiple times. - -In the AD provider this is simple because the GC service of the -configured domain AD_GC_SERVICE_NAME ("AD_GC") can be used. In the IPA -case all domains from the trusted forest are on the level of sub-domains -so we have to pick one. Since the forest root is linked from all domain -of the same forest it will be the most straight forward choice. - -Related to https://pagure.io/SSSD/sssd/issue/3902 - -Reviewed-by: Jakub Hrozek ---- - src/providers/ipa/ipa_subdomains_id.c | 50 +++++++++++++++++++++++++-- - 1 file changed, 47 insertions(+), 3 deletions(-) - -diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c -index a16eed284..48cf74460 100644 ---- a/src/providers/ipa/ipa_subdomains_id.c -+++ b/src/providers/ipa/ipa_subdomains_id.c -@@ -713,6 +713,52 @@ int ipa_get_subdom_acct_recv(struct tevent_req *req, int *dp_error_out) - return EOK; - } - -+static struct ad_id_ctx *ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx, -+ struct sss_domain_info *dom); -+ -+static struct sdap_id_conn_ctx ** -+ipa_ad_gc_conn_list(TALLOC_CTX *mem_ctx, struct ipa_id_ctx *ipa_ctx, -+ struct ad_id_ctx *ad_ctx, struct sss_domain_info *dom) -+{ -+ struct ad_id_ctx *forest_root_ad_id_ctx; -+ struct sdap_id_conn_ctx **clist; -+ int cindex = 0; -+ -+ /* While creating the domains and sub-domains each domain gets a global -+ * catalog services assigned but only one should be used because the -+ * global catalog is by definition responsible for the whole forest so it -+ * does not make sense to use a global catalog service for each domain and -+ * in the worst case connect to the same GC multiple times. -+ * -+ * In the AD provider this is simple because the GC service of the -+ * configured domain AD_GC_SERVICE_NAME ("AD_GC") can be used. In the IPA -+ * case all domains from the trusted forest are on the level of -+ * sub-domains so we have to pick one. Since the forest root is linked -+ * from all domain of the same forest it will be the most straight forward -+ * choice. */ -+ forest_root_ad_id_ctx = ipa_get_ad_id_ctx(ipa_ctx, dom->forest_root); -+ if (forest_root_ad_id_ctx == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "Missing ad_id_ctx for forest root.\n"); -+ return NULL; -+ } -+ -+ clist = talloc_zero_array(mem_ctx, struct sdap_id_conn_ctx *, 3); -+ if (clist == NULL) return NULL; -+ -+ /* Always try GC first */ -+ if (dp_opt_get_bool(forest_root_ad_id_ctx->ad_options->basic, -+ AD_ENABLE_GC)) { -+ clist[cindex] = forest_root_ad_id_ctx->gc_ctx; -+ clist[cindex]->ignore_mark_offline = true; -+ clist[cindex]->no_mpg_user_fallback = true; -+ cindex++; -+ } -+ -+ clist[cindex] = ad_get_dom_ldap_conn(ad_ctx, dom); -+ -+ return clist; -+} -+ - /* IPA lookup for server mode. Directly to AD. */ - struct ipa_get_ad_acct_state { - int dp_error; -@@ -731,8 +777,6 @@ static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req); - static errno_t ipa_get_ad_ipa_membership_step(struct tevent_req *req); - static void ipa_id_get_groups_overrides_done(struct tevent_req *subreq); - static void ipa_get_ad_acct_done(struct tevent_req *subreq); --static struct ad_id_ctx *ipa_get_ad_id_ctx(struct ipa_id_ctx *ipa_ctx, -- struct sss_domain_info *dom); - - static struct tevent_req * - ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx, -@@ -785,7 +829,7 @@ ipa_get_ad_acct_send(TALLOC_CTX *mem_ctx, - case BE_REQ_INITGROUPS: - case BE_REQ_BY_SECID: - case BE_REQ_GROUP: -- clist = ad_gc_conn_list(req, ad_id_ctx, state->obj_dom); -+ clist = ipa_ad_gc_conn_list(req, ipa_ctx, ad_id_ctx, state->obj_dom); - break; - default: - clist = ad_ldap_conn_list(req, ad_id_ctx, state->obj_dom); --- -2.19.1 - diff --git a/SOURCES/0085-krb5_child-fix-permissions-during-SC-auth.patch b/SOURCES/0085-krb5_child-fix-permissions-during-SC-auth.patch deleted file mode 100644 index 6765540..0000000 --- a/SOURCES/0085-krb5_child-fix-permissions-during-SC-auth.patch +++ /dev/null @@ -1,138 +0,0 @@ -From e49e9f727e4960c8a0a2ed50488dac6e51ddf284 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 10 Dec 2018 17:44:13 +0100 -Subject: [PATCH] krb5_child: fix permissions during SC auth - -For PKINIT we might need access to the pcscd socket which by default is -only allowed for authenticated users. Since PKINIT is part of the -authentication and the user is not authenticated yet, we have to use -different privileges and can only drop it only after the TGT is -received. The fast_uid and fast_gid are the IDs the backend is running -with. This can be either root or the 'sssd' user. Root is allowed by -default and the 'sssd' user is allowed with the help of the -sssd-pcsc.rules policy-kit rule. So those IDs are a suitable choice. We -can only call switch_creds() because after the TGT is returned we have -to switch to the IDs of the user to store the TGT. - -The final change to the IDs of the user is not only important for KCM -type credential caches but for file based ccache types like FILE or DIR -as well. - -Related to https://pagure.io/SSSD/sssd/issue/3903 - -Reviewed-by: Jakub Hrozek ---- - src/providers/krb5/krb5_child.c | 64 ++++++++++++++++++++------------- - 1 file changed, 39 insertions(+), 25 deletions(-) - -diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c -index a578930a9..7ad411914 100644 ---- a/src/providers/krb5/krb5_child.c -+++ b/src/providers/krb5/krb5_child.c -@@ -108,6 +108,7 @@ struct krb5_req { - - uid_t fast_uid; - gid_t fast_gid; -+ struct sss_creds *pcsc_saved_creds; - - struct cli_opts *cli_opts; - }; -@@ -1746,6 +1747,22 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr, - goto done; - } - -+ kerr = restore_creds(kr->pcsc_saved_creds); -+ if (kerr != 0) { -+ DEBUG(SSSDBG_OP_FAILURE, "restore_creds failed.\n"); -+ } -+ /* Make sure ccache is created and written as the user */ -+ if (geteuid() != kr->uid || getegid() != kr->gid) { -+ kerr = k5c_become_user(kr->uid, kr->gid, kr->posix_domain); -+ if (kerr != 0) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n"); -+ goto done; -+ } -+ } -+ -+ DEBUG(SSSDBG_TRACE_INTERNAL, -+ "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid()); -+ - /* If kr->ccname is cache collection (DIR:/...), we want to work - * directly with file ccache (DIR::/...), but cache collection - * should be returned back to back end. -@@ -2998,20 +3015,6 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline) - krb5_error_code kerr; - int parse_flags; - -- if (offline || (kr->fast_val == K5C_FAST_NEVER && kr->validate == false)) { -- /* If krb5_child was started as setuid, but we don't need to -- * perform either validation or FAST, just drop privileges to -- * the user who is logging in. The same applies to the offline case. -- */ -- kerr = k5c_become_user(kr->uid, kr->gid, kr->posix_domain); -- if (kerr != 0) { -- DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n"); -- return kerr; -- } -- } -- DEBUG(SSSDBG_TRACE_INTERNAL, -- "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid()); -- - /* Set the global error context */ - krb5_error_ctx = kr->ctx; - -@@ -3205,8 +3208,8 @@ int main(int argc, const char *argv[]) - const char *opt_logger = NULL; - errno_t ret; - krb5_error_code kerr; -- uid_t fast_uid; -- gid_t fast_gid; -+ uid_t fast_uid = 0; -+ gid_t fast_gid = 0; - struct cli_opts cli_opts = { 0 }; - int sss_creds_password = 0; - -@@ -3320,20 +3323,31 @@ int main(int argc, const char *argv[]) - goto done; - } - -- /* pkinit needs access to pcscd */ -- if ((sss_authtok_get_type(kr->pd->authtok) != SSS_AUTHTOK_TYPE_SC_PIN -- && sss_authtok_get_type(kr->pd->authtok) -- != SSS_AUTHTOK_TYPE_SC_KEYPAD)) { -+ /* For PKINIT we might need access to the pcscd socket which by default -+ * is only allowed for authenticated users. Since PKINIT is part of -+ * the authentication and the user is not authenticated yet, we have -+ * to use different privileges and can only drop it only after the TGT is -+ * received. The fast_uid and fast_gid are the IDs the backend is running -+ * with. This can be either root or the 'sssd' user. Root is allowed by -+ * default and the 'sssd' user is allowed with the help of the -+ * sssd-pcsc.rules policy-kit rule. So those IDs are a suitable choice. We -+ * can only call switch_creds() because after the TGT is returned we have -+ * to switch to the IDs of the user to store the TGT. */ -+ if (IS_SC_AUTHTOK(kr->pd->authtok)) { -+ kerr = switch_creds(kr, kr->fast_uid, kr->fast_gid, 0, NULL, -+ &kr->pcsc_saved_creds); -+ } else { - kerr = k5c_become_user(kr->uid, kr->gid, kr->posix_domain); -- if (kerr != 0) { -- DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n"); -- ret = EFAULT; -- goto done; -- } -+ } -+ if (kerr != 0) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "become_user failed.\n"); -+ ret = EFAULT; -+ goto done; - } - - DEBUG(SSSDBG_TRACE_INTERNAL, - "Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid()); -+ - try_open_krb5_conf(); - - ret = k5c_setup(kr, offline); --- -2.19.1 - diff --git a/SOURCES/0086-MAN-Explicitly-state-that-not-all-generic-domain-opt.patch b/SOURCES/0086-MAN-Explicitly-state-that-not-all-generic-domain-opt.patch deleted file mode 100644 index 078fe9f..0000000 --- a/SOURCES/0086-MAN-Explicitly-state-that-not-all-generic-domain-opt.patch +++ /dev/null @@ -1,36 +0,0 @@ -From f94881d4d34959231fedbaafd5f1fd6f5e9d8924 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Thu, 3 Jan 2019 15:32:26 +0100 -Subject: [PATCH] MAN: Explicitly state that not all generic domain options are - supported for the files provider - -Resolves: -https://pagure.io/SSSD/sssd/issue/3882 - -Reviewed-by: Tomas Halman ---- - src/man/sssd-files.5.xml | 8 +++++++- - 1 file changed, 7 insertions(+), 1 deletion(-) - -diff --git a/src/man/sssd-files.5.xml b/src/man/sssd-files.5.xml -index 067e21949..34b107965 100644 ---- a/src/man/sssd-files.5.xml -+++ b/src/man/sssd-files.5.xml -@@ -84,7 +84,13 @@ - sssd.conf - 5 - manual page for details on the configuration -- of an SSSD domain. -+ of an SSSD domain. But the purpose of the files provider is -+ to expose the same data as the UNIX files, just through the -+ SSSD interfaces. Therefore not all generic domain options are -+ supported. Likewise, some global options, such as overriding -+ the shell in the nss section for all domains -+ has no effect on the files domain unless explicitly specified -+ per-domain. - - - passwd_files (string) --- -2.19.1 - diff --git a/SOURCES/0087-KCM-Deleting-a-non-existent-ccache-should-not-yield-.patch b/SOURCES/0087-KCM-Deleting-a-non-existent-ccache-should-not-yield-.patch deleted file mode 100644 index dcc0d83..0000000 --- a/SOURCES/0087-KCM-Deleting-a-non-existent-ccache-should-not-yield-.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 02c15d40efe6dd9107528469904f1315fca37416 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Thu, 3 Jan 2019 15:07:59 +0100 -Subject: [PATCH 87/88] KCM: Deleting a non-existent ccache should not yield an - error - -Resolves: -https://pagure.io/SSSD/sssd/issue/3910 - -When the KCM destroy operation is called, it receives a name as an input. If -the name cannot be found, we would currently return KRB5_CC_NOTFOUND. But -other ccache types return KRB5_FCC_NOFILE in that case and e.g. utilities -like kdestroy special case KRB5_FCC_NOFILE to be non-fatal. - -Reviewed-by: Tomas Halman ---- - src/responder/kcm/kcmsrv_ops.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c -index 1e229adc4..9352909f4 100644 ---- a/src/responder/kcm/kcmsrv_ops.c -+++ b/src/responder/kcm/kcmsrv_ops.c -@@ -698,9 +698,10 @@ static void kcm_op_destroy_getbyname_done(struct tevent_req *subreq) - ret = kcm_ccdb_uuid_by_name_recv(subreq, state, uuid); - talloc_zfree(subreq); - if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -+ DEBUG(SSSDBG_MINOR_FAILURE, - "Cannot get matching ccache [%d]: %s\n", - ret, sss_strerror(ret)); -+ ret = ERR_NO_MATCHING_CREDS; - tevent_req_error(req, ret); - return; - } --- -2.19.1 - diff --git a/SOURCES/0088-confdb-Always-read-snippet-files.patch b/SOURCES/0088-confdb-Always-read-snippet-files.patch deleted file mode 100644 index c6d5ef0..0000000 --- a/SOURCES/0088-confdb-Always-read-snippet-files.patch +++ /dev/null @@ -1,220 +0,0 @@ -From 8a3517c5466c107f4d4e0970a1c33b51d6c762f8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michal=20=C5=BDidek?= -Date: Wed, 9 Jan 2019 14:08:29 +0100 -Subject: [PATCH 88/89] confdb: Always read snippet files - -This patch removes the ldif with fallback configuration -and adds the fallback configuration as in-memory -INI snippet. - -Fixes: -https://pagure.io/SSSD/sssd/issue/3439 - -Reviewed-by: Jakub Hrozek ---- - src/confdb/confdb_setup.c | 122 +++++++++++++++++--------------------- - src/util/sss_ini.c | 13 +++- - src/util/sss_ini.h | 5 ++ - 3 files changed, 70 insertions(+), 70 deletions(-) - -diff --git a/src/confdb/confdb_setup.c b/src/confdb/confdb_setup.c -index 7acefbe6b..7d039341d 100644 ---- a/src/confdb/confdb_setup.c -+++ b/src/confdb/confdb_setup.c -@@ -28,16 +28,6 @@ - #include "confdb_setup.h" - #include "util/sss_ini.h" - --#ifndef SSSD_FALLBACK_CONFIG_LDIF --#define SSSD_FALLBACK_CONFIG_LDIF \ --"dn: cn=config\n" \ --"version: 2\n\n" \ --"dn: cn=sssd,cn=config\n" \ --"cn: sssd\n" \ --"enable_files_domain: true\n" \ --"services: nss\n\n" --#endif /* SSSD_FALLBACK_CONFIG_LDIF */ -- - static int confdb_test(struct confdb_ctx *cdb) - { - char **values; -@@ -146,28 +136,52 @@ static int confdb_ldif_from_ini_file(TALLOC_CTX *mem_ctx, - errno_t ret; - char timestr[21]; - int version; -+ char fallback_cfg[] = -+ "[sssd]\n" -+ "enable_files_domain = true\n" -+ "services = nss\n"; - -- ret = sss_ini_config_access_check(init_data); -- if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "Permission check on config file failed.\n"); -- return EPERM; -- } -+ /* Open config file */ -+ ret = sss_ini_config_file_open(init_data, config_file); -+ if (ret == ENOENT) { -+ DEBUG(SSSDBG_TRACE_FUNC, "No sssd.conf.\n"); -+ ret = sss_ini_config_file_from_mem(fallback_cfg, -+ strlen(fallback_cfg), -+ init_data); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "sss_ini_config_file_from_mem failed. Error %d: %s\n", -+ ret, sss_strerror(ret)); -+ return ret; -+ } -+ } else if (ret == EOK) { -+ ret = sss_ini_config_access_check(init_data); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Permission check on config file failed.\n"); -+ return EPERM; -+ } - -- ret = sss_ini_get_stat(init_data); -- if (ret != EOK) { -- ret = errno; -- DEBUG(SSSDBG_FATAL_FAILURE, -+ ret = sss_ini_get_stat(init_data); -+ if (ret != EOK) { -+ ret = errno; -+ DEBUG(SSSDBG_FATAL_FAILURE, - "Status check on config file failed.\n"); -- return ret; -- } -+ return ret; -+ } - -- errno = 0; -- ret = sss_ini_get_mtime(init_data, sizeof(timestr), timestr); -- if (ret <= 0 || ret >= (int)sizeof(timestr)) { -- DEBUG(SSSDBG_FATAL_FAILURE, -- "Failed to convert time_t to string??\n"); -- ret = errno ? errno : EFAULT; -+ errno = 0; -+ ret = sss_ini_get_mtime(init_data, sizeof(timestr), timestr); -+ if (ret <= 0 || ret >= (int)sizeof(timestr)) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "Failed to convert time_t to string??\n"); -+ ret = errno ? errno : EFAULT; -+ return ret; -+ } -+ } else { -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "sss_ini_config_file_open failed: %s [%d]\n", sss_strerror(ret), -+ ret); - return ret; - } - -@@ -237,19 +251,6 @@ static int confdb_ldif_from_ini_file(TALLOC_CTX *mem_ctx, - return EOK; - } - --static int confdb_fallback_ldif(TALLOC_CTX *mem_ctx, -- const char **_timestr, -- const char **_ldif) --{ -- *_timestr = talloc_strdup(mem_ctx, "1"); -- *_ldif = talloc_strdup(mem_ctx, SSSD_FALLBACK_CONFIG_LDIF); -- if (*_timestr == NULL || *_ldif == NULL) { -- return ENOMEM; -- } -- -- return EOK; --} -- - static int confdb_write_ldif(struct confdb_ctx *cdb, - const char *config_ldif, - bool replace_whole_db) -@@ -318,34 +319,17 @@ static int confdb_init_db(const char *config_file, - goto done; - } - -- /* Open config file */ -- ret = sss_ini_config_file_open(init_data, config_file); -- if (ret == EOK) { -- ret = confdb_ldif_from_ini_file(tmp_ctx, -- config_file, -- config_dir, -- only_section, -- init_data, -- ×tr, -- &config_ldif); -- if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "Cannot convert INI to LDIF [%d]: [%s]\n", -- ret, sss_strerror(ret)); -- goto done; -- } -- } else if (ret == ENOENT) { -- ret = confdb_fallback_ldif(tmp_ctx, ×tr, &config_ldif); -- if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "Cannot create a fallback configuration [%d]: [%s]\n", -- ret, sss_strerror(ret)); -- goto done; -- } -- } else { -- DEBUG(SSSDBG_CONF_SETTINGS, -- "sss_ini_config_file_open failed: %s [%d]\n", sss_strerror(ret), -- ret); -+ ret = confdb_ldif_from_ini_file(tmp_ctx, -+ config_file, -+ config_dir, -+ only_section, -+ init_data, -+ ×tr, -+ &config_ldif); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Cannot convert INI to LDIF [%d]: [%s]\n", -+ ret, sss_strerror(ret)); - goto done; - } - -diff --git a/src/util/sss_ini.c b/src/util/sss_ini.c -index 3c15b2809..010b77889 100644 ---- a/src/util/sss_ini.c -+++ b/src/util/sss_ini.c -@@ -123,7 +123,18 @@ int sss_ini_config_file_open(struct sss_ini_initdata *init_data, - #endif - } - -- -+int sss_ini_config_file_from_mem(void *data_buf, -+ uint32_t data_len, -+ struct sss_ini_initdata *init_data) -+{ -+#ifdef HAVE_LIBINI_CONFIG_V1 -+ return ini_config_file_from_mem(data_buf, strlen(data_buf), -+ &init_data->file); -+#else -+ /* FIXME: Remove support for older libini versions */ -+ return EINVAL; -+#endif -+} - - /* Check configuration file permissions */ - -diff --git a/src/util/sss_ini.h b/src/util/sss_ini.h -index 470b88f99..0bf9c0ff5 100644 ---- a/src/util/sss_ini.h -+++ b/src/util/sss_ini.h -@@ -45,6 +45,11 @@ void sss_ini_close_file(struct sss_ini_initdata *init_data); - int sss_ini_config_file_open(struct sss_ini_initdata *init_data, - const char *config_file); - -+/* Load config from buffer */ -+int sss_ini_config_file_from_mem(void *data_buf, -+ uint32_t data_len, -+ struct sss_ini_initdata *init_data); -+ - /* Check file permissions */ - int sss_ini_config_access_check(struct sss_ini_initdata *init_data); - --- -2.19.1 - diff --git a/SOURCES/0089-CONFDB-Remove-old-libini-support.patch b/SOURCES/0089-CONFDB-Remove-old-libini-support.patch deleted file mode 100644 index a148912..0000000 --- a/SOURCES/0089-CONFDB-Remove-old-libini-support.patch +++ /dev/null @@ -1,269 +0,0 @@ -From b66f8dc3bd4e89c424bef5953aeb70742f9656dd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michal=20=C5=BDidek?= -Date: Wed, 9 Jan 2019 14:19:26 +0100 -Subject: [PATCH 89/89] CONFDB: Remove old libini support - -Remove code code that uses libini older then v1 - -Related: -https://pagure.io/SSSD/sssd/issue/3439 - -Reviewed-by: Jakub Hrozek ---- - src/util/sss_ini.c | 111 +-------------------------------------------- - 1 file changed, 1 insertion(+), 110 deletions(-) - -diff --git a/src/util/sss_ini.c b/src/util/sss_ini.c -index 010b77889..cf61a1722 100644 ---- a/src/util/sss_ini.c -+++ b/src/util/sss_ini.c -@@ -32,18 +32,9 @@ - #include "confdb/confdb_setup.h" - #include "confdb/confdb_private.h" - --#ifdef HAVE_LIBINI_CONFIG_V1 - #include "ini_configobj.h" --#else --#include "collection.h" --#include "collection_tools.h" --#endif -- - #include "ini_config.h" - -- --#ifdef HAVE_LIBINI_CONFIG_V1 -- - struct sss_ini_initdata { - char **error_list; - struct ref_array *ra_success_list; -@@ -59,25 +50,6 @@ struct sss_ini_initdata { - #define sss_ini_get_const_string_config_value ini_get_const_string_config_value - #define sss_ini_get_config_obj ini_get_config_valueobj - --#else -- --struct sss_ini_initdata { -- struct collection_item *error_list; -- struct collection_item *sssd_config; -- struct collection_item *obj; -- struct stat cstat; -- int file; --}; -- --#define sss_ini_get_sec_list get_section_list --#define sss_ini_get_attr_list get_attribute_list --#define sss_ini_get_const_string_config_value get_const_string_config_value --#define sss_ini_get_config_obj(secs,attrs,cfg,flag,attr) \ -- get_config_item(secs,attrs,cfg,attr) -- --#endif -- -- - /* Initialize data structure */ - - struct sss_ini_initdata* sss_ini_initdata_init(TALLOC_CTX *mem_ctx) -@@ -92,17 +64,10 @@ struct sss_ini_initdata* sss_ini_initdata_init(TALLOC_CTX *mem_ctx) - void sss_ini_close_file(struct sss_ini_initdata *init_data) - { - if (init_data == NULL) return; --#ifdef HAVE_LIBINI_CONFIG_V1 - if (init_data->file != NULL) { - ini_config_file_destroy(init_data->file); - init_data->file = NULL; - } --#else -- if (init_data->file != -1) { -- close(init_data->file); -- init_data->file = -1; -- } --#endif - } - - -@@ -112,35 +77,23 @@ void sss_ini_close_file(struct sss_ini_initdata *init_data) - int sss_ini_config_file_open(struct sss_ini_initdata *init_data, - const char *config_file) - { --#ifdef HAVE_LIBINI_CONFIG_V1 - return ini_config_file_open(config_file, - INI_META_STATS, - &init_data->file); --#else -- return check_and_open_readonly(config_file, &init_data->file, 0, 0, -- S_IFREG|S_IRUSR, /* f r**------ */ -- S_IFMT|(ALLPERMS & ~(S_IWUSR|S_IXUSR))); --#endif - } - - int sss_ini_config_file_from_mem(void *data_buf, - uint32_t data_len, - struct sss_ini_initdata *init_data) - { --#ifdef HAVE_LIBINI_CONFIG_V1 - return ini_config_file_from_mem(data_buf, strlen(data_buf), - &init_data->file); --#else -- /* FIXME: Remove support for older libini versions */ -- return EINVAL; --#endif - } - - /* Check configuration file permissions */ - - int sss_ini_config_access_check(struct sss_ini_initdata *init_data) - { --#ifdef HAVE_LIBINI_CONFIG_V1 - return ini_config_access_check(init_data->file, - INI_ACCESS_CHECK_MODE | - INI_ACCESS_CHECK_UID | -@@ -149,9 +102,6 @@ int sss_ini_config_access_check(struct sss_ini_initdata *init_data) - 0, /* owned by root */ - S_IRUSR, /* r**------ */ - ALLPERMS & ~(S_IWUSR|S_IXUSR)); --#else -- return EOK; --#endif - } - - -@@ -160,21 +110,11 @@ int sss_ini_config_access_check(struct sss_ini_initdata *init_data) - - int sss_ini_get_stat(struct sss_ini_initdata *init_data) - { --#ifdef HAVE_LIBINI_CONFIG_V1 - init_data->cstat = ini_config_get_stat(init_data->file); - - if (!init_data->cstat) return EIO; - - return EOK; --#else -- int ret; -- -- ret = fstat(init_data->file, &init_data->cstat); -- if (ret != 0) { -- return errno; -- } -- return EOK; --#endif - } - - -@@ -185,13 +125,8 @@ int sss_ini_get_mtime(struct sss_ini_initdata *init_data, - size_t timestr_len, - char *timestr) - { --#ifdef HAVE_LIBINI_CONFIG_V1 - return snprintf(timestr, timestr_len, "%llu", - (long long unsigned)init_data->cstat->st_mtime); --#else -- return snprintf(timestr, timestr_len, "%llu", -- (long long unsigned)init_data->cstat.st_mtime); --#endif - } - - -@@ -200,7 +135,6 @@ int sss_ini_get_mtime(struct sss_ini_initdata *init_data, - - static void sss_ini_config_print_errors(char **error_list) - { --#ifdef HAVE_LIBINI_CONFIG_V1 - unsigned count = 0; - - if (!error_list) { -@@ -211,9 +145,6 @@ static void sss_ini_config_print_errors(char **error_list) - DEBUG(SSSDBG_FATAL_FAILURE, "%s\n", error_list[count]); - count++; - } --#endif -- -- return; - } - - -@@ -225,7 +156,6 @@ int sss_ini_get_config(struct sss_ini_initdata *init_data, - const char *config_dir) - { - int ret; --#ifdef HAVE_LIBINI_CONFIG_V1 - #ifdef HAVE_LIBINI_CONFIG_V1_3 - const char *patterns[] = { "^[^\\.].*\\.conf$", NULL }; - const char *sections[] = { ".*", NULL }; -@@ -317,35 +247,7 @@ int sss_ini_get_config(struct sss_ini_initdata *init_data, - "Using only main configuration file due to errors in merging\n"); - } - #endif -- - return ret; -- --#else -- -- /* Read the configuration into a collection */ -- ret = config_from_fd("sssd", -- init_data->file, -- config_file, -- &init_data->sssd_config, -- INI_STOP_ON_ANY, -- &init_data->error_list); -- -- if (ret != EOK) { -- DEBUG(SSSDBG_FATAL_FAILURE, -- "Parse error reading configuration file [%s]\n", -- config_file); -- -- print_file_parsing_errors(stderr, init_data->error_list); -- -- free_ini_config_errors(init_data->error_list); -- free_ini_config(init_data->sssd_config); -- -- return ret; -- } -- -- return EOK; -- --#endif - } - - struct ref_array * -@@ -395,11 +297,7 @@ int sss_ini_check_config_obj(struct sss_ini_initdata *init_data) - int sss_ini_get_int_config_value(struct sss_ini_initdata *init_data, - int strict, int def, int *error) - { --#ifdef HAVE_LIBINI_CONFIG_V1 - return ini_get_int_config_value(init_data->obj, strict, def, error); --#else -- return get_int_config_value(init_data->obj, strict, def, error); --#endif - } - - -@@ -409,14 +307,11 @@ int sss_ini_get_int_config_value(struct sss_ini_initdata *init_data, - void sss_ini_config_destroy(struct sss_ini_initdata *init_data) - { - if (init_data == NULL) return; --#ifdef HAVE_LIBINI_CONFIG_V1 -+ - if (init_data->sssd_config != NULL) { - ini_config_destroy(init_data->sssd_config); - init_data->sssd_config = NULL; - } --#else -- free_ini_config(init_data->sssd_config); --#endif - } - - -@@ -443,11 +338,7 @@ int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx, - size_t dn_size; - size_t ldif_len; - size_t attr_len; --#ifdef HAVE_LIBINI_CONFIG_V1 - struct value_obj *obj = NULL; --#else -- struct collection_item *obj = NULL; --#endif - bool section_handled = true; - - if (only_section != NULL) { --- -2.19.1 - diff --git a/SOURCES/0090-idmap_sss-improve-man-page.patch b/SOURCES/0090-idmap_sss-improve-man-page.patch deleted file mode 100644 index 3d5d23e..0000000 --- a/SOURCES/0090-idmap_sss-improve-man-page.patch +++ /dev/null @@ -1,54 +0,0 @@ -From ea7ada6c0629df45348f699e30acc44194550801 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 10 Jan 2019 18:12:35 +0100 -Subject: [PATCH] idmap_sss: improve man page - -The misleading in the idmap_sss man page is improved. - -Related to https://pagure.io/SSSD/sssd/issue/3912 - -Reviewed-by: Jakub Hrozek ---- - src/man/idmap_sss.8.xml | 24 ++++++++++++++++++++---- - 1 file changed, 20 insertions(+), 4 deletions(-) - -diff --git a/src/man/idmap_sss.8.xml b/src/man/idmap_sss.8.xml -index b819304fb..a316c32a3 100644 ---- a/src/man/idmap_sss.8.xml -+++ b/src/man/idmap_sss.8.xml -@@ -48,12 +48,28 @@ - - - [global] --security = domain --workgroup = MAIN -+security = ads -+workgroup = <AD-DOMAIN-SHORTNAME> - --idmap config * : backend = sss --idmap config * : range = 200000-2147483647 -+idmap config <AD-DOMAIN-SHORTNAME> : backend = sss -+idmap config <AD-DOMAIN-SHORTNAME> : range = 200000-2147483647 -+ -+idmap config * : backend = tdb -+idmap config * : range = 100000-199999 - -+ -+ -+ Please replace <AD-DOMAIN-SHORTNAME> with the NetBIOS domain -+ name of the AD domain. If multiple AD domains should be used each -+ domain needs an idmap config line with -+ backend = sss and a line with a suitable -+ range. -+ -+ -+ Since Winbind requires a writeable default backend and idmap_sss is -+ read-only the example includes backend = tdb as -+ default. -+ - - - --- -2.19.1 - diff --git a/SOURCES/0091-sbus-allow-access-for-sssd-user.patch b/SOURCES/0091-sbus-allow-access-for-sssd-user.patch deleted file mode 100644 index c6e8679..0000000 --- a/SOURCES/0091-sbus-allow-access-for-sssd-user.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 4760eae9b1b3ebb94fc5590cf5ba1a268e3120be Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Wed, 31 Oct 2018 13:07:26 +0100 -Subject: [PATCH] sbus: allow access for sssd user - -D-Bus allows access for root and euid by default, however when running -in non-root mode monitor continues to run as root but responsers as sssd -user. Therefore monitor euid != sssd user and the connection is terminated. - -We must explicitly allow the connection for sssd user uid. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3871 - -Reviewed-by: Jakub Hrozek ---- - src/sbus/server/sbus_server.c | 21 +++++++++++++++++++++ - 1 file changed, 21 insertions(+) - -diff --git a/src/sbus/server/sbus_server.c b/src/sbus/server/sbus_server.c -index 576cff616..5405dae56 100644 ---- a/src/sbus/server/sbus_server.c -+++ b/src/sbus/server/sbus_server.c -@@ -400,6 +400,22 @@ sbus_server_filter_add(struct sbus_server *server, - return true; - } - -+static dbus_bool_t -+sbus_server_check_connection_uid(DBusConnection *dbus_conn, -+ unsigned long uid, -+ void *data) -+{ -+ struct sbus_server *sbus_server; -+ -+ sbus_server = talloc_get_type(data, struct sbus_server); -+ -+ if (uid == 0 || uid == sbus_server->uid) { -+ return true; -+ } -+ -+ return false; -+} -+ - static void - sbus_server_new_connection(DBusServer *dbus_server, - DBusConnection *dbus_conn, -@@ -415,6 +431,11 @@ sbus_server_new_connection(DBusServer *dbus_server, - - DEBUG(SSSDBG_FUNC_DATA, "Adding connection %p.\n", dbus_conn); - -+ /* Allow access from uid that is associated with this sbus server. */ -+ dbus_connection_set_unix_user_function(dbus_conn, -+ sbus_server_check_connection_uid, -+ sbus_server, NULL); -+ - /* First, add a message filter that will take care of routing messages - * between connections. */ - bret = sbus_server_filter_add(sbus_server, dbus_conn); --- -2.19.1 - diff --git a/SOURCES/0092-sbus-use-120-second-default-timeout.patch b/SOURCES/0092-sbus-use-120-second-default-timeout.patch deleted file mode 100644 index dd010bf..0000000 --- a/SOURCES/0092-sbus-use-120-second-default-timeout.patch +++ /dev/null @@ -1,50 +0,0 @@ -From e4469fbdb3d5c53294c6514280ac75b847b3c61c Mon Sep 17 00:00:00 2001 -From: Adam Williamson -Date: Wed, 12 Dec 2018 22:28:15 -0800 -Subject: [PATCH] sbus: use 120 second default timeout -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -As discussed in #1654537, first login to a system as a FreeIPA -domain user now usually causes an expensive SELinux operation -to happen; this can take longer than the default bus message -timeout of 25 seconds. To deal with this for now, let's use a -120 second default timeout; this is a big hammer, but unless we -can refactor things to use a longer timeout just for that one -call, or make the actual operation take less time, there's not -much else we can do. - -Resolves: -https://bugzilla.redhat.com/show_bug.cgi?id=1654537 - -Resolves: -https://pagure.io/SSSD/sssd/issue/3909 - -Signed-off-by: Adam Williamson - -Reviewed-by: Pavel Březina ---- - src/sbus/sbus_message.h | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/sbus/sbus_message.h b/src/sbus/sbus_message.h -index e7b8fe594..7ae634ece 100644 ---- a/src/sbus/sbus_message.h -+++ b/src/sbus/sbus_message.h -@@ -27,8 +27,10 @@ - #include "util/util.h" - #include "sbus/sbus_errors.h" - --/* Use reasonable default timeout which is computed in libdbus */ --#define SBUS_MESSAGE_TIMEOUT -1 -+/* Use longer default timeout than libdbus default due to expensive -+ * selinux operation: see https://bugzilla.redhat.com/show_bug.cgi?id=1654537 -+ */ -+#define SBUS_MESSAGE_TIMEOUT 120000 - - /** - * Bound message with a talloc context. --- -2.19.1 - diff --git a/SOURCES/0093-ifp-extraAttributes-is-UnknownProperty.patch b/SOURCES/0093-ifp-extraAttributes-is-UnknownProperty.patch deleted file mode 100644 index ad00b4c..0000000 --- a/SOURCES/0093-ifp-extraAttributes-is-UnknownProperty.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 814889a7f4691a135b617058c3ae876b54d5b226 Mon Sep 17 00:00:00 2001 -From: Tomas Halman -Date: Tue, 18 Dec 2018 16:31:28 +0100 -Subject: [PATCH] ifp: extraAttributes is UnknownProperty - -Attempting to get extraAttributes via SSSD's ifp fails. - -Here I uncomment interface function for extraAttributes. -also right for querying this interface is changed to allow -this request. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3906 - -Reviewed-by: Jakub Hrozek ---- - src/responder/ifp/ifp_iface/ifp_iface.c | 4 ++-- - src/responder/ifp/ifpsrv_util.c | 2 +- - src/tests/cmocka/test_ifp.c | 15 +++++++++------ - 3 files changed, 12 insertions(+), 9 deletions(-) - -diff --git a/src/responder/ifp/ifp_iface/ifp_iface.c b/src/responder/ifp/ifp_iface/ifp_iface.c -index 4464b7dd4..fa9f9ba53 100644 ---- a/src/responder/ifp/ifp_iface/ifp_iface.c -+++ b/src/responder/ifp/ifp_iface/ifp_iface.c -@@ -173,8 +173,8 @@ ifp_register_sbus_interface(struct sbus_connection *conn, - SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, uniqueID, ifp_users_user_get_unique_id, ctx), - SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, groups, ifp_users_user_get_groups, ctx), - SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, domain, ifp_users_user_get_domain, ctx), -- SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, domainname, ifp_users_user_get_domainname, ctx) --// SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, extraAttributes, ifp_users_user_get_extra_attributes, ctx) -+ SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, domainname, ifp_users_user_get_domainname, ctx), -+ SBUS_SYNC(GETTER, org_freedesktop_sssd_infopipe_Users_User, extraAttributes, ifp_users_user_get_extra_attributes, ctx) - ) - ); - -diff --git a/src/responder/ifp/ifpsrv_util.c b/src/responder/ifp/ifpsrv_util.c -index 6a625c244..ebc4c2118 100644 ---- a/src/responder/ifp/ifpsrv_util.c -+++ b/src/responder/ifp/ifpsrv_util.c -@@ -30,7 +30,7 @@ - SYSDB_GIDNUM, SYSDB_GECOS, \ - SYSDB_HOMEDIR, SYSDB_SHELL, \ - "groups", "domain", "domainname", \ -- NULL} -+ "extraAttributes", NULL} - - errno_t ifp_add_value_to_dict(DBusMessageIter *iter_dict, - const char *key, -diff --git a/src/tests/cmocka/test_ifp.c b/src/tests/cmocka/test_ifp.c -index 82ab70d75..fd754e779 100644 ---- a/src/tests/cmocka/test_ifp.c -+++ b/src/tests/cmocka/test_ifp.c -@@ -172,7 +172,8 @@ void test_attr_acl(void **state) - const char *exp_defaults[] = { SYSDB_NAME, SYSDB_UIDNUM, - SYSDB_GIDNUM, SYSDB_GECOS, - SYSDB_HOMEDIR, SYSDB_SHELL, -- "groups", "domain", "domainname", NULL }; -+ "groups", "domain", "domainname", -+ "extraAttributes", NULL }; - attr_parse_test(exp_defaults, NULL); - - /* Test adding some attributes to the defaults */ -@@ -180,7 +181,8 @@ void test_attr_acl(void **state) - SYSDB_NAME, SYSDB_UIDNUM, - SYSDB_GIDNUM, SYSDB_GECOS, - SYSDB_HOMEDIR, SYSDB_SHELL, -- "groups", "domain", "domainname", NULL }; -+ "groups", "domain", "domainname", -+ "extraAttributes", NULL }; - attr_parse_test(exp_add, "+telephoneNumber, +streetAddress"); - - /* Test removing some attributes to the defaults */ -@@ -188,7 +190,7 @@ void test_attr_acl(void **state) - SYSDB_GIDNUM, SYSDB_GECOS, - SYSDB_HOMEDIR, "groups", - "domain", "domainname", -- NULL }; -+ "extraAttributes", NULL }; - attr_parse_test(exp_rm, "-"SYSDB_SHELL ",-"SYSDB_UIDNUM); - - /* Test both add and remove */ -@@ -197,7 +199,7 @@ void test_attr_acl(void **state) - SYSDB_GIDNUM, SYSDB_GECOS, - SYSDB_HOMEDIR, "groups", - "domain", "domainname", -- NULL }; -+ "extraAttributes", NULL }; - attr_parse_test(exp_add_rm, "+telephoneNumber, -"SYSDB_SHELL); - - /* Test rm trumps add */ -@@ -205,7 +207,8 @@ void test_attr_acl(void **state) - SYSDB_GIDNUM, SYSDB_GECOS, - SYSDB_HOMEDIR, SYSDB_SHELL, - "groups", "domain", -- "domainname", NULL }; -+ "domainname", -+ "extraAttributes", NULL }; - attr_parse_test(exp_add_rm_override, - "+telephoneNumber, -telephoneNumber, +telephoneNumber"); - -@@ -214,7 +217,7 @@ void test_attr_acl(void **state) - attr_parse_test(rm_all, "-"SYSDB_NAME ", -"SYSDB_UIDNUM - ", -"SYSDB_GIDNUM ", -"SYSDB_GECOS - ", -"SYSDB_HOMEDIR ", -"SYSDB_SHELL", -groups, " -- "-domain, -domainname"); -+ "-domain, -domainname, -extraAttributes"); - - /* Malformed list */ - attr_parse_test(NULL, "missing_plus_or_minus"); --- -2.19.1 - diff --git a/SOURCES/0094-AD-IPA-Reset-subdomain-service-name-not-domain-name.patch b/SOURCES/0094-AD-IPA-Reset-subdomain-service-name-not-domain-name.patch deleted file mode 100644 index b62c72f..0000000 --- a/SOURCES/0094-AD-IPA-Reset-subdomain-service-name-not-domain-name.patch +++ /dev/null @@ -1,140 +0,0 @@ -From b3285f9f8a5eac3e4e70ed3bd6b74c15ad806e9e Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Wed, 19 Dec 2018 14:12:25 +0100 -Subject: [PATCH 94/95] AD/IPA: Reset subdomain service name, not domain name - -Related: -https://pagure.io/SSSD/sssd/issue/3911 - -Since commit 778f241e78241b0d6b8734148175f8dee804f494 the subdomain fail -over services use the "sd_" prefix. This was done to make it easier, -until the whole failover design works better with subdomains, to see -which services belong to the main domain from tools. - -However, some parts of the code would still just use the domain name for -the failover service, which meant the service was not found, notably -when trying to reset services: - -(Thu Dec 13 05:29:31 2018) [sssd[be[testrelm.test]]] [ipa_srv_ad_acct_retried] (0x0400): Subdomain re-set, will retry lookup -(Thu Dec 13 05:29:31 2018) [sssd[be[testrelm.test]]] [be_fo_reset_svc] (0x1000): Resetting all servers in service ipaad2016.test -(Thu Dec 13 05:29:31 2018) [sssd[be[testrelm.test]]] [be_fo_reset_svc] (0x0080): Cannot retrieve service [ipaad2016.test] - -This patch switches to reading the service names from the ad_options and -the sdap_service structures that are contained within ad_options. - -Reviewed-by: Tomas Halman ---- - src/providers/ad/ad_common.c | 13 +++++++++++++ - src/providers/ad/ad_common.h | 4 ++++ - src/providers/ipa/ipa_subdomains_id.c | 11 ++++++++++- - src/providers/ldap/ldap_common.c | 11 +++++++++++ - src/providers/ldap/ldap_common.h | 3 +++ - 5 files changed, 41 insertions(+), 1 deletion(-) - -diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c -index 0d154ca57..cb5912838 100644 ---- a/src/providers/ad/ad_common.c -+++ b/src/providers/ad/ad_common.c -@@ -839,6 +839,19 @@ done: - return ret; - } - -+void -+ad_failover_reset(struct be_ctx *bectx, -+ struct ad_service *adsvc) -+{ -+ if (adsvc == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "NULL service\n"); -+ return; -+ } -+ -+ sdap_service_reset_fo(bectx, adsvc->sdap); -+ sdap_service_reset_fo(bectx, adsvc->gc); -+} -+ - static void - ad_resolve_callback(void *private_data, struct fo_server *server) - { -diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h -index cb4dda750..662276cb6 100644 ---- a/src/providers/ad/ad_common.h -+++ b/src/providers/ad/ad_common.h -@@ -148,6 +148,10 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, - bool use_kdcinfo, - struct ad_service **_service); - -+void -+ad_failover_reset(struct be_ctx *bectx, -+ struct ad_service *adsvc); -+ - errno_t - ad_get_id_options(struct ad_options *ad_opts, - struct confdb_ctx *cdb, -diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c -index 48cf74460..b841f0a52 100644 ---- a/src/providers/ipa/ipa_subdomains_id.c -+++ b/src/providers/ipa/ipa_subdomains_id.c -@@ -1757,6 +1757,7 @@ fail: - static void ipa_srv_ad_acct_retried(struct tevent_req *subreq) - { - errno_t ret; -+ struct ad_id_ctx *ad_id_ctx; - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct ipa_srv_ad_acct_state *state = tevent_req_data(req, -@@ -1772,7 +1773,15 @@ static void ipa_srv_ad_acct_retried(struct tevent_req *subreq) - } - - DEBUG(SSSDBG_TRACE_FUNC, "Subdomain re-set, will retry lookup\n"); -- be_fo_reset_svc(state->be_ctx, state->obj_dom->name); -+ ad_id_ctx = ipa_get_ad_id_ctx(state->ipa_ctx, state->obj_dom); -+ if (ad_id_ctx == NULL || ad_id_ctx->ad_options == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "No AD ID ctx or no ID CTX options?\n"); -+ state->dp_error = DP_ERR_FATAL; -+ tevent_req_error(req, EINVAL); -+ return; -+ } -+ -+ ad_failover_reset(state->be_ctx, ad_id_ctx->ad_options->service); - - ret = ipa_srv_ad_acct_lookup_step(req); - if (ret != EOK) { -diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c -index 9cd8ec09c..237749aae 100644 ---- a/src/providers/ldap/ldap_common.c -+++ b/src/providers/ldap/ldap_common.c -@@ -520,6 +520,17 @@ static int ldap_user_data_cmp(void *ud1, void *ud2) - return strcasecmp((char*) ud1, (char*) ud2); - } - -+void sdap_service_reset_fo(struct be_ctx *ctx, -+ struct sdap_service *service) -+{ -+ if (service == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "NULL service\n"); -+ return; -+ } -+ -+ be_fo_reset_svc(ctx, service->name); -+} -+ - int sdap_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, - const char *service_name, const char *dns_service_name, - const char *urls, const char *backup_urls, -diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h -index 6c08d789b..89d819fb9 100644 ---- a/src/providers/ldap/ldap_common.h -+++ b/src/providers/ldap/ldap_common.h -@@ -171,6 +171,9 @@ int sdap_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, - const char *urls, const char *backup_urls, - struct sdap_service **_service); - -+void sdap_service_reset_fo(struct be_ctx *ctx, -+ struct sdap_service *service); -+ - const char *sdap_gssapi_realm(struct dp_option *opts); - - int sdap_gssapi_init(TALLOC_CTX *mem_ctx, --- -2.19.1 - diff --git a/SOURCES/0095-IPA-Add-explicit-return-after-tevent_req_error.patch b/SOURCES/0095-IPA-Add-explicit-return-after-tevent_req_error.patch deleted file mode 100644 index e749f70..0000000 --- a/SOURCES/0095-IPA-Add-explicit-return-after-tevent_req_error.patch +++ /dev/null @@ -1,37 +0,0 @@ -From aaaa9a3e836e7b7af1ff0fc5058ddddfeef120a8 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Thu, 20 Dec 2018 15:30:03 +0100 -Subject: [PATCH 95/95] IPA: Add explicit return after tevent_req_error - -When working on another patch I realized that we don't use explicit -return after failing a request. This could be potentially fatal as the -code would continue, perhaps with data that is not defined. - -Reviewed-by: Tomas Halman ---- - src/providers/ipa/ipa_subdomains_id.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c -index b841f0a52..9958d9dfe 100644 ---- a/src/providers/ipa/ipa_subdomains_id.c -+++ b/src/providers/ipa/ipa_subdomains_id.c -@@ -1770,6 +1770,7 @@ static void ipa_srv_ad_acct_retried(struct tevent_req *subreq) - "Failed to re-set subdomain [%d]: %s\n", ret, sss_strerror(ret)); - state->dp_error = DP_ERR_FATAL; - tevent_req_error(req, ret); -+ return; - } - - DEBUG(SSSDBG_TRACE_FUNC, "Subdomain re-set, will retry lookup\n"); -@@ -1789,6 +1790,7 @@ static void ipa_srv_ad_acct_retried(struct tevent_req *subreq) - "Failed to look up AD acct [%d]: %s\n", ret, sss_strerror(ret)); - state->dp_error = DP_ERR_FATAL; - tevent_req_error(req, ret); -+ return; - } - } - --- -2.19.1 - diff --git a/SOURCES/0096-KCM-Return-a-valid-tevent-error-code-if-a-request-ca.patch b/SOURCES/0096-KCM-Return-a-valid-tevent-error-code-if-a-request-ca.patch deleted file mode 100644 index 395e1a9..0000000 --- a/SOURCES/0096-KCM-Return-a-valid-tevent-error-code-if-a-request-ca.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 334950e4b352ffa3a672f30f62b478c69690c830 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Wed, 16 Jan 2019 13:06:10 +0100 -Subject: [PATCH 96/99] KCM: Return a valid tevent error code if a request - cannot be created -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Previously we were returning whatever was in 'ret' which is wrong, -typically it would have been EOK as returned from a previous successfull -call or even an uninitialized value. - -Reviewed-by: Michal Židek -Reviewed-by: Simo Sorce ---- - src/responder/kcm/kcmsrv_ops.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c -index 9352909f4..60b5677e9 100644 ---- a/src/responder/kcm/kcmsrv_ops.c -+++ b/src/responder/kcm/kcmsrv_ops.c -@@ -527,7 +527,7 @@ static void kcm_op_initialize_create_step(struct tevent_req *req) - state->op_ctx->client, - state->new_cc); - if (subreq == NULL) { -- tevent_req_error(req, ret); -+ tevent_req_error(req, ENOMEM); - return; - } - tevent_req_set_callback(subreq, kcm_op_initialize_cc_create_done, req); --- -2.19.1 - diff --git a/SOURCES/0097-KCM-Allow-representing-ccaches-with-a-NULL-principal.patch b/SOURCES/0097-KCM-Allow-representing-ccaches-with-a-NULL-principal.patch deleted file mode 100644 index 564122b..0000000 --- a/SOURCES/0097-KCM-Allow-representing-ccaches-with-a-NULL-principal.patch +++ /dev/null @@ -1,281 +0,0 @@ -From 7c441a13215dfd87f9facdaf5f6bcc19a25ec472 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Wed, 16 Jan 2019 13:02:01 +0100 -Subject: [PATCH 97/99] KCM: Allow representing ccaches with a NULL principal -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related: -https://pagure.io/SSSD/sssd/issue/3873 - -We need to make it possible to create an internal ccache representation -without passing in a principal. The principal is only assigned to the -ccache with krb5_cc_initialize(), but some programs like openssh use the -following sequence of calls: - krb5_cc_new_unique - krb5_cc_switch - krb5_cc_initialize - -Reviewed-by: Michal Židek -Reviewed-by: Simo Sorce ---- - src/responder/kcm/kcmsrv_ccache.c | 18 +++-- - src/responder/kcm/kcmsrv_ccache_json.c | 79 ++++++++++++++++--- - src/tests/cmocka/test_kcm_json_marshalling.c | 83 ++++++++++++++++++-- - 3 files changed, 153 insertions(+), 27 deletions(-) - -diff --git a/src/responder/kcm/kcmsrv_ccache.c b/src/responder/kcm/kcmsrv_ccache.c -index af2bcf8bb..e7800662a 100644 ---- a/src/responder/kcm/kcmsrv_ccache.c -+++ b/src/responder/kcm/kcmsrv_ccache.c -@@ -68,14 +68,16 @@ errno_t kcm_cc_new(TALLOC_CTX *mem_ctx, - - uuid_generate(cc->uuid); - -- kret = krb5_copy_principal(k5c, princ, &cc->client); -- if (kret != 0) { -- const char *err_msg = sss_krb5_get_error_message(k5c, kret); -- DEBUG(SSSDBG_OP_FAILURE, -- "krb5_copy_principal failed: [%d][%s]\n", kret, err_msg); -- sss_krb5_free_error_message(k5c, err_msg); -- ret = ERR_INTERNAL; -- goto done; -+ if (princ) { -+ kret = krb5_copy_principal(k5c, princ, &cc->client); -+ if (kret != 0) { -+ const char *err_msg = sss_krb5_get_error_message(k5c, kret); -+ DEBUG(SSSDBG_OP_FAILURE, -+ "krb5_copy_principal failed: [%d][%s]\n", kret, err_msg); -+ sss_krb5_free_error_message(k5c, err_msg); -+ ret = ERR_INTERNAL; -+ goto done; -+ } - } - - cc->owner.uid = cli_creds_get_uid(owner); -diff --git a/src/responder/kcm/kcmsrv_ccache_json.c b/src/responder/kcm/kcmsrv_ccache_json.c -index 6341530ee..72e24c430 100644 ---- a/src/responder/kcm/kcmsrv_ccache_json.c -+++ b/src/responder/kcm/kcmsrv_ccache_json.c -@@ -229,6 +229,20 @@ static json_t *princ_to_json(TALLOC_CTX *mem_ctx, - json_error_t error; - char *str_realm_data; - -+ if (princ == NULL) { -+ jprinc = json_pack_ex(&error, -+ JSON_STRICT, -+ "{}"); -+ if (jprinc == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to pack JSON princ structure on line %d: %s\n", -+ error.line, error.text); -+ return NULL; -+ } -+ -+ return jprinc; -+ } -+ - components = princ_data_to_json(mem_ctx, princ); - if (components == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, -@@ -587,13 +601,12 @@ static errno_t json_array_to_krb5_data(TALLOC_CTX *mem_ctx, - return EOK; - } - --static errno_t json_to_princ(TALLOC_CTX *mem_ctx, -- json_t *js_princ, -- krb5_principal *_princ) -+static errno_t json_to_nonempty_princ(TALLOC_CTX *mem_ctx, -+ json_t *js_princ, -+ krb5_principal *_princ) - { - errno_t ret; - json_t *components = NULL; -- int ok; - krb5_principal princ = NULL; - TALLOC_CTX *tmp_ctx = NULL; - char *realm_str; -@@ -601,13 +614,6 @@ static errno_t json_to_princ(TALLOC_CTX *mem_ctx, - size_t comp_count; - json_error_t error; - -- ok = json_is_object(js_princ); -- if (!ok) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Json principal is not an object.\n"); -- ret = ERR_JSON_DECODING; -- goto done; -- } -- - tmp_ctx = talloc_new(mem_ctx); - if (tmp_ctx == NULL) { - ret = ENOMEM; -@@ -684,6 +690,57 @@ done: - return ret; - } - -+static bool is_nonempty_principal(json_t *js_princ) -+{ -+ errno_t ret; -+ json_error_t error; -+ -+ ret = json_unpack_ex(js_princ, -+ &error, -+ JSON_VALIDATE_ONLY, -+ "{s:i, s:s, s:o}", -+ "type", -+ "realm", -+ "components"); -+ -+ return ret == 0 ? true : false; -+} -+ -+static bool is_empty_principal(json_t *js_princ) -+{ -+ errno_t ret; -+ json_error_t error; -+ -+ ret = json_unpack_ex(js_princ, -+ &error, -+ JSON_VALIDATE_ONLY, -+ "{}"); -+ -+ return ret == 0 ? true : false; -+} -+ -+static errno_t json_to_princ(TALLOC_CTX *mem_ctx, -+ json_t *js_princ, -+ krb5_principal *_princ) -+{ -+ int ok; -+ -+ ok = json_is_object(js_princ); -+ if (!ok) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Json principal is not an object.\n"); -+ return ERR_JSON_DECODING; -+ } -+ -+ if (is_nonempty_principal(js_princ)) { -+ return json_to_nonempty_princ(mem_ctx, js_princ, _princ); -+ } else if (is_empty_principal(js_princ)) { -+ *_princ = NULL; -+ return EOK; -+ } -+ -+ return ERR_JSON_DECODING; -+} -+ - static errno_t json_elem_to_cred(TALLOC_CTX *mem_ctx, - json_t *element, - struct kcm_cred **_crd) -diff --git a/src/tests/cmocka/test_kcm_json_marshalling.c b/src/tests/cmocka/test_kcm_json_marshalling.c -index 05d472499..48ee92bd6 100644 ---- a/src/tests/cmocka/test_kcm_json_marshalling.c -+++ b/src/tests/cmocka/test_kcm_json_marshalling.c -@@ -116,14 +116,22 @@ static void assert_cc_princ_equal(struct kcm_ccache *cc1, - p1 = kcm_cc_get_client_principal(cc1); - p2 = kcm_cc_get_client_principal(cc2); - -- kerr = krb5_unparse_name(NULL, p1, &name1); -- assert_int_equal(kerr, 0); -- kerr = krb5_unparse_name(NULL, p2, &name2); -- assert_int_equal(kerr, 0); -- -- assert_string_equal(name1, name2); -- krb5_free_unparsed_name(NULL, name1); -- krb5_free_unparsed_name(NULL, name2); -+ if (p1 != NULL && p2 != NULL) { -+ kerr = krb5_unparse_name(NULL, p1, &name1); -+ assert_int_equal(kerr, 0); -+ kerr = krb5_unparse_name(NULL, p2, &name2); -+ assert_int_equal(kerr, 0); -+ -+ assert_string_equal(name1, name2); -+ krb5_free_unparsed_name(NULL, name1); -+ krb5_free_unparsed_name(NULL, name2); -+ } else { -+ /* Either both principals must be NULL or both -+ * non-NULL and represent the same principals -+ */ -+ assert_null(p1); -+ assert_null(p2); -+ } - } - - static void assert_cc_offset_equal(struct kcm_ccache *cc1, -@@ -206,6 +214,62 @@ static void test_kcm_ccache_marshall_unmarshall(void **state) - assert_int_equal(ret, EINVAL); - } - -+static void test_kcm_ccache_no_princ(void **state) -+{ -+ struct kcm_marshalling_test_ctx *test_ctx = talloc_get_type(*state, -+ struct kcm_marshalling_test_ctx); -+ errno_t ret; -+ struct cli_creds owner; -+ const char *name; -+ struct kcm_ccache *cc; -+ krb5_principal princ; -+ struct kcm_ccache *cc2; -+ struct sss_iobuf *payload; -+ const char *key; -+ uint8_t *data; -+ uuid_t uuid; -+ -+ owner.ucred.uid = getuid(); -+ owner.ucred.gid = getuid(); -+ -+ name = talloc_asprintf(test_ctx, "%"SPRIuid, getuid()); -+ assert_non_null(name); -+ -+ ret = kcm_cc_new(test_ctx, -+ test_ctx->kctx, -+ &owner, -+ name, -+ NULL, -+ &cc); -+ assert_int_equal(ret, EOK); -+ -+ princ = kcm_cc_get_client_principal(cc); -+ assert_null(princ); -+ -+ ret = kcm_ccache_to_sec_input(test_ctx, -+ cc, -+ &owner, -+ &payload); -+ assert_int_equal(ret, EOK); -+ -+ data = sss_iobuf_get_data(payload); -+ assert_non_null(data); -+ -+ ret = kcm_cc_get_uuid(cc, uuid); -+ assert_int_equal(ret, EOK); -+ key = sec_key_create(test_ctx, name, uuid); -+ assert_non_null(key); -+ -+ ret = sec_kv_to_ccache(test_ctx, -+ key, -+ (const char *) data, -+ &owner, -+ &cc2); -+ assert_int_equal(ret, EOK); -+ -+ assert_cc_equal(cc, cc2); -+} -+ - void test_sec_key_get_uuid(void **state) - { - errno_t ret; -@@ -279,6 +343,9 @@ int main(int argc, const char *argv[]) - cmocka_unit_test_setup_teardown(test_kcm_ccache_marshall_unmarshall, - setup_kcm_marshalling, - teardown_kcm_marshalling), -+ cmocka_unit_test_setup_teardown(test_kcm_ccache_no_princ, -+ setup_kcm_marshalling, -+ teardown_kcm_marshalling), - cmocka_unit_test(test_sec_key_get_uuid), - cmocka_unit_test(test_sec_key_get_name), - cmocka_unit_test(test_sec_key_match_name), --- -2.19.1 - diff --git a/SOURCES/0098-KCM-Create-an-empty-ccache-on-switch-to-a-non-existi.patch b/SOURCES/0098-KCM-Create-an-empty-ccache-on-switch-to-a-non-existi.patch deleted file mode 100644 index c98c83c..0000000 --- a/SOURCES/0098-KCM-Create-an-empty-ccache-on-switch-to-a-non-existi.patch +++ /dev/null @@ -1,244 +0,0 @@ -From d0eae0598cfb37e1e5aca10a0827b912f707d783 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Wed, 16 Jan 2019 13:06:15 +0100 -Subject: [PATCH 98/99] KCM: Create an empty ccache on switch to a non-existing - one -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related: -https://pagure.io/SSSD/sssd/issue/3873 - -We need to make it possible to create an internal ccache representation -without passing in a principal. The principal is only assigned to the -ccache with krb5_cc_initialize(), but some programs like openssh use the -following sequence of calls: - cc = krb5_cc_new_unique - krb5_cc_switch(cc) - krb5_cc_initialize(cc, principal) - -Since switch changes the default ccache, we create a 'dummy' ccache with -krb5_cc_switch() and then the initialize call just fills in the details. - -Reviewed-by: Simo Sorce -Reviewed-by: Michal Židek ---- - src/responder/kcm/kcmsrv_ops.c | 133 +++++++++++++++++++++++++++++---- - 1 file changed, 118 insertions(+), 15 deletions(-) - -diff --git a/src/responder/kcm/kcmsrv_ops.c b/src/responder/kcm/kcmsrv_ops.c -index 60b5677e9..6544c4ed0 100644 ---- a/src/responder/kcm/kcmsrv_ops.c -+++ b/src/responder/kcm/kcmsrv_ops.c -@@ -1601,8 +1601,21 @@ static errno_t kcm_op_get_default_ccache_recv(struct tevent_req *req, - - /* (name) -> () */ - static void kcm_op_set_default_ccache_getbyname_done(struct tevent_req *subreq); -+static void kcm_op_set_default_create_step(struct tevent_req *req); -+static void kcm_op_set_default_create_step_done(struct tevent_req *subreq); -+static void kcm_op_set_default_step(struct tevent_req *req); - static void kcm_op_set_default_done(struct tevent_req *subreq); - -+struct kcm_op_set_default_ccache_state { -+ uint32_t op_ret; -+ struct kcm_op_ctx *op_ctx; -+ struct tevent_context *ev; -+ -+ const char *name; -+ uuid_t dfl_uuid; -+ struct kcm_ccache *new_cc; -+}; -+ - static struct tevent_req * - kcm_op_set_default_ccache_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, -@@ -1610,30 +1623,31 @@ kcm_op_set_default_ccache_send(TALLOC_CTX *mem_ctx, - { - struct tevent_req *req = NULL; - struct tevent_req *subreq = NULL; -- struct kcm_op_common_state *state = NULL; -+ struct kcm_op_set_default_ccache_state *state = NULL; - errno_t ret; -- const char *name; - -- req = tevent_req_create(mem_ctx, &state, struct kcm_op_common_state); -+ req = tevent_req_create(mem_ctx, -+ &state, -+ struct kcm_op_set_default_ccache_state); - if (req == NULL) { - return NULL; - } - state->op_ctx = op_ctx; - state->ev = ev; - -- ret = sss_iobuf_read_stringz(op_ctx->input, &name); -+ ret = sss_iobuf_read_stringz(op_ctx->input, &state->name); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Cannot read input name [%d]: %s\n", - ret, sss_strerror(ret)); - goto immediate; - } -- DEBUG(SSSDBG_TRACE_LIBS, "Setting default ccache %s\n", name); -+ DEBUG(SSSDBG_TRACE_LIBS, "Setting default ccache %s\n", state->name); - - subreq = kcm_ccdb_uuid_by_name_send(state, ev, - op_ctx->kcm_data->db, - op_ctx->client, -- name); -+ state->name); - if (subreq == NULL) { - ret = ENOMEM; - goto immediate; -@@ -1652,13 +1666,16 @@ static void kcm_op_set_default_ccache_getbyname_done(struct tevent_req *subreq) - errno_t ret; - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); -- struct kcm_op_common_state *state = tevent_req_data(req, -- struct kcm_op_common_state); -- uuid_t dfl_uuid; -+ struct kcm_op_set_default_ccache_state *state = tevent_req_data(req, -+ struct kcm_op_set_default_ccache_state); - -- ret = kcm_ccdb_uuid_by_name_recv(subreq, state, dfl_uuid); -+ ret = kcm_ccdb_uuid_by_name_recv(subreq, state, state->dfl_uuid); - talloc_zfree(subreq); -- if (ret != EOK) { -+ if (ret == ERR_NO_CREDS) { -+ DEBUG(SSSDBG_TRACE_LIBS, -+ "The ccache does not exist, creating a new one\n"); -+ kcm_op_set_default_create_step(req); -+ } else if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, - "Cannot get ccache by name [%d]: %s\n", - ret, sss_strerror(ret)); -@@ -1666,11 +1683,91 @@ static void kcm_op_set_default_ccache_getbyname_done(struct tevent_req *subreq) - return; - } - -+ kcm_op_set_default_step(req); -+} -+ -+static void kcm_op_set_default_create_step(struct tevent_req *req) -+{ -+ errno_t ret; -+ struct tevent_req *subreq; -+ struct kcm_op_set_default_ccache_state *state = tevent_req_data(req, -+ struct kcm_op_set_default_ccache_state); -+ -+ /* Only allow to create ccaches for 'self' */ -+ ret = kcm_check_name(state->name, state->op_ctx->client); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Name %s is malformed [%d]: %s\n", -+ state->name, ret, sss_strerror(ret)); -+ tevent_req_error(req, ret); -+ return; -+ } -+ -+ ret = kcm_cc_new(state->op_ctx, -+ state->op_ctx->kcm_data->k5c, -+ state->op_ctx->client, -+ state->name, -+ NULL, -+ &state->new_cc); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Cannot create new ccache %d: %s\n", ret, sss_strerror(ret)); -+ tevent_req_error(req, ret); -+ return; -+ } -+ -+ subreq = kcm_ccdb_create_cc_send(state, -+ state->ev, -+ state->op_ctx->kcm_data->db, -+ state->op_ctx->client, -+ state->new_cc); -+ if (subreq == NULL) { -+ tevent_req_error(req, ENOMEM); -+ return; -+ } -+ tevent_req_set_callback(subreq, kcm_op_set_default_create_step_done, req); -+} -+ -+static void kcm_op_set_default_create_step_done(struct tevent_req *subreq) -+{ -+ errno_t ret; -+ struct tevent_req *req = tevent_req_callback_data(subreq, -+ struct tevent_req); -+ struct kcm_op_set_default_ccache_state *state = tevent_req_data(req, -+ struct kcm_op_set_default_ccache_state); -+ -+ ret = kcm_ccdb_create_cc_recv(subreq); -+ talloc_zfree(subreq); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Cannot add ccache to db %d: %s\n", ret, sss_strerror(ret)); -+ tevent_req_error(req, ret); -+ return; -+ } -+ -+ ret = kcm_cc_get_uuid(state->new_cc, state->dfl_uuid); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Cannot get new ccache UUID [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ tevent_req_error(req, ret); -+ return; -+ } -+ -+ kcm_op_set_default_step(req); -+} -+ -+static void kcm_op_set_default_step(struct tevent_req *req) -+{ -+ struct kcm_op_set_default_ccache_state *state = tevent_req_data(req, -+ struct kcm_op_set_default_ccache_state); -+ struct tevent_req *subreq; -+ - subreq = kcm_ccdb_set_default_send(state, - state->ev, - state->op_ctx->kcm_data->db, - state->op_ctx->client, -- dfl_uuid); -+ state->dfl_uuid); - if (subreq == NULL) { - tevent_req_error(req, ENOMEM); - return; -@@ -1684,8 +1781,8 @@ static void kcm_op_set_default_done(struct tevent_req *subreq) - errno_t ret; - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); -- struct kcm_op_common_state *state = tevent_req_data(req, -- struct kcm_op_common_state); -+ struct kcm_op_set_default_ccache_state *state = tevent_req_data(req, -+ struct kcm_op_set_default_ccache_state); - - ret = kcm_ccdb_set_default_recv(subreq); - talloc_zfree(subreq); -@@ -1700,6 +1797,12 @@ static void kcm_op_set_default_done(struct tevent_req *subreq) - tevent_req_done(req); - } - -+static errno_t kcm_op_set_default_ccache_recv(struct tevent_req *req, -+ uint32_t *_op_ret) -+{ -+ KCM_OP_RET_FROM_TYPE(req, struct kcm_op_set_default_ccache_state, _op_ret); -+} -+ - /* (name) -> (offset) */ - static void kcm_op_get_kdc_offset_getbyname_done(struct tevent_req *subreq); - -@@ -1948,7 +2051,7 @@ static struct kcm_op kcm_optable[] = { - { "GET_CACHE_UUID_LIST", kcm_op_get_cache_uuid_list_send, NULL }, - { "GET_CACHE_BY_UUID", kcm_op_get_cache_by_uuid_send, NULL }, - { "GET_DEFAULT_CACHE", kcm_op_get_default_ccache_send, kcm_op_get_default_ccache_recv }, -- { "SET_DEFAULT_CACHE", kcm_op_set_default_ccache_send, NULL }, -+ { "SET_DEFAULT_CACHE", kcm_op_set_default_ccache_send, kcm_op_set_default_ccache_recv }, - { "GET_KDC_OFFSET", kcm_op_get_kdc_offset_send, NULL }, - { "SET_KDC_OFFSET", kcm_op_set_kdc_offset_send, kcm_op_set_kdc_offset_recv }, - { "ADD_NTLM_CRED", NULL, NULL }, --- -2.19.1 - diff --git a/SOURCES/0099-PAM-use-user-name-hint-if-any-domain-has-set-it.patch b/SOURCES/0099-PAM-use-user-name-hint-if-any-domain-has-set-it.patch deleted file mode 100644 index 7c7551c..0000000 --- a/SOURCES/0099-PAM-use-user-name-hint-if-any-domain-has-set-it.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 3eb99a171f59454fc2ec130b3e5052b3de5569a2 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 7 Feb 2019 16:48:44 +0100 -Subject: [PATCH] PAM: use user name hint if any domain has set it - -When using multiple domains the user name hint should be shown even if -only one domain has set the flag to have a consistent user experience. -Currently this would only be related to logins with GDM and activated -GDM Smartcard plugin. - -Related to https://pagure.io/SSSD/sssd/issue/3949 - -Reviewed-by: Jakub Hrozek ---- - src/responder/pam/pamsrv_cmd.c | 22 ++++++++++++++++++---- - 1 file changed, 18 insertions(+), 4 deletions(-) - -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index 553bf8fbb..3b4869ece 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -1578,6 +1578,20 @@ done: - return ret; - } - -+/* Return true if hint is set for at least one domain */ -+static bool get_user_name_hint(struct sss_domain_info *domains) -+{ -+ struct sss_domain_info *d; -+ -+ DLIST_FOR_EACH(d, domains) { -+ if (d->user_name_hint == true) { -+ return true; -+ } -+ } -+ -+ return false; -+} -+ - static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - { - int ret; -@@ -1646,9 +1660,9 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - preq->current_cert = sss_cai_get_next(preq->current_cert)) { - - ret = add_pam_cert_response(preq->pd, -- preq->cctx->rctx->domains, "", -- preq->current_cert, -- preq->cctx->rctx->domains->user_name_hint -+ preq->cctx->rctx->domains, "", -+ preq->current_cert, -+ get_user_name_hint(preq->cctx->rctx->domains) - ? SSS_PAM_CERT_INFO_WITH_HINT - : SSS_PAM_CERT_INFO); - if (ret != EOK) { -@@ -1698,7 +1712,7 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - } - } - -- if (preq->cctx->rctx->domains->user_name_hint -+ if (get_user_name_hint(preq->cctx->rctx->domains) - && preq->pd->cmd == SSS_PAM_PREAUTH) { - ret = add_pam_cert_response(preq->pd, - preq->cctx->rctx->domains, cert_user, --- -2.19.2 - diff --git a/SOURCES/0100-pam_sss-PAM_USER_UNKNOWN-if-socket-is-missing.patch b/SOURCES/0100-pam_sss-PAM_USER_UNKNOWN-if-socket-is-missing.patch deleted file mode 100644 index ece50bc..0000000 --- a/SOURCES/0100-pam_sss-PAM_USER_UNKNOWN-if-socket-is-missing.patch +++ /dev/null @@ -1,139 +0,0 @@ -From 0479c6f1598602909487c499266fe410085251a5 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 25 Mar 2019 10:17:17 +0100 -Subject: [PATCH] pam_sss: PAM_USER_UNKNOWN if socket is missing - -If SSSD used without explicit configuration in the files-only mode and -pam_sss is also used in the PAM configuration, as e.g. in recent Fedora -systems, users handled by other NSS modules might get an 'Access Denied' -when trying to log in. - -The culprit is the line like - - account [default=bad success=ok user_unknown=ignore] pam_sss.so - -in the PAM configuration which can only grant access if pam_sss.so -returns PAM_SUCCESS or PAM_USER_UNKNOWN. Even PAM_IGNORE causes a -rejection because of 'default=bad'. - -Of the PAM responder is running PAM_USER_UNKNOWN is returned for users -from other NSS modules. With this patch PAM_USER_UNKNOWN is returned as -well during the 'account' step if the PAM responder socket is not -available. - -Related to https://pagure.io/SSSD/sssd/issue/3988 - -Reviewed-by: Jakub Hrozek ---- - src/man/pam_sss.8.xml | 4 ++++ - src/sss_client/common.c | 18 ++++++++++++++++++ - src/sss_client/pam_sss.c | 16 +++++++++++++--- - src/sss_client/sss_cli.h | 2 ++ - 4 files changed, 37 insertions(+), 3 deletions(-) - -diff --git a/src/man/pam_sss.8.xml b/src/man/pam_sss.8.xml -index 86ed0fefe..834d9d268 100644 ---- a/src/man/pam_sss.8.xml -+++ b/src/man/pam_sss.8.xml -@@ -256,6 +256,10 @@ auth sufficient pam_sss.so allow_missing_name - All module types (, , - and ) are provided. - -+ If SSSD's PAM responder is not running, e.g. if the PAM responder -+ socket is not available, pam_sss will return PAM_USER_UNKNOWN when -+ called as module to avoid issues with users -+ from other sources during access control. - - - -diff --git a/src/sss_client/common.c b/src/sss_client/common.c -index 224f33b55..e2d840540 100644 ---- a/src/sss_client/common.c -+++ b/src/sss_client/common.c -@@ -913,8 +913,14 @@ int sss_pam_make_request(enum sss_cli_command cmd, - /* only root shall use the privileged pipe */ - if (getuid() == 0 && getgid() == 0) { - socket_name = SSS_PAM_PRIV_SOCKET_NAME; -+ errno = 0; - statret = stat(socket_name, &stat_buf); - if (statret != 0) { -+ if (errno == ENOENT) { -+ *errnop = ESSS_NO_SOCKET; -+ } else { -+ *errnop = ESSS_SOCKET_STAT_ERROR; -+ } - ret = PAM_SERVICE_ERR; - goto out; - } -@@ -928,8 +934,14 @@ int sss_pam_make_request(enum sss_cli_command cmd, - } - } else { - socket_name = SSS_PAM_SOCKET_NAME; -+ errno = 0; - statret = stat(socket_name, &stat_buf); - if (statret != 0) { -+ if (errno == ENOENT) { -+ *errnop = ESSS_NO_SOCKET; -+ } else { -+ *errnop = ESSS_SOCKET_STAT_ERROR; -+ } - ret = PAM_SERVICE_ERR; - goto out; - } -@@ -1075,6 +1087,12 @@ const char *ssscli_err2string(int err) - case ESSS_SERVER_NOT_TRUSTED: - return _("SSSD is not run by root."); - break; -+ case ESSS_NO_SOCKET: -+ return _("SSSD socket does not exist."); -+ break; -+ case ESSS_SOCKET_STAT_ERROR: -+ return _("Cannot get stat of SSSD socket."); -+ break; - default: - m = strerror(err); - if (m == NULL) { -diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c -index 69dc50dfd..9d51aefc6 100644 ---- a/src/sss_client/pam_sss.c -+++ b/src/sss_client/pam_sss.c -@@ -1304,10 +1304,20 @@ static int send_and_receive(pam_handle_t *pamh, struct pam_items *pi, - } - - if (ret != PAM_SUCCESS) { -- if (errnop != 0) { -- logger(pamh, LOG_ERR, "Request to sssd failed. %s", ssscli_err2string(errnop)); -+ /* If there is no PAM responder socket during the access control step -+ * we assume this is on purpose, i.e. PAM responder is not configured. -+ * PAM_USER_UNKNOWN is returned to the PAM stack to avoid unexpected -+ * denials. */ -+ if (errnop == ESSS_NO_SOCKET && task == SSS_PAM_ACCT_MGMT) { -+ pam_status = PAM_USER_UNKNOWN; -+ } else { -+ if (errnop != 0 && errnop != ESSS_NO_SOCKET) { -+ logger(pamh, LOG_ERR, "Request to sssd failed. %s", -+ ssscli_err2string(errnop)); -+ } -+ -+ pam_status = PAM_AUTHINFO_UNAVAIL; - } -- pam_status = PAM_AUTHINFO_UNAVAIL; - goto done; - } - -diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h -index af8a43916..31b4e50f7 100644 ---- a/src/sss_client/sss_cli.h -+++ b/src/sss_client/sss_cli.h -@@ -584,6 +584,8 @@ enum sss_cli_error_codes { - ESSS_BAD_PUB_SOCKET, - ESSS_BAD_CRED_MSG, - ESSS_SERVER_NOT_TRUSTED, -+ ESSS_NO_SOCKET, -+ ESSS_SOCKET_STAT_ERROR, - - ESS_SSS_CLI_ERROR_MAX - }; --- -2.19.1 - diff --git a/SOURCES/0101-ipa-ipa_getkeytab-don-t-call-libnss_sss.patch b/SOURCES/0101-ipa-ipa_getkeytab-don-t-call-libnss_sss.patch deleted file mode 100644 index 31be7f1..0000000 --- a/SOURCES/0101-ipa-ipa_getkeytab-don-t-call-libnss_sss.patch +++ /dev/null @@ -1,44 +0,0 @@ -From b927dc7c8d5d4f467749958d3e6330ff70fc3ea2 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 1 Apr 2019 17:27:45 +0200 -Subject: [PATCH] ipa: ipa_getkeytab don't call libnss_sss - -Resolves: https://pagure.io/SSSD/sssd/issue/3992 - -ipa-getkeytab is a help process which might even get called during -the startup of SSSD. Hence it should not try to use any SSSD responder -especially not the NSS responder. - -Typically we call helpers with the environment of the calling SSSD -component where then _SSS_LOOPS environment variable is set to 'NO' to -skip calls to SSSD in libnss_sss. Since we have to set the KRB5CCNAME -environment variable to the ccache with the current TGT for the host -principal when calling ipa-getkeytab execle() is used to call -ipa_getkeytab which unfortunately replaces the environment of the caller -with the one provided in the last argument of the call. To make sure -ipa_getkeytab does not call back into SSSD we have to set _SSS_LOOPS=NO -here as well. - -Reviewed-by: Alexander Bokovoy -Reviewed-by: Alexey Tikhonov -(cherry picked from commit d409c10d00101734d1af0c9e0256e607ee8b09c7) ---- - src/providers/ipa/ipa_subdomains_server.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c -index dd0933642..1d480e52b 100644 ---- a/src/providers/ipa/ipa_subdomains_server.c -+++ b/src/providers/ipa/ipa_subdomains_server.c -@@ -481,7 +481,7 @@ static void ipa_getkeytab_exec(const char *ccache, - { - errno_t ret; - int debug_fd; -- const char *gkt_env[2] = { NULL, NULL }; -+ const char *gkt_env[3] = { NULL, "_SSS_LOOPS=NO", NULL }; - - if (debug_level >= SSSDBG_TRACE_LIBS) { - debug_fd = get_fd_from_debug_file(); --- -2.19.1 - diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec index 4e50f5d..6903ad2 100644 --- a/SPECS/sssd.spec +++ b/SPECS/sssd.spec @@ -23,8 +23,8 @@ %endif Name: sssd -Version: 2.0.0 -Release: 43%{?dist}.3 +Version: 2.2.0 +Release: 19%{?dist} Group: Applications/System Summary: System Security Services Daemon License: GPLv3+ @@ -32,107 +32,61 @@ URL: https://pagure.io/SSSD/sssd/ Source0: https://releases.pagure.org/SSSD/sssd/%{name}-%{version}.tar.gz ### Patches ### -Patch0001: 0001-KCM-Don-t-error-out-if-creating-a-new-ID-as-the-firs.patch -Patch0002: 0002-sbus-register-filter-on-new-connection.patch -Patch0003: 0003-sysdb-extract-sysdb_ldb_msg_attr_to_certmap_info-cal.patch -Patch0004: 0004-sysdb_ldb_msg_attr_to_certmap_info-set-SSS_CERTMAP_M.patch -Patch0005: 0005-sysdb-add-attr_map-attribute-to-sysdb_ldb_msg_attr_t.patch -Patch0006: 0006-confdb-add-confdb_certmap_to_sysdb.patch -Patch0007: 0007-AD-LDAP-read-certificate-mapping-rules-from-config-f.patch -Patch0008: 0008-sysdb-sysdb_certmap_add-handle-domains-more-flexible.patch -Patch0009: 0009-confdb-add-special-handling-for-rules-for-the-files-.patch -Patch0010: 0010-files-add-support-for-Smartcard-authentication.patch -Patch0011: 0011-responder-make-sure-SSS_DP_CERT-is-passed-to-files-p.patch -Patch0012: 0012-PAM-add-certificate-matching-rules-from-all-domains.patch -Patch0013: 0013-doc-add-certificate-mapping-section-to-man-page.patch -Patch0014: 0014-intg-user-default-locale.patch -Patch0015: 0015-PAM-use-better-PAM-error-code-for-failed-Smartcard-a.patch -Patch0016: 0016-test_ca-test-library-only-for-readable.patch -Patch0017: 0017-test_ca-set-a-password-PIN-to-nss-databases.patch -Patch0018: 0018-getsockopt_wrapper-add-support-for-PAM-clients.patch -Patch0019: 0019-intg-add-Smartcard-authentication-tests.patch -Patch0020: 0020-sbus-dectect-python-binary-for-sbus_generate.sh.patch -Patch0021: 0021-CONFDB-Skip-local-domain-if-not-supported.patch -Patch0022: 0022-SELINUX-Always-add-SELinux-user-to-the-semanage-data.patch -Patch0023: 0023-proxy-access-provider-directly-not-through-be_ctx.patch -Patch0024: 0024-dp-set-be_ctx-provider-as-part-of-dp_init-request.patch -Patch0025: 0025-sbus-read-destination-after-sender-is-set.patch -Patch0026: 0026-sbus-do-not-try-to-remove-signal-listeners-when-disc.patch -Patch0027: 0027-sbus-free-watch_fd-fdevent-explicitly.patch -Patch0028: 0028-doc-remove-local-provider-reference-from-manpages.patch -Patch0029: 0029-confdb-log-an-error-when-domain-is-misconfigured.patch -Patch0030: 0030-be-use-be_is_offline-for-the-main-domain-when-asking.patch -Patch0031: 0031-sudo-respect-case-sensitivity-in-sudo-responder.patch -Patch0032: 0032-sbus-fix-typo.patch -Patch0033: 0033-sbus-check-for-null-message-in-sbus_message_bound.patch -Patch0034: 0034-sbus-replace-sbus_message_bound_ref-with-sbus_messag.patch -Patch0035: 0035-sbus-add-unit-tests-for-public-sbus_message-module.patch -Patch0036: 0036-p11-handle-multiple-certs-during-auth-with-OpenSSL.patch -Patch0037: 0037-p11_child-add-wait_for_card-option.patch -Patch0038: 0038-PAM-add-p11_wait_for_card_timeout-option.patch -Patch0039: 0039-pam_sss-make-flags-public.patch -Patch0040: 0040-pam_sss-add-try_cert_auth-option.patch -Patch0041: 0041-pam_sss-add-option-require_cert_auth.patch -Patch0042: 0042-intg-require-SC-tests.patch -Patch0043: 0043-p11_child-show-PKCS-11-URI-in-debug-output.patch -Patch0044: 0044-p11_child-add-PKCS-11-uri-to-restrict-selection.patch -Patch0045: 0045-PAM-add-p11_uri-option.patch -Patch0046: 0046-tests-add-PKCS-11-URI-tests.patch -Patch0047: 0047-PAM-return-short-name-for-files-provider-users.patch -Patch0048: 0048-doc-Add-nsswitch.conf-note-to-manpage.patch -Patch0049: 0049-intg-flush-the-SSSD-caches-to-sync-with-files.patch -Patch0050: 0050-FILES-The-files-provider-should-not-enumerate.patch -Patch0051: 0051-p11_child-add-OCSP-check-ot-the-OpenSSL-version.patch -Patch0052: 0052-p11_child-add-crl_file-option-for-the-OpenSSL-build.patch -Patch0053: 0053-p11-Fix-two-instances-of-Wmaybe-uninitialized-in-p11.patch -Patch0054: 0054-sudo-use-correct-sbus-interface.patch -Patch0055: 0055-sudo-fix-error-handling-in-sudosrv_refresh_rules_don.patch -Patch0056: 0056-files-add-session-recording-flag.patch -Patch0057: 0057-UTIL-Suppress-Coverity-warning.patch -Patch0058: 0058-PYSSS-Re-add-the-pysss.getgrouplist-interface.patch -Patch0059: 0059-ifp-fix-typo-causing-a-crash-in-FindByNameAndCertifi.patch -Patch0060: 0060-IFP-Use-subreq-not-req-when-calling-RefreshRules_rec.patch -Patch0061: 0061-INI-Return-errno-not-1-on-failure-from-sss_ini_get_s.patch -Patch0062: 0062-MONITOR-Don-t-check-for-pidfile-if-SSSD-is-already-r.patch -Patch0063: 0063-SSSD-Allow-refreshing-only-certain-section-with-genc.patch -Patch0064: 0064-SYSTEMD-Re-read-KCM-configuration-on-systemctl-resta.patch -Patch0065: 0065-pam_sss-return-PAM_AUTHINFO_UNAVAIL-if-sc-options-ar.patch -Patch0066: 0066-p11_child-NSS-print-key-type-in-a-debug-message.patch -Patch0067: 0067-pam_test_srv-set-default-value-for-SOFTHSM2_CONF.patch -Patch0068: 0068-tests-add-ECC-CA.patch -Patch0069: 0069-test_pam_srv-add-test-for-certificate-with-EC-keys.patch -Patch0070: 0070-p11_child-openssl-add-support-for-EC-keys.patch -Patch0071: 0071-utils-refactor-ssh-key-extraction-OpenSSL.patch -Patch0072: 0072-utils-add-ec_pub_key_to_ssh-OpenSSL.patch -Patch0073: 0073-utils-refactor-ssh-key-extraction-NSS.patch -Patch0074: 0074-utils-add-ec_pub_key_to_ssh-NSS.patch -Patch0075: 0075-SSSCTL-user-show-says-that-user-is-expired.patch -Patch0076: 0076-sss_iface-prevent-from-using-invalid-names-that-star.patch -Patch0077: 0077-nss-use-enumeration-context-as-talloc-parent-for-cac.patch -Patch0078: 0078-LDAP-minor-refactoring-in-auth_send-to-conform-to-ou.patch -Patch0079: 0079-LDAP-Only-authenticate-the-auth-connection-if-we-nee.patch -Patch0080: 0080-LDAP-Log-the-encryption-used-during-LDAP-authenticat.patch -Patch0081: 0081-nss-sssd-returns-for-emtpy-home-directories.patch -Patch0082: 0082-PROXY-Copy-the-response-to-the-caller.patch -Patch0083: 0083-Revert-IPA-use-forest-name-when-looking-up-the-Globa.patch -Patch0084: 0084-ipa-use-only-the-global-catalog-service-of-the-fores.patch -Patch0085: 0085-krb5_child-fix-permissions-during-SC-auth.patch -Patch0086: 0086-MAN-Explicitly-state-that-not-all-generic-domain-opt.patch -Patch0087: 0087-KCM-Deleting-a-non-existent-ccache-should-not-yield-.patch -Patch0088: 0088-confdb-Always-read-snippet-files.patch -Patch0089: 0089-CONFDB-Remove-old-libini-support.patch -Patch0090: 0090-idmap_sss-improve-man-page.patch -Patch0091: 0091-sbus-allow-access-for-sssd-user.patch -Patch0092: 0092-sbus-use-120-second-default-timeout.patch -Patch0093: 0093-ifp-extraAttributes-is-UnknownProperty.patch -Patch0094: 0094-AD-IPA-Reset-subdomain-service-name-not-domain-name.patch -Patch0095: 0095-IPA-Add-explicit-return-after-tevent_req_error.patch -Patch0096: 0096-KCM-Return-a-valid-tevent-error-code-if-a-request-ca.patch -Patch0097: 0097-KCM-Allow-representing-ccaches-with-a-NULL-principal.patch -Patch0098: 0098-KCM-Create-an-empty-ccache-on-switch-to-a-non-existi.patch -Patch0099: 0099-PAM-use-user-name-hint-if-any-domain-has-set-it.patch -Patch0100: 0100-pam_sss-PAM_USER_UNKNOWN-if-socket-is-missing.patch -Patch0101: 0101-ipa-ipa_getkeytab-don-t-call-libnss_sss.patch +Patch0001: 0001-MAN-ldap_user_home_directory-default-missing.patch +Patch0002: 0002-PROXY-Return-data-in-output-parameter-if-everything-.patch +Patch0003: 0003-LDAP-failover-does-not-work-on-non-responsive-ldaps.patch +Patch0004: 0004-sudo-use-proper-datetime-for-default-modifyTimestamp.patch +Patch0005: 0005-negcache-add-fq-usernames-of-know-domains-to-all-UPN.patch +Patch0006: 0006-p11_child-prefer-better-digest-function-if-card-supp.patch +Patch0007: 0007-p11_child-fix-a-memory-leak-and-other-memory-mangeme.patch +Patch0008: 0008-man-fix-description-of-dns_resolver_op_timeout.patch +Patch0009: 0009-man-fix-description-of-dns_resolver_timeout.patch +Patch0010: 0010-failover-add-dns_resolver_server_timeout-option.patch +Patch0011: 0011-failover-change-default-timeouts.patch +Patch0012: 0012-config-add-dns_resolver_op_timeout-to-option-list.patch +Patch0013: 0013-pam_sss-Add-missing-colon-to-the-PIN-prompt.patch +Patch0014: 0014-pam-make-sure-p11_child.log-has-the-right-permission.patch +Patch0015: 0015-ssh-make-sure-p11_child.log-has-the-right-permission.patch +Patch0016: 0016-BE-make-sure-child-log-files-have-the-right-permissi.patch +Patch0017: 0017-MAN-Get-rid-of-sssd-secrets-reference.patch +Patch0018: 0018-MAN-Document-that-it-is-enough-to-systemctl-restart-.patch +Patch0019: 0019-SECRETS-Use-different-option-names-from-secrets-and-.patch +Patch0020: 0020-SECRETS-Don-t-limit-the-global-number-of-ccaches.patch +Patch0021: 0021-KCM-Pass-confdb-context-to-the-ccache-db-initializat.patch +Patch0022: 0022-KCM-Configurable-quotas-for-the-secdb-ccache-back-en.patch +Patch0023: 0023-MAN-Document-that-PAM-stack-contains-the-systemd-use.patch +Patch0024: 0024-Don-t-qualify-users-from-files-domain-when-default_d.patch +Patch0025: 0025-pam-fix-loop-in-Smartcard-authentication.patch +Patch0026: 0026-SYSDB-Add-sysdb_search_with_ts_attr.patch +Patch0027: 0027-BE-search-with-sysdb_search_with_ts_attr.patch +Patch0028: 0028-BE-Enable-refresh-for-multiple-domains.patch +Patch0029: 0029-BE-Make-be_refresh_ctx_init-set-up-the-periodical-ta.patch +Patch0030: 0030-BE-LDAP-Call-be_refresh_ctx_init-in-the-provider-lib.patch +Patch0031: 0031-BE-Pass-in-attribute-to-look-up-with-instead-of-hard.patch +Patch0032: 0032-BE-Change-be_refresh_ctx_init-to-return-errno-and-se.patch +Patch0033: 0033-BE-LDAP-Split-out-a-helper-function-from-sdap_refres.patch +Patch0034: 0034-BE-Pass-in-filter_type-when-creating-the-refresh-acc.patch +Patch0035: 0035-BE-Send-refresh-requests-in-batches.patch +Patch0036: 0036-BE-Extend-be_ptask_create-with-control-when-to-sched.patch +Patch0037: 0037-BE-Schedule-the-refresh-interval-from-the-finish-tim.patch +Patch0038: 0038-AD-Implement-background-refresh-for-AD-domains.patch +Patch0039: 0039-IPA-Implement-background-refresh-for-IPA-domains.patch +Patch0040: 0040-BE-IPA-AD-LDAP-Add-inigroups-refresh-support.patch +Patch0041: 0041-BE-IPA-AD-LDAP-Initialize-the-refresh-callback-from-.patch +Patch0042: 0042-IPA-AD-SDAP-BE-Generate-refresh-callbacks-with-a-mac.patch +Patch0043: 0043-MAN-Amend-the-documentation-for-the-background-refre.patch +Patch0044: 0044-DP-SYSDB-Move-the-code-to-set-initgrExpireTimestamp-.patch +Patch0045: 0045-IPA-AD-LDAP-Increase-the-initgrExpireTimestamp-after.patch +Patch0046: 0046-BE-Introduce-flag-for-be_ptask_create.patch +Patch0047: 0047-BE-Convert-be_ptask-params-to-flags.patch +Patch0048: 0048-DYNDNS-dyndns_update-is-not-enough.patch +Patch0049: 0049-tests-Use-idm-DL1-module-to-install-389-ds.patch +Patch0050: 0050-pam-keep-pin-on-the-PAM-stack-for-forward_pass.patch +Patch0051: 0051-BE-Invalid-oprator-used-in-condition.patch +Patch0052: 0052-TESTS-Sync.-multihost-kcm-tests-with-master.patch +Patch0053: 0053-KCM-Add-a-forgotten-return.patch +Patch0054: 0054-KCM-Allow-modifications-of-ccache-s-principal.patch +Patch0055: 0055-KCM-Fill-empty-cache-do-not-initialize-a-new-one.patch ### Downstream Patches ### @@ -204,6 +158,7 @@ BuildRequires: selinux-policy-targeted BuildRequires: libcmocka-devel >= 1.0.0 BuildRequires: uid_wrapper BuildRequires: nss_wrapper +BuildRequires: pam_wrapper BuildRequires: p11-kit-devel BuildRequires: openssl-devel BuildRequires: gnutls-utils @@ -611,7 +566,7 @@ UIDs/GIDs to names and vice versa. It can be also used for mapping principal (user) name to IDs(UID or GID) or to obtain groups which user are member of. %package -n libsss_certmap -Summary: SSSD Certficate Mapping Library +Summary: SSSD Certificate Mapping Library Group: Development/Libraries License: LGPLv3+ Requires(post): /sbin/ldconfig @@ -622,7 +577,7 @@ Conflicts: sssd-common < %{version}-%{release} Library to map certificates to users based on rules %package -n libsss_certmap-devel -Summary: SSSD Certficate Mapping Library +Summary: SSSD Certificate Mapping Library Group: Development/Libraries License: LGPLv3+ Requires: libsss_certmap = %{version}-%{release} @@ -889,12 +844,12 @@ done %dir %{sssdstatedir} %dir %{_localstatedir}/cache/krb5rcache %attr(700,sssd,sssd) %dir %{dbpath} -%attr(755,sssd,sssd) %dir %{mcpath} +%attr(775,sssd,sssd) %dir %{mcpath} %attr(700,root,root) %dir %{secdbpath} %attr(751,root,root) %dir %{deskprofilepath} -%ghost %attr(0644,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/passwd -%ghost %attr(0644,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/group -%ghost %attr(0644,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/initgroups +%ghost %attr(0664,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/passwd +%ghost %attr(0664,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/group +%ghost %attr(0664,sssd,sssd) %verify(not md5 size mtime) %{mcpath}/initgroups %attr(755,sssd,sssd) %dir %{pipepath} %attr(750,sssd,root) %dir %{pipepath}/private %attr(755,sssd,sssd) %dir %{pubconfpath} @@ -903,7 +858,7 @@ done %attr(700,sssd,sssd) %dir %{_sysconfdir}/sssd %attr(711,sssd,sssd) %dir %{_sysconfdir}/sssd/conf.d %attr(711,root,root) %dir %{_sysconfdir}/sssd/pki -%ghost %attr(0600,sssd,sssd) %config(noreplace) %{_sysconfdir}/sssd/sssd.conf +%ghost %attr(0600,root,root) %config(noreplace) %{_sysconfdir}/sssd/sssd.conf %dir %{_sysconfdir}/logrotate.d %config(noreplace) %{_sysconfdir}/logrotate.d/sssd %dir %{_sysconfdir}/rwtab.d @@ -1284,17 +1239,93 @@ fi %{_libdir}/%{name}/modules/libwbclient.so %changelog -* Thu Apr 18 2019 Michal Židek - 2.0.0-43.3 -- Resolves: rhbz#1701135 - Include libsss_nss_idmap-devel in the Builder +* Wed Sep 4 2019 Michal Židek - 2.2.0-19 +- Resolves: rhbz#1712875 - Old kerberos credentials active instead of valid + new ones (kcm) + +* Sun Sep 1 2019 Michal Židek - 2.2.0-18 +- Resolves: rhbz#1744134 - New defect found in sssd-2.2.0-16.el8 +- Also sync. kcm multihost tests with master + +* Sun Sep 1 2019 Michal Židek - 2.2.0-17 +- Resolves: rhbz#1676385 - pam_sss with smartcard auth does not create gnome + keyring +- Also apply a patch to fix gating tests issue + +* Sun Aug 18 2019 Michal Židek - 2.2.0-16 +- Resolves: rhbz#1736861 - dyndns_update = True is no longer enough to get + the IP address of the machine updated in IPA upon + sssd.service startup + +* Sun Aug 18 2019 Michal Židek - 2.2.0-15 +- Resolves: rhbz#1736265 - Smart Card auth of local user: endless + loop if wrong PIN was provided + +* Sun Aug 18 2019 Michal Židek - 2.2.0-14 +- Resolves: rhbz#1736796 - sssd config option "default_domain_suffix" + should not cause files domain entries to be + qualified, this can break sudo access + +* Sun Aug 18 2019 Michal Židek - 2.2.0-13 +- Resolves: rhbz#1669407 - MAN: Document that PAM stack contains the + systemd-user service in the account phase in RHEL-8 + +* Sun Aug 18 2019 Michal Židek - 2.2.0-12 +- Resolves: rhbz#1448094 - sssd-kcm cannot handle big tickets + +* Fri Aug 9 2019 Michal Židek - 2.2.0-11 +- Resolves: rhbz#1733372 - permission denied on logs when running sssd as + non-root user + +* Fri Aug 9 2019 Michal Židek - 2.2.0-10 +- Resolves: rhbz#1736483 - Sudo prompt for smart card authentication is missing + the trailing colon + +* Fri Aug 9 2019 Michal Židek - 2.2.0-9 +- Resolves: rhbz#1382750 - Conflicting default timeout values + +* Fri Aug 2 2019 Michal Židek - 2.2.0-8 +- Resolves: rhbz#1699480 - Include libsss_nss_idmap-devel in the Builder repository + - This just required a raise in release number + and changelog for the record. + +* Fri Aug 2 2019 Michal Židek - 2.2.0-7 +- Resolves: rhbz#1711318 - p11_child::sign_data() function implementation is + not FIPS140 compliant + +* Fri Aug 2 2019 Michal Židek - 2.2.0-6 +- Resolves: rhbz#1726945 - negative cache does not use values from + 'filter_users' config option for known domains + +* Thu Jul 25 2019 Jakub Hrozek - 2.2.0-5 +- Resolves: rhbz#1729055 - sssd does not pass correct rules to sudo + +* Thu Jul 25 2019 Jakub Hrozek - 2.2.0-4 +- Resolves: rhbz#1283798 - sssd failover does not work on connecting to + non-responsive ldaps:// server + +* Wed Jul 3 2019 Jakub Hrozek - 2.2.0-3 +- Resolves: rhbz#1725168 - sssd-proxy crashes resolving groups with + no members + +* Wed Jul 3 2019 Jakub Hrozek - 2.2.0-2 +- Resolves: rhbz#1673443 - sssd man pages: The default value of + "ldap_user_home_directory" is not mentioned + with AD server configuration + +* Fri Jun 14 2019 Michal Židek - 2.2.0-1 +- Resolves: rhbz#1687281 + Rebase sssd in RHEL-8.1 to the latest upstream release -* Fri Apr 05 2019 Michal Židek - 2.0.0-43.2 -- Resolves: rhbz#1696596 - AD user not found after establishing trust and - restarting sssd [ZStream Clone] +* Wed Jun 12 2019 Michal Židek - 2.1.0-1 +- Resolves: rhbz#1687281 + Rebase sssd in RHEL-8.1 to the latest upstream release -* Fri Mar 29 2019 Michal Židek - 2.0.0-43.1 -- Resolves: rhbz#1691750 - pam_sss failing for external users not configured - via sssd +* Thu May 30 2019 Michal Židek - 2.0.0-45 +- Replace ARRAY_SIZE with N_ELEMENTS to reflect samba changes. This is + done here in order to unblock gating changes before rebase. +- Related: rhbz#1682305 * Sun Feb 10 2019 Jakub Hrozek - 2.0.0-43 - Resolves: rhbz#1672780 - gdm login not prompting for username when smart