diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b147e6a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/sssd-2.0.0.tar.gz diff --git a/.sssd.metadata b/.sssd.metadata new file mode 100644 index 0000000..7f62e35 --- /dev/null +++ b/.sssd.metadata @@ -0,0 +1 @@ +700ff5391bea73c19ddcdf99b25615fd4d284d7b SOURCES/sssd-2.0.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 new file mode 100644 index 0000000..c6c7fa1 --- /dev/null +++ b/SOURCES/0001-KCM-Don-t-error-out-if-creating-a-new-ID-as-the-firs.patch @@ -0,0 +1,41 @@ +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/0002-sbus-register-filter-on-new-connection.patch b/SOURCES/0002-sbus-register-filter-on-new-connection.patch new file mode 100644 index 0000000..69e00c2 --- /dev/null +++ b/SOURCES/0002-sbus-register-filter-on-new-connection.patch @@ -0,0 +1,48 @@ +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-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 new file mode 100644 index 0000000..4ed5198 --- /dev/null +++ b/SOURCES/0003-sysdb-extract-sysdb_ldb_msg_attr_to_certmap_info-cal.patch @@ -0,0 +1,260 @@ +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-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 new file mode 100644 index 0000000..38fc538 --- /dev/null +++ b/SOURCES/0004-sysdb_ldb_msg_attr_to_certmap_info-set-SSS_CERTMAP_M.patch @@ -0,0 +1,40 @@ +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-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 new file mode 100644 index 0000000..c67b895 --- /dev/null +++ b/SOURCES/0005-sysdb-add-attr_map-attribute-to-sysdb_ldb_msg_attr_t.patch @@ -0,0 +1,141 @@ +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 new file mode 100644 index 0000000..210f90d --- /dev/null +++ b/SOURCES/0006-confdb-add-confdb_certmap_to_sysdb.patch @@ -0,0 +1,168 @@ +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/0007-AD-LDAP-read-certificate-mapping-rules-from-config-f.patch b/SOURCES/0007-AD-LDAP-read-certificate-mapping-rules-from-config-f.patch new file mode 100644 index 0000000..a838fe7 --- /dev/null +++ b/SOURCES/0007-AD-LDAP-read-certificate-mapping-rules-from-config-f.patch @@ -0,0 +1,72 @@ +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/0008-sysdb-sysdb_certmap_add-handle-domains-more-flexible.patch b/SOURCES/0008-sysdb-sysdb_certmap_add-handle-domains-more-flexible.patch new file mode 100644 index 0000000..0ca43a2 --- /dev/null +++ b/SOURCES/0008-sysdb-sysdb_certmap_add-handle-domains-more-flexible.patch @@ -0,0 +1,33 @@ +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 new file mode 100644 index 0000000..ad0e621 --- /dev/null +++ b/SOURCES/0009-confdb-add-special-handling-for-rules-for-the-files-.patch @@ -0,0 +1,132 @@ +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/0010-files-add-support-for-Smartcard-authentication.patch b/SOURCES/0010-files-add-support-for-Smartcard-authentication.patch new file mode 100644 index 0000000..41d3d62 --- /dev/null +++ b/SOURCES/0010-files-add-support-for-Smartcard-authentication.patch @@ -0,0 +1,415 @@ +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-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 new file mode 100644 index 0000000..be4740f --- /dev/null +++ b/SOURCES/0011-responder-make-sure-SSS_DP_CERT-is-passed-to-files-p.patch @@ -0,0 +1,69 @@ +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 new file mode 100644 index 0000000..2dea1b9 --- /dev/null +++ b/SOURCES/0012-PAM-add-certificate-matching-rules-from-all-domains.patch @@ -0,0 +1,167 @@ +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/0013-doc-add-certificate-mapping-section-to-man-page.patch b/SOURCES/0013-doc-add-certificate-mapping-section-to-man-page.patch new file mode 100644 index 0000000..e6641ce --- /dev/null +++ b/SOURCES/0013-doc-add-certificate-mapping-section-to-man-page.patch @@ -0,0 +1,183 @@ +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/0014-intg-user-default-locale.patch b/SOURCES/0014-intg-user-default-locale.patch new file mode 100644 index 0000000..1e94700 --- /dev/null +++ b/SOURCES/0014-intg-user-default-locale.patch @@ -0,0 +1,31 @@ +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/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 new file mode 100644 index 0000000..39c3c91 --- /dev/null +++ b/SOURCES/0015-PAM-use-better-PAM-error-code-for-failed-Smartcard-a.patch @@ -0,0 +1,35 @@ +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/0016-test_ca-test-library-only-for-readable.patch b/SOURCES/0016-test_ca-test-library-only-for-readable.patch new file mode 100644 index 0000000..6e71fd2 --- /dev/null +++ b/SOURCES/0016-test_ca-test-library-only-for-readable.patch @@ -0,0 +1,32 @@ +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-test_ca-set-a-password-PIN-to-nss-databases.patch b/SOURCES/0017-test_ca-set-a-password-PIN-to-nss-databases.patch new file mode 100644 index 0000000..6df5716 --- /dev/null +++ b/SOURCES/0017-test_ca-set-a-password-PIN-to-nss-databases.patch @@ -0,0 +1,58 @@ +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-getsockopt_wrapper-add-support-for-PAM-clients.patch b/SOURCES/0018-getsockopt_wrapper-add-support-for-PAM-clients.patch new file mode 100644 index 0000000..c520c4d --- /dev/null +++ b/SOURCES/0018-getsockopt_wrapper-add-support-for-PAM-clients.patch @@ -0,0 +1,79 @@ +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-intg-add-Smartcard-authentication-tests.patch b/SOURCES/0019-intg-add-Smartcard-authentication-tests.patch new file mode 100644 index 0000000..f7912ec --- /dev/null +++ b/SOURCES/0019-intg-add-Smartcard-authentication-tests.patch @@ -0,0 +1,331 @@ +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-sbus-dectect-python-binary-for-sbus_generate.sh.patch b/SOURCES/0020-sbus-dectect-python-binary-for-sbus_generate.sh.patch new file mode 100644 index 0000000..bd0e5ee --- /dev/null +++ b/SOURCES/0020-sbus-dectect-python-binary-for-sbus_generate.sh.patch @@ -0,0 +1,88 @@ +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 new file mode 100644 index 0000000..1f608ec --- /dev/null +++ b/SOURCES/0021-CONFDB-Skip-local-domain-if-not-supported.patch @@ -0,0 +1,42 @@ +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/0022-SELINUX-Always-add-SELinux-user-to-the-semanage-data.patch b/SOURCES/0022-SELINUX-Always-add-SELinux-user-to-the-semanage-data.patch new file mode 100644 index 0000000..3b1da28 --- /dev/null +++ b/SOURCES/0022-SELINUX-Always-add-SELinux-user-to-the-semanage-data.patch @@ -0,0 +1,145 @@ +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-proxy-access-provider-directly-not-through-be_ctx.patch b/SOURCES/0023-proxy-access-provider-directly-not-through-be_ctx.patch new file mode 100644 index 0000000..2ac0feb --- /dev/null +++ b/SOURCES/0023-proxy-access-provider-directly-not-through-be_ctx.patch @@ -0,0 +1,49 @@ +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-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 new file mode 100644 index 0000000..cef0070 --- /dev/null +++ b/SOURCES/0024-dp-set-be_ctx-provider-as-part-of-dp_init-request.patch @@ -0,0 +1,144 @@ +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-sbus-read-destination-after-sender-is-set.patch b/SOURCES/0025-sbus-read-destination-after-sender-is-set.patch new file mode 100644 index 0000000..30364d0 --- /dev/null +++ b/SOURCES/0025-sbus-read-destination-after-sender-is-set.patch @@ -0,0 +1,42 @@ +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-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 new file mode 100644 index 0000000..ec4f920 --- /dev/null +++ b/SOURCES/0026-sbus-do-not-try-to-remove-signal-listeners-when-disc.patch @@ -0,0 +1,34 @@ +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-sbus-free-watch_fd-fdevent-explicitly.patch b/SOURCES/0027-sbus-free-watch_fd-fdevent-explicitly.patch new file mode 100644 index 0000000..8fd0972 --- /dev/null +++ b/SOURCES/0027-sbus-free-watch_fd-fdevent-explicitly.patch @@ -0,0 +1,29 @@ +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-doc-remove-local-provider-reference-from-manpages.patch b/SOURCES/0028-doc-remove-local-provider-reference-from-manpages.patch new file mode 100644 index 0000000..aa12719 --- /dev/null +++ b/SOURCES/0028-doc-remove-local-provider-reference-from-manpages.patch @@ -0,0 +1,139 @@ +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-confdb-log-an-error-when-domain-is-misconfigured.patch b/SOURCES/0029-confdb-log-an-error-when-domain-is-misconfigured.patch new file mode 100644 index 0000000..f8120b9 --- /dev/null +++ b/SOURCES/0029-confdb-log-an-error-when-domain-is-misconfigured.patch @@ -0,0 +1,48 @@ +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-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 new file mode 100644 index 0000000..30cb266 --- /dev/null +++ b/SOURCES/0030-be-use-be_is_offline-for-the-main-domain-when-asking.patch @@ -0,0 +1,58 @@ +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-sudo-respect-case-sensitivity-in-sudo-responder.patch b/SOURCES/0031-sudo-respect-case-sensitivity-in-sudo-responder.patch new file mode 100644 index 0000000..aa983bd --- /dev/null +++ b/SOURCES/0031-sudo-respect-case-sensitivity-in-sudo-responder.patch @@ -0,0 +1,69 @@ +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-sbus-fix-typo.patch b/SOURCES/0032-sbus-fix-typo.patch new file mode 100644 index 0000000..af080fc --- /dev/null +++ b/SOURCES/0032-sbus-fix-typo.patch @@ -0,0 +1,27 @@ +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-sbus-check-for-null-message-in-sbus_message_bound.patch b/SOURCES/0033-sbus-check-for-null-message-in-sbus_message_bound.patch new file mode 100644 index 0000000..e257239 --- /dev/null +++ b/SOURCES/0033-sbus-check-for-null-message-in-sbus_message_bound.patch @@ -0,0 +1,42 @@ +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-sbus-replace-sbus_message_bound_ref-with-sbus_messag.patch b/SOURCES/0034-sbus-replace-sbus_message_bound_ref-with-sbus_messag.patch new file mode 100644 index 0000000..2fb9d4f --- /dev/null +++ b/SOURCES/0034-sbus-replace-sbus_message_bound_ref-with-sbus_messag.patch @@ -0,0 +1,337 @@ +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-sbus-add-unit-tests-for-public-sbus_message-module.patch b/SOURCES/0035-sbus-add-unit-tests-for-public-sbus_message-module.patch new file mode 100644 index 0000000..70e2298 --- /dev/null +++ b/SOURCES/0035-sbus-add-unit-tests-for-public-sbus_message-module.patch @@ -0,0 +1,664 @@ +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-p11-handle-multiple-certs-during-auth-with-OpenSSL.patch b/SOURCES/0036-p11-handle-multiple-certs-during-auth-with-OpenSSL.patch new file mode 100644 index 0000000..945601d --- /dev/null +++ b/SOURCES/0036-p11-handle-multiple-certs-during-auth-with-OpenSSL.patch @@ -0,0 +1,147 @@ +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-p11_child-add-wait_for_card-option.patch b/SOURCES/0037-p11_child-add-wait_for_card-option.patch new file mode 100644 index 0000000..6cf433d --- /dev/null +++ b/SOURCES/0037-p11_child-add-wait_for_card-option.patch @@ -0,0 +1,476 @@ +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-PAM-add-p11_wait_for_card_timeout-option.patch b/SOURCES/0038-PAM-add-p11_wait_for_card_timeout-option.patch new file mode 100644 index 0000000..d3931d1 --- /dev/null +++ b/SOURCES/0038-PAM-add-p11_wait_for_card_timeout-option.patch @@ -0,0 +1,144 @@ +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-pam_sss-make-flags-public.patch b/SOURCES/0039-pam_sss-make-flags-public.patch new file mode 100644 index 0000000..b690e75 --- /dev/null +++ b/SOURCES/0039-pam_sss-make-flags-public.patch @@ -0,0 +1,245 @@ +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-pam_sss-add-try_cert_auth-option.patch b/SOURCES/0040-pam_sss-add-try_cert_auth-option.patch new file mode 100644 index 0000000..89129f6 --- /dev/null +++ b/SOURCES/0040-pam_sss-add-try_cert_auth-option.patch @@ -0,0 +1,101 @@ +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-pam_sss-add-option-require_cert_auth.patch b/SOURCES/0041-pam_sss-add-option-require_cert_auth.patch new file mode 100644 index 0000000..7dc8826 --- /dev/null +++ b/SOURCES/0041-pam_sss-add-option-require_cert_auth.patch @@ -0,0 +1,372 @@ +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-intg-require-SC-tests.patch b/SOURCES/0042-intg-require-SC-tests.patch new file mode 100644 index 0000000..a8c7e18 --- /dev/null +++ b/SOURCES/0042-intg-require-SC-tests.patch @@ -0,0 +1,310 @@ +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-p11_child-show-PKCS-11-URI-in-debug-output.patch b/SOURCES/0043-p11_child-show-PKCS-11-URI-in-debug-output.patch new file mode 100644 index 0000000..1b0cf16 --- /dev/null +++ b/SOURCES/0043-p11_child-show-PKCS-11-URI-in-debug-output.patch @@ -0,0 +1,408 @@ +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-p11_child-add-PKCS-11-uri-to-restrict-selection.patch b/SOURCES/0044-p11_child-add-PKCS-11-uri-to-restrict-selection.patch new file mode 100644 index 0000000..bc0eb02 --- /dev/null +++ b/SOURCES/0044-p11_child-add-PKCS-11-uri-to-restrict-selection.patch @@ -0,0 +1,239 @@ +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-PAM-add-p11_uri-option.patch b/SOURCES/0045-PAM-add-p11_uri-option.patch new file mode 100644 index 0000000..e495f08 --- /dev/null +++ b/SOURCES/0045-PAM-add-p11_uri-option.patch @@ -0,0 +1,194 @@ +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-tests-add-PKCS-11-URI-tests.patch b/SOURCES/0046-tests-add-PKCS-11-URI-tests.patch new file mode 100644 index 0000000..a63bb54 --- /dev/null +++ b/SOURCES/0046-tests-add-PKCS-11-URI-tests.patch @@ -0,0 +1,210 @@ +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-PAM-return-short-name-for-files-provider-users.patch b/SOURCES/0047-PAM-return-short-name-for-files-provider-users.patch new file mode 100644 index 0000000..b3cbed2 --- /dev/null +++ b/SOURCES/0047-PAM-return-short-name-for-files-provider-users.patch @@ -0,0 +1,148 @@ +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-doc-Add-nsswitch.conf-note-to-manpage.patch b/SOURCES/0048-doc-Add-nsswitch.conf-note-to-manpage.patch new file mode 100644 index 0000000..7fd3b19 --- /dev/null +++ b/SOURCES/0048-doc-Add-nsswitch.conf-note-to-manpage.patch @@ -0,0 +1,77 @@ +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 new file mode 100644 index 0000000..a49ca25 --- /dev/null +++ b/SOURCES/0049-intg-flush-the-SSSD-caches-to-sync-with-files.patch @@ -0,0 +1,45 @@ +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/0050-FILES-The-files-provider-should-not-enumerate.patch b/SOURCES/0050-FILES-The-files-provider-should-not-enumerate.patch new file mode 100644 index 0000000..654964a --- /dev/null +++ b/SOURCES/0050-FILES-The-files-provider-should-not-enumerate.patch @@ -0,0 +1,101 @@ +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/0051-p11_child-add-OCSP-check-ot-the-OpenSSL-version.patch b/SOURCES/0051-p11_child-add-OCSP-check-ot-the-OpenSSL-version.patch new file mode 100644 index 0000000..e04bad1 --- /dev/null +++ b/SOURCES/0051-p11_child-add-OCSP-check-ot-the-OpenSSL-version.patch @@ -0,0 +1,490 @@ +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-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 new file mode 100644 index 0000000..31dc808 --- /dev/null +++ b/SOURCES/0052-p11_child-add-crl_file-option-for-the-OpenSSL-build.patch @@ -0,0 +1,280 @@ +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-p11-Fix-two-instances-of-Wmaybe-uninitialized-in-p11.patch b/SOURCES/0053-p11-Fix-two-instances-of-Wmaybe-uninitialized-in-p11.patch new file mode 100644 index 0000000..831330d --- /dev/null +++ b/SOURCES/0053-p11-Fix-two-instances-of-Wmaybe-uninitialized-in-p11.patch @@ -0,0 +1,38 @@ +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-sudo-use-correct-sbus-interface.patch b/SOURCES/0054-sudo-use-correct-sbus-interface.patch new file mode 100644 index 0000000..7122888 --- /dev/null +++ b/SOURCES/0054-sudo-use-correct-sbus-interface.patch @@ -0,0 +1,32 @@ +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-sudo-fix-error-handling-in-sudosrv_refresh_rules_don.patch b/SOURCES/0055-sudo-fix-error-handling-in-sudosrv_refresh_rules_don.patch new file mode 100644 index 0000000..c7ca404 --- /dev/null +++ b/SOURCES/0055-sudo-fix-error-handling-in-sudosrv_refresh_rules_don.patch @@ -0,0 +1,41 @@ +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 new file mode 100644 index 0000000..440e9b7 --- /dev/null +++ b/SOURCES/0056-files-add-session-recording-flag.patch @@ -0,0 +1,136 @@ +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 new file mode 100644 index 0000000..dff7c19 --- /dev/null +++ b/SOURCES/0057-UTIL-Suppress-Coverity-warning.patch @@ -0,0 +1,43 @@ +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 new file mode 100644 index 0000000..399c5c7 --- /dev/null +++ b/SOURCES/0058-PYSSS-Re-add-the-pysss.getgrouplist-interface.patch @@ -0,0 +1,121 @@ +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 new file mode 100644 index 0000000..7509f03 --- /dev/null +++ b/SOURCES/0059-ifp-fix-typo-causing-a-crash-in-FindByNameAndCertifi.patch @@ -0,0 +1,46 @@ +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 new file mode 100644 index 0000000..0c5e349 --- /dev/null +++ b/SOURCES/0060-IFP-Use-subreq-not-req-when-calling-RefreshRules_rec.patch @@ -0,0 +1,35 @@ +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 new file mode 100644 index 0000000..2452780 --- /dev/null +++ b/SOURCES/0061-INI-Return-errno-not-1-on-failure-from-sss_ini_get_s.patch @@ -0,0 +1,42 @@ +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 new file mode 100644 index 0000000..824a2a6 --- /dev/null +++ b/SOURCES/0062-MONITOR-Don-t-check-for-pidfile-if-SSSD-is-already-r.patch @@ -0,0 +1,53 @@ +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 new file mode 100644 index 0000000..6af1af1 --- /dev/null +++ b/SOURCES/0063-SSSD-Allow-refreshing-only-certain-section-with-genc.patch @@ -0,0 +1,399 @@ +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 new file mode 100644 index 0000000..e5f66ba --- /dev/null +++ b/SOURCES/0064-SYSTEMD-Re-read-KCM-configuration-on-systemctl-resta.patch @@ -0,0 +1,84 @@ +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 new file mode 100644 index 0000000..700b249 --- /dev/null +++ b/SOURCES/0065-pam_sss-return-PAM_AUTHINFO_UNAVAIL-if-sc-options-ar.patch @@ -0,0 +1,72 @@ +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 new file mode 100644 index 0000000..e9e73dd --- /dev/null +++ b/SOURCES/0066-p11_child-NSS-print-key-type-in-a-debug-message.patch @@ -0,0 +1,72 @@ +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 new file mode 100644 index 0000000..6662610 --- /dev/null +++ b/SOURCES/0067-pam_test_srv-set-default-value-for-SOFTHSM2_CONF.patch @@ -0,0 +1,47 @@ +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 new file mode 100644 index 0000000..a8f0717 --- /dev/null +++ b/SOURCES/0068-tests-add-ECC-CA.patch @@ -0,0 +1,276 @@ +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 new file mode 100644 index 0000000..f9e9d92 --- /dev/null +++ b/SOURCES/0069-test_pam_srv-add-test-for-certificate-with-EC-keys.patch @@ -0,0 +1,198 @@ +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 new file mode 100644 index 0000000..3b3f29e --- /dev/null +++ b/SOURCES/0070-p11_child-openssl-add-support-for-EC-keys.patch @@ -0,0 +1,409 @@ +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 new file mode 100644 index 0000000..6d732d7 --- /dev/null +++ b/SOURCES/0071-utils-refactor-ssh-key-extraction-OpenSSL.patch @@ -0,0 +1,133 @@ +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 new file mode 100644 index 0000000..2fa32d0 --- /dev/null +++ b/SOURCES/0072-utils-add-ec_pub_key_to_ssh-OpenSSL.patch @@ -0,0 +1,265 @@ +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 new file mode 100644 index 0000000..c3e1ec7 --- /dev/null +++ b/SOURCES/0073-utils-refactor-ssh-key-extraction-NSS.patch @@ -0,0 +1,153 @@ +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 new file mode 100644 index 0000000..6ad4d92 --- /dev/null +++ b/SOURCES/0074-utils-add-ec_pub_key_to_ssh-NSS.patch @@ -0,0 +1,158 @@ +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 new file mode 100644 index 0000000..b960eea --- /dev/null +++ b/SOURCES/0075-SSSCTL-user-show-says-that-user-is-expired.patch @@ -0,0 +1,53 @@ +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 new file mode 100644 index 0000000..a444b0c --- /dev/null +++ b/SOURCES/0076-sss_iface-prevent-from-using-invalid-names-that-star.patch @@ -0,0 +1,52 @@ +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 new file mode 100644 index 0000000..3e2745e --- /dev/null +++ b/SOURCES/0077-nss-use-enumeration-context-as-talloc-parent-for-cac.patch @@ -0,0 +1,145 @@ +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 new file mode 100644 index 0000000..d24017d --- /dev/null +++ b/SOURCES/0078-LDAP-minor-refactoring-in-auth_send-to-conform-to-ou.patch @@ -0,0 +1,71 @@ +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 new file mode 100644 index 0000000..db77f7c --- /dev/null +++ b/SOURCES/0079-LDAP-Only-authenticate-the-auth-connection-if-we-nee.patch @@ -0,0 +1,130 @@ +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 new file mode 100644 index 0000000..435ecae --- /dev/null +++ b/SOURCES/0080-LDAP-Log-the-encryption-used-during-LDAP-authenticat.patch @@ -0,0 +1,59 @@ +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 new file mode 100644 index 0000000..6560880 --- /dev/null +++ b/SOURCES/0081-nss-sssd-returns-for-emtpy-home-directories.patch @@ -0,0 +1,98 @@ +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 new file mode 100644 index 0000000..e619358 --- /dev/null +++ b/SOURCES/0082-PROXY-Copy-the-response-to-the-caller.patch @@ -0,0 +1,57 @@ +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 new file mode 100644 index 0000000..6b167a4 --- /dev/null +++ b/SOURCES/0083-Revert-IPA-use-forest-name-when-looking-up-the-Globa.patch @@ -0,0 +1,29 @@ +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 new file mode 100644 index 0000000..904a923 --- /dev/null +++ b/SOURCES/0084-ipa-use-only-the-global-catalog-service-of-the-fores.patch @@ -0,0 +1,103 @@ +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 new file mode 100644 index 0000000..6765540 --- /dev/null +++ b/SOURCES/0085-krb5_child-fix-permissions-during-SC-auth.patch @@ -0,0 +1,138 @@ +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 new file mode 100644 index 0000000..078fe9f --- /dev/null +++ b/SOURCES/0086-MAN-Explicitly-state-that-not-all-generic-domain-opt.patch @@ -0,0 +1,36 @@ +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 new file mode 100644 index 0000000..dcc0d83 --- /dev/null +++ b/SOURCES/0087-KCM-Deleting-a-non-existent-ccache-should-not-yield-.patch @@ -0,0 +1,38 @@ +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 new file mode 100644 index 0000000..c6d5ef0 --- /dev/null +++ b/SOURCES/0088-confdb-Always-read-snippet-files.patch @@ -0,0 +1,220 @@ +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 new file mode 100644 index 0000000..a148912 --- /dev/null +++ b/SOURCES/0089-CONFDB-Remove-old-libini-support.patch @@ -0,0 +1,269 @@ +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 new file mode 100644 index 0000000..3d5d23e --- /dev/null +++ b/SOURCES/0090-idmap_sss-improve-man-page.patch @@ -0,0 +1,54 @@ +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 new file mode 100644 index 0000000..c6e8679 --- /dev/null +++ b/SOURCES/0091-sbus-allow-access-for-sssd-user.patch @@ -0,0 +1,61 @@ +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 new file mode 100644 index 0000000..dd010bf --- /dev/null +++ b/SOURCES/0092-sbus-use-120-second-default-timeout.patch @@ -0,0 +1,50 @@ +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 new file mode 100644 index 0000000..ad00b4c --- /dev/null +++ b/SOURCES/0093-ifp-extraAttributes-is-UnknownProperty.patch @@ -0,0 +1,113 @@ +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 new file mode 100644 index 0000000..b62c72f --- /dev/null +++ b/SOURCES/0094-AD-IPA-Reset-subdomain-service-name-not-domain-name.patch @@ -0,0 +1,140 @@ +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 new file mode 100644 index 0000000..e749f70 --- /dev/null +++ b/SOURCES/0095-IPA-Add-explicit-return-after-tevent_req_error.patch @@ -0,0 +1,37 @@ +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 new file mode 100644 index 0000000..395e1a9 --- /dev/null +++ b/SOURCES/0096-KCM-Return-a-valid-tevent-error-code-if-a-request-ca.patch @@ -0,0 +1,35 @@ +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 new file mode 100644 index 0000000..564122b --- /dev/null +++ b/SOURCES/0097-KCM-Allow-representing-ccaches-with-a-NULL-principal.patch @@ -0,0 +1,281 @@ +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 new file mode 100644 index 0000000..c98c83c --- /dev/null +++ b/SOURCES/0098-KCM-Create-an-empty-ccache-on-switch-to-a-non-existi.patch @@ -0,0 +1,244 @@ +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 new file mode 100644 index 0000000..7c7551c --- /dev/null +++ b/SOURCES/0099-PAM-use-user-name-hint-if-any-domain-has-set-it.patch @@ -0,0 +1,67 @@ +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/0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec b/SOURCES/0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec new file mode 100644 index 0000000..f24afe3 --- /dev/null +++ b/SOURCES/0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec @@ -0,0 +1,26 @@ +From 8d38a4b28ab7af15406b244910f369ba1aff02db Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Thu, 30 Oct 2014 15:59:17 +0100 +Subject: [PATCH 93/93] NOUPSTREAM: Default to root if sssd user is not + specified + +--- + src/monitor/monitor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c +index 0dea327213a1ad04b6f69c0ffb0fb87254420796..20b4aef4ee94fd42de1585d7d7c2e01ea01845ac 100644 +--- a/src/monitor/monitor.c ++++ b/src/monitor/monitor.c +@@ -925,7 +925,7 @@ static int get_service_user(struct mt_ctx *ctx) + + ret = confdb_get_string(ctx->cdb, ctx, CONFDB_MONITOR_CONF_ENTRY, + CONFDB_MONITOR_USER_RUNAS, +- SSSD_USER, &user_str); ++ "root", &user_str); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get the user to run as\n"); + return ret; +-- +1.9.3 + diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec new file mode 100644 index 0000000..6ecbcdd --- /dev/null +++ b/SPECS/sssd.spec @@ -0,0 +1,2920 @@ +# we don't want to provide private python extension libs +%define __provides_exclude_from %{python3_sitearch}/.*\.so$|%{_libdir}/%{name}/modules/libwbclient.so.*$ + +# SSSD fails to build with -Wl,-z,defs +%undefine _strict_symbol_defs_build + +%define _hardened_build 1 + +%global install_pcscd_polkit_rule 1 + +# Determine the location of the LDB modules directory +%global ldb_modulesdir %(pkg-config --variable=modulesdir ldb) +%global ldb_version 1.2.0 + +%global enable_systemtap 1 + %global enable_systemtap_opt --enable-systemtap + +%global libwbc_alternatives_version 0.14 +%global libwbc_lib_version %{libwbc_alternatives_version}.0 +%global libwbc_alternatives_suffix %nil +%if 0%{?__isa_bits} == 64 +%global libwbc_alternatives_suffix -64 +%endif + +Name: sssd +Version: 2.0.0 +Release: 43%{?dist} +Group: Applications/System +Summary: System Security Services Daemon +License: GPLv3+ +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 + +### Downstream Patches ### + +#This patch should not be removed in RHEL-8 +Patch999: 0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec + +### Dependencies ### + +Requires: sssd-common = %{version}-%{release} +Requires: sssd-ldap = %{version}-%{release} +Requires: sssd-krb5 = %{version}-%{release} +Requires: sssd-ipa = %{version}-%{release} +Requires: sssd-ad = %{version}-%{release} +Recommends: sssd-proxy = %{version}-%{release} +Requires: python3-sssdconfig = %{version}-%{release} +Suggests: sssd-dbus = %{version}-%{release} + +%global servicename sssd +%global sssdstatedir %{_localstatedir}/lib/sss +%global dbpath %{sssdstatedir}/db +%global keytabdir %{sssdstatedir}/keytabs +%global pipepath %{sssdstatedir}/pipes +%global mcpath %{sssdstatedir}/mc +%global pubconfpath %{sssdstatedir}/pubconf +%global gpocachepath %{sssdstatedir}/gpo_cache +%global secdbpath %{sssdstatedir}/secrets +%global deskprofilepath %{sssdstatedir}/deskprofile + +### Build Dependencies ### + +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: libtool +BuildRequires: m4 +BuildRequires: gcc +BuildRequires: popt-devel +BuildRequires: libtalloc-devel +BuildRequires: libtevent-devel +BuildRequires: libtdb-devel +BuildRequires: libldb-devel >= %{ldb_version} +BuildRequires: libdhash-devel >= 0.4.2 +BuildRequires: libcollection-devel +BuildRequires: libini_config-devel >= 1.1 +BuildRequires: dbus-devel +BuildRequires: dbus-libs +BuildRequires: openldap-devel +BuildRequires: pam-devel +BuildRequires: nss-devel +BuildRequires: nspr-devel +BuildRequires: pcre-devel +BuildRequires: libxslt +BuildRequires: libxml2 +BuildRequires: docbook-style-xsl +BuildRequires: krb5-devel +BuildRequires: c-ares-devel +BuildRequires: python3-devel +BuildRequires: check-devel +BuildRequires: doxygen +BuildRequires: libselinux-devel +BuildRequires: libsemanage-devel +BuildRequires: bind-utils +BuildRequires: keyutils-libs-devel +BuildRequires: gettext-devel +BuildRequires: pkgconfig +BuildRequires: diffstat +BuildRequires: findutils +BuildRequires: glib2-devel +BuildRequires: selinux-policy-targeted +BuildRequires: libcmocka-devel >= 1.0.0 +BuildRequires: uid_wrapper +BuildRequires: nss_wrapper +BuildRequires: p11-kit-devel +BuildRequires: openssl-devel +BuildRequires: gnutls-utils +BuildRequires: softhsm >= 2.1.0 +BuildRequires: openssl +BuildRequires: openssh +BuildRequires: libnl3-devel +BuildRequires: systemd-devel +BuildRequires: systemd +BuildRequires: cifs-utils-devel +BuildRequires: libnfsidmap-devel +BuildRequires: samba4-devel +BuildRequires: libsmbclient-devel +BuildRequires: samba-winbind +BuildRequires: systemtap-sdt-devel +BuildRequires: libuuid-devel +BuildRequires: jansson-devel +BuildRequires: gdm-pam-extensions-devel + +%description +Provides a set of daemons to manage access to remote directories and +authentication mechanisms. It provides an NSS and PAM interface toward +the system and a plug-gable back-end system to connect to multiple different +account sources. It is also the basis to provide client auditing and policy +services for projects like FreeIPA. + +The sssd sub-package is a meta-package that contains the daemon as well as all +the existing back ends. + +%package common +Summary: Common files for the SSSD +Group: Applications/System +License: GPLv3+ +# Conflicts +Conflicts: selinux-policy < 3.10.0-46 +Conflicts: sssd < 1.10.0-8%{?dist}.beta2 +# Requires +# Explicitly require RHEL-8.0 versions of the Samba libraries +# in order to prevent untested combinations of a new SSSD and +# older libraries. See e.g. rhbz#1593756 +Requires: libtalloc >= 2.1.14-1 +Requires: libtevent >= 0.9.37-1 +Requires: libldb >= 1.4.2-1 +Requires: libtdb >= 1.3.16-1 +# due to ABI changes in 1.1.30/1.2.0 +Requires: libldb >= %{ldb_version} +Requires: sssd-client%{?_isa} = %{version}-%{release} +Recommends: libsss_sudo = %{version}-%{release} +Recommends: libsss_autofs%{?_isa} = %{version}-%{release} +Recommends: sssd-nfs-idmap = %{version}-%{release} +Requires: libsss_idmap = %{version}-%{release} +Requires(pre): shadow-utils +%{?systemd_requires} + +### Provides ### +Provides: libsss_sudo-devel = %{version}-%{release} +Obsoletes: libsss_sudo-devel <= 1.10.0-7%{?dist}.beta1 + +%description common +Common files for the SSSD. The common package includes all the files needed +to run a particular back end, however, the back ends are packaged in separate +sub-packages such as sssd-ldap. + +%package client +Summary: SSSD Client libraries for NSS and PAM +Group: Applications/System +License: LGPLv3+ +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +Requires(post): /usr/sbin/alternatives +Requires(preun): /usr/sbin/alternatives + +%description client +Provides the libraries needed by the PAM and NSS stacks to connect to the SSSD +service. + +%package -n libsss_sudo +Summary: A library to allow communication between SUDO and SSSD +Group: Development/Libraries +License: LGPLv3+ +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +Conflicts: sssd-common < %{version}-%{release} + +%description -n libsss_sudo +A utility library to allow communication between SUDO and SSSD + +%package -n libsss_autofs +Summary: A library to allow communication between Autofs and SSSD +Group: Development/Libraries +License: LGPLv3+ +Conflicts: sssd-common < %{version}-%{release} + +%description -n libsss_autofs +A utility library to allow communication between Autofs and SSSD + +%package tools +Summary: Userspace tools for use with the SSSD +Group: Applications/System +License: GPLv3+ +Requires: sssd-common = %{version}-%{release} +# required by sss_obfuscate +Requires: python3-sss = %{version}-%{release} +Requires: python3-sssdconfig = %{version}-%{release} + +%description tools +Provides userspace tools for manipulating users, groups, and nested groups in +SSSD when using id_provider = local in /etc/sssd/sssd.conf. + +Also provides several other administrative tools: + * sss_debuglevel to change the debug level on the fly + * sss_seed which pre-creates a user entry for use in kickstarts + * sss_obfuscate for generating an obfuscated LDAP password + * sssctl -- an sssd status and control utility + +%package -n python3-sssdconfig +Summary: SSSD and IPA configuration file manipulation classes and functions +Group: Applications/System +License: GPLv3+ +BuildArch: noarch +%{?python_provide:%python_provide python3-sssdconfig} + +%description -n python3-sssdconfig +Provides python3 files for manipulation SSSD and IPA configuration files. + +%package -n python3-sss +Summary: Python3 bindings for sssd +Group: Development/Libraries +License: LGPLv3+ +Requires: sssd-common = %{version}-%{release} +%{?python_provide:%python_provide python3-sss} + +%description -n python3-sss +Provides python3 module for manipulating users, groups, and nested groups in +SSSD when using id_provider = local in /etc/sssd/sssd.conf. + +Also provides several other useful python3 bindings: + * function for retrieving list of groups user belongs to. + * class for obfuscation of passwords + +%package -n python3-sss-murmur +Summary: Python3 bindings for murmur hash function +Group: Development/Libraries +License: LGPLv3+ +%{?python_provide:%python_provide python3-sss-murmur} + +%description -n python3-sss-murmur +Provides python3 module for calculating the murmur hash version 3 + +%package ldap +Summary: The LDAP back end of the SSSD +Group: Applications/System +License: GPLv3+ +Conflicts: sssd < 1.10.0-8.beta2 +Requires: sssd-common = %{version}-%{release} +Requires: sssd-krb5-common = %{version}-%{release} + +%description ldap +Provides the LDAP back end that the SSSD can utilize to fetch identity data +from and authenticate against an LDAP server. + +%package krb5-common +Summary: SSSD helpers needed for Kerberos and GSSAPI authentication +Group: Applications/System +License: GPLv3+ +Conflicts: sssd < 1.10.0-8.beta2 +Requires: cyrus-sasl-gssapi%{?_isa} +Requires: sssd-common = %{version}-%{release} +Requires(pre): shadow-utils + +%description krb5-common +Provides helper processes that the LDAP and Kerberos back ends can use for +Kerberos user or host authentication. + +%package krb5 +Summary: The Kerberos authentication back end for the SSSD +Group: Applications/System +License: GPLv3+ +Conflicts: sssd < 1.10.0-8.beta2 +Requires: sssd-common = %{version}-%{release} +Requires: sssd-krb5-common = %{version}-%{release} + +%description krb5 +Provides the Kerberos back end that the SSSD can utilize authenticate +against a Kerberos server. + +%package common-pac +Summary: Common files needed for supporting PAC processing +Group: Applications/System +License: GPLv3+ +Requires: sssd-common = %{version}-%{release} + +%description common-pac +Provides common files needed by SSSD providers such as IPA and Active Directory +for handling Kerberos PACs. + +%package ipa +Summary: The IPA back end of the SSSD +Group: Applications/System +License: GPLv3+ +Conflicts: sssd < 1.10.0-8.beta2 +Requires: sssd-common = %{version}-%{release} +Requires: sssd-krb5-common = %{version}-%{release} +Requires: libipa_hbac%{?_isa} = %{version}-%{release} +Recommends: bind-utils +Requires: sssd-common-pac = %{version}-%{release} +Requires(pre): shadow-utils + +%description ipa +Provides the IPA back end that the SSSD can utilize to fetch identity data +from and authenticate against an IPA server. + +%package ad +Summary: The AD back end of the SSSD +Group: Applications/System +License: GPLv3+ +Conflicts: sssd < 1.10.0-8.beta2 +Requires: sssd-common = %{version}-%{release} +Requires: sssd-krb5-common = %{version}-%{release} +Requires: sssd-common-pac = %{version}-%{release} +Recommends: bind-utils +Recommends: adcli +Suggests: sssd-libwbclient = %{version}-%{release} +Suggests: sssd-winbind-idmap = %{version}-%{release} + +%description ad +Provides the Active Directory back end that the SSSD can utilize to fetch +identity data from and authenticate against an Active Directory server. + +%package proxy +Summary: The proxy back end of the SSSD +Group: Applications/System +License: GPLv3+ +Conflicts: sssd < 1.10.0-8.beta2 +Requires: sssd-common = %{version}-%{release} +Requires(pre): shadow-utils + +%description proxy +Provides the proxy back end which can be used to wrap an existing NSS and/or +PAM modules to leverage SSSD caching. + +%package -n libsss_idmap +Summary: FreeIPA Idmap library +Group: Development/Libraries +License: LGPLv3+ +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description -n libsss_idmap +Utility library to convert SIDs to Unix uids and gids + +%package -n libsss_idmap-devel +Summary: FreeIPA Idmap library +Group: Development/Libraries +License: LGPLv3+ +Requires: libsss_idmap = %{version}-%{release} + +%description -n libsss_idmap-devel +Utility library to SIDs to Unix uids and gids + +%package -n libipa_hbac +Summary: FreeIPA HBAC Evaluator library +Group: Development/Libraries +License: LGPLv3+ +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description -n libipa_hbac +Utility library to validate FreeIPA HBAC rules for authorization requests + +%package -n libipa_hbac-devel +Summary: FreeIPA HBAC Evaluator library +Group: Development/Libraries +License: LGPLv3+ +Requires: libipa_hbac = %{version}-%{release} + +%description -n libipa_hbac-devel +Utility library to validate FreeIPA HBAC rules for authorization requests + +%package -n python3-libipa_hbac +Summary: Python3 bindings for the FreeIPA HBAC Evaluator library +Group: Development/Libraries +License: LGPLv3+ +Requires: libipa_hbac = %{version}-%{release} +%{?python_provide:%python_provide python3-libipa_hbac} + +%description -n python3-libipa_hbac +The python3-libipa_hbac contains the bindings so that libipa_hbac can be +used by Python applications. + +%package -n libsss_nss_idmap +Summary: Library for SID and certificate based lookups +Group: Development/Libraries +License: LGPLv3+ +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description -n libsss_nss_idmap +Utility library for SID and certificate based lookups + +%package -n libsss_nss_idmap-devel +Summary: Library for SID and certificate based lookups +Group: Development/Libraries +License: LGPLv3+ +Requires: libsss_nss_idmap = %{version}-%{release} + +%description -n libsss_nss_idmap-devel +Utility library for SID and certificate based lookups + +%package -n python3-libsss_nss_idmap +Summary: Python3 bindings for libsss_nss_idmap +Group: Development/Libraries +License: LGPLv3+ +Requires: libsss_nss_idmap = %{version}-%{release} +%{?python_provide:%python_provide python3-libsss_nss_idmap} + +%description -n python3-libsss_nss_idmap +The python3-libsss_nss_idmap contains the bindings so that libsss_nss_idmap can +be used by Python applications. + +%package dbus +Summary: The D-Bus responder of the SSSD +Group: Applications/System +License: GPLv3+ +Requires: sssd-common = %{version}-%{release} +%{?systemd_requires} + +%description dbus +Provides the D-Bus responder of the SSSD, called the InfoPipe, that allows +the information from the SSSD to be transmitted over the system bus. + +%if (0%{?install_pcscd_polkit_rule} == 1) +%package polkit-rules +Summary: Rules for polkit integration for SSSD +Group: Applications/System +License: GPLv3+ +Requires: polkit >= 0.106 +Requires: sssd-common = %{version}-%{release} + +%description polkit-rules +Provides rules for polkit integration with SSSD. This is required +for smartcard support. +%endif + +%package -n libsss_simpleifp +Summary: The SSSD D-Bus responder helper library +Group: Development/Libraries +License: GPLv3+ +Requires: sssd-dbus = %{version}-%{release} +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description -n libsss_simpleifp +Provides library that simplifies D-Bus API for the SSSD InfoPipe responder. + +%package -n libsss_simpleifp-devel +Summary: The SSSD D-Bus responder helper library +Group: Development/Libraries +License: GPLv3+ +Requires: dbus-devel +Requires: libsss_simpleifp = %{version}-%{release} + +%description -n libsss_simpleifp-devel +Provides library that simplifies D-Bus API for the SSSD InfoPipe responder. + +%package libwbclient +Summary: The SSSD libwbclient implementation +Group: Applications/System +License: GPLv3+ and LGPLv3+ +Conflicts: libwbclient < 4.2.0-0.2.rc2 +Conflicts: sssd-common < %{version}-%{release} + +%description libwbclient +The SSSD libwbclient implementation. + +%package libwbclient-devel +Summary: Development libraries for the SSSD libwbclient implementation +Group: Development/Libraries +License: GPLv3+ and LGPLv3+ +Requires: sssd-libwbclient = %{version}-%{release} +Conflicts: libwbclient-devel < 4.2.0-0.2.rc2 + +%description libwbclient-devel +Development libraries for the SSSD libwbclient implementation. + +%package winbind-idmap +Summary: SSSD's idmap_sss Backend for Winbind +Group: Applications/System +License: GPLv3+ and LGPLv3+ +Conflicts: sssd-common < %{version}-%{release} + +%description winbind-idmap +The idmap_sss module provides a way for Winbind to call SSSD to map UIDs/GIDs +and SIDs. + +%package nfs-idmap +Summary: SSSD plug-in for NFSv4 rpc.idmapd +Group: Applications/System +License: GPLv3+ +Conflicts: sssd-common < %{version}-%{release} + +%description nfs-idmap +The libnfsidmap sssd module provides a way for rpc.idmapd to call SSSD to map +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 +Group: Development/Libraries +License: LGPLv3+ +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig +Conflicts: sssd-common < %{version}-%{release} + +%description -n libsss_certmap +Library to map certificates to users based on rules + +%package -n libsss_certmap-devel +Summary: SSSD Certficate Mapping Library +Group: Development/Libraries +License: LGPLv3+ +Requires: libsss_certmap = %{version}-%{release} + +%description -n libsss_certmap-devel +Library to map certificates to users based on rules + +%package kcm +Summary: An implementation of a Kerberos KCM server +Group: Applications/System +License: GPLv3+ +Requires: sssd-common = %{version}-%{release} +%{?systemd_requires} + +%description kcm +An implementation of a Kerberos KCM server. Use this package if you want to +use the KCM: Kerberos credentials cache. + +%prep +# Update timestamps on the files touched by a patch, to avoid non-equal +# .pyc/.pyo files across the multilib peers within a build, where "Level" +# is the patch prefix option (e.g. -p1) +# Taken from specfile for python-simplejson +UpdateTimestamps() { + Level=$1 + PatchFile=$2 + + # Locate the affected files: + for f in $(diffstat $Level -l $PatchFile); do + # Set the files to have the same timestamp as that of the patch: + touch -r $PatchFile $f + done +} + +%setup -q + +for p in %patches ; do + %__patch -p1 -i $p + UpdateTimestamps -p1 $p +done + +%build +autoreconf -ivf + +%configure \ + --with-test-dir=/dev/shm \ + --with-db-path=%{dbpath} \ + --with-mcache-path=%{mcpath} \ + --with-pipe-path=%{pipepath} \ + --with-pubconf-path=%{pubconfpath} \ + --with-gpo-cache-path=%{gpocachepath} \ + --with-init-dir=%{_initrddir} \ + --with-krb5-rcache-dir=%{_localstatedir}/cache/krb5rcache \ + --enable-nsslibdir=%{_libdir} \ + --enable-pammoddir=%{_libdir}/security \ + --enable-nfsidmaplibdir=%{_libdir}/libnfsidmap \ + --disable-static \ + --with-crypto=libcrypto \ + --disable-rpath \ + --with-initscript=systemd \ + --with-syslog=journald \ + --enable-sss-default-nss-plugin \ + --enable-files-domain \ + --without-python2-bindings \ + --with-sssd-user=sssd \ + %{?with_cifs_utils_plugin_option} \ + %{?enable_systemtap_opt} \ + + +make %{?_smp_mflags} all docs + +%check +export CK_TIMEOUT_MULTIPLIER=10 +make %{?_smp_mflags} check VERBOSE=yes +unset CK_TIMEOUT_MULTIPLIER + +%install + +sed -i -e 's:/usr/bin/python:%{__python3}:' src/tools/sss_obfuscate + +make install DESTDIR=$RPM_BUILD_ROOT + +if [ ! -f $RPM_BUILD_ROOT/%{_libdir}/%{name}/modules/libwbclient.so.%{libwbc_lib_version} ] +then + echo "Expected libwbclient version not found, please check if version has changed." + exit -1 +fi + +# Prepare language files +/usr/lib/rpm/find-lang.sh $RPM_BUILD_ROOT sssd + +# Copy default logrotate file +mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/logrotate.d +install -m644 src/examples/logrotate $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/sssd + +# Make sure SSSD is able to run on read-only root +mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/rwtab.d +install -m644 src/examples/rwtab $RPM_BUILD_ROOT%{_sysconfdir}/rwtab.d/sssd + +# Kerberos KCM credential cache by default +mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/krb5.conf.d +cp $RPM_BUILD_ROOT/%{_datadir}/sssd-kcm/kcm_default_ccache \ + $RPM_BUILD_ROOT/%{_sysconfdir}/krb5.conf.d/kcm_default_ccache + +# Create directory for cifs-idmap alternative +# Otherwise this directory could not be owned by sssd-client +mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/cifs-utils + +# Remove .la files created by libtool +find $RPM_BUILD_ROOT -name "*.la" -exec rm -f {} \; + +# Suppress developer-only documentation +rm -Rf ${RPM_BUILD_ROOT}/%{_docdir}/%{name} + +# Older versions of rpmbuild can only handle one -f option +# So we need to append to the sssd*.lang file +for file in `ls $RPM_BUILD_ROOT/%{python3_sitelib}/*.egg-info 2> /dev/null` +do + echo %{python3_sitelib}/`basename $file` >> python3_sssdconfig.lang +done + +touch sssd.lang +for subpackage in sssd_ldap sssd_krb5 sssd_ipa sssd_ad sssd_proxy sssd_tools \ + sssd_client sssd_dbus sssd_nfs_idmap sssd_winbind_idmap \ + libsss_certmap sssd_kcm +do + touch $subpackage.lang +done + +for man in `find $RPM_BUILD_ROOT/%{_mandir}/??/man?/ -type f | sed -e "s#$RPM_BUILD_ROOT/%{_mandir}/##"` +do + lang=`echo $man | cut -c 1-2` + case `basename $man` in + sss_cache*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd.lang + ;; + sss_ssh*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd.lang + ;; + sss_rpcidmapd*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_nfs_idmap.lang + ;; + sss_*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_tools.lang + ;; + sssctl*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_tools.lang + ;; + sssd_krb5_*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_client.lang + ;; + pam_sss*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_client.lang + ;; + sssd-ldap*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_ldap.lang + ;; + sssd-krb5*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_krb5.lang + ;; + sssd-ipa*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_ipa.lang + ;; + sssd-ad*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_ad.lang + ;; + sssd-proxy*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_proxy.lang + ;; + sssd-ifp*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_dbus.lang + ;; + sssd-kcm*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_kcm.lang + ;; + idmap_sss*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd_winbind_idmap.lang + ;; + sss-certmap*) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> libsss_certmap.lang + ;; + *) + echo \%lang\(${lang}\) \%{_mandir}/${man}\* >> sssd.lang + ;; + esac +done + +# Print these to the rpmbuild log +echo "sssd.lang:" +cat sssd.lang + +echo "python3_sssdconfig.lang:" +cat python3_sssdconfig.lang + +for subpackage in sssd_ldap sssd_krb5 sssd_ipa sssd_ad sssd_proxy sssd_tools \ + sssd_client sssd_dbus sssd_nfs_idmap sssd_winbind_idmap \ + libsss_certmap sssd_kcm +do + echo "$subpackage.lang:" + cat $subpackage.lang +done + +%files +%defattr(-,root,root,-) +%license COPYING + +%files common -f sssd.lang +%defattr(-,root,root,-) +%license COPYING +%doc src/examples/sssd-example.conf +%{_sbindir}/sssd +%{_unitdir}/sssd.service +%{_unitdir}/sssd-autofs.socket +%{_unitdir}/sssd-autofs.service +%{_unitdir}/sssd-nss.socket +%{_unitdir}/sssd-nss.service +%{_unitdir}/sssd-pac.socket +%{_unitdir}/sssd-pac.service +%{_unitdir}/sssd-pam.socket +%{_unitdir}/sssd-pam-priv.socket +%{_unitdir}/sssd-pam.service +%{_unitdir}/sssd-ssh.socket +%{_unitdir}/sssd-ssh.service +%{_unitdir}/sssd-sudo.socket +%{_unitdir}/sssd-sudo.service + +%dir %{_libexecdir}/%{servicename} +%{_libexecdir}/%{servicename}/sssd_be +%{_libexecdir}/%{servicename}/sssd_nss +%{_libexecdir}/%{servicename}/sssd_pam +%{_libexecdir}/%{servicename}/sssd_autofs +%{_libexecdir}/%{servicename}/sssd_ssh +%{_libexecdir}/%{servicename}/sssd_sudo +%{_libexecdir}/%{servicename}/p11_child +%{_libexecdir}/%{servicename}/sssd_check_socket_activated_responders + +%dir %{_libdir}/%{name} +# The files provider is intentionally packaged in -common +%{_libdir}/%{name}/libsss_files.so +%{_libdir}/%{name}/libsss_simple.so + +#Internal shared libraries +%{_libdir}/%{name}/libsss_child.so +%{_libdir}/%{name}/libsss_crypt.so +%{_libdir}/%{name}/libsss_cert.so +%{_libdir}/%{name}/libsss_debug.so +%{_libdir}/%{name}/libsss_krb5_common.so +%{_libdir}/%{name}/libsss_ldap_common.so +%{_libdir}/%{name}/libsss_util.so +%{_libdir}/%{name}/libsss_semanage.so +%{_libdir}/%{name}/libifp_iface.so +%{_libdir}/%{name}/libifp_iface_sync.so +%{_libdir}/%{name}/libsss_iface.so +%{_libdir}/%{name}/libsss_iface_sync.so +%{_libdir}/%{name}/libsss_sbus.so +%{_libdir}/%{name}/libsss_sbus_sync.so + +%{ldb_modulesdir}/memberof.so +%{_bindir}/sss_ssh_authorizedkeys +%{_bindir}/sss_ssh_knownhostsproxy +%{_sbindir}/sss_cache +%{_libexecdir}/%{servicename}/sss_signal + +%dir %{sssdstatedir} +%dir %{_localstatedir}/cache/krb5rcache +%attr(700,sssd,sssd) %dir %{dbpath} +%attr(755,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 +%attr(755,sssd,sssd) %dir %{pipepath} +%attr(750,sssd,root) %dir %{pipepath}/private +%attr(755,sssd,sssd) %dir %{pubconfpath} +%attr(755,sssd,sssd) %dir %{gpocachepath} +%attr(750,sssd,sssd) %dir %{_var}/log/%{name} +%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 +%dir %{_sysconfdir}/logrotate.d +%config(noreplace) %{_sysconfdir}/logrotate.d/sssd +%dir %{_sysconfdir}/rwtab.d +%config(noreplace) %{_sysconfdir}/rwtab.d/sssd +%dir %{_datadir}/sssd +%{_sysconfdir}/pam.d/sssd-shadowutils +%dir %{_libdir}/%{name}/conf +%{_libdir}/%{name}/conf/sssd.conf + +%{_datadir}/sssd/cfg_rules.ini +%{_datadir}/sssd/sssd.api.conf +%{_datadir}/sssd/sssd.api.d +%{_mandir}/man1/sss_ssh_authorizedkeys.1* +%{_mandir}/man1/sss_ssh_knownhostsproxy.1* +%{_mandir}/man5/sssd.conf.5* +%{_mandir}/man5/sssd-files.5* +%{_mandir}/man5/sssd-simple.5* +%{_mandir}/man5/sssd-sudo.5* +%{_mandir}/man5/sssd-session-recording.5* +%{_mandir}/man8/sssd.8* +%{_mandir}/man8/sss_cache.8* +%dir %{_datadir}/sssd/systemtap +%{_datadir}/sssd/systemtap/id_perf.stp +%{_datadir}/sssd/systemtap/nested_group_perf.stp +%{_datadir}/sssd/systemtap/dp_request.stp +%dir %{_datadir}/systemtap +%dir %{_datadir}/systemtap/tapset +%{_datadir}/systemtap/tapset/sssd.stp +%{_datadir}/systemtap/tapset/sssd_functions.stp +%{_mandir}/man5/sssd-systemtap.5* + +%if (0%{?install_pcscd_polkit_rule} == 1) +%files polkit-rules +%{_datadir}/polkit-1/rules.d/* +%endif + +%files ldap -f sssd_ldap.lang +%defattr(-,root,root,-) +%license COPYING +%{_libdir}/%{name}/libsss_ldap.so +%{_mandir}/man5/sssd-ldap.5* + +%files krb5-common +%defattr(-,root,root,-) +%license COPYING +%attr(755,sssd,sssd) %dir %{pubconfpath}/krb5.include.d +%attr(4750,root,sssd) %{_libexecdir}/%{servicename}/ldap_child +%attr(4750,root,sssd) %{_libexecdir}/%{servicename}/krb5_child + +%files krb5 -f sssd_krb5.lang +%defattr(-,root,root,-) +%license COPYING +%{_libdir}/%{name}/libsss_krb5.so +%{_mandir}/man5/sssd-krb5.5* + +%files common-pac +%defattr(-,root,root,-) +%license COPYING +%{_libexecdir}/%{servicename}/sssd_pac + +%files ipa -f sssd_ipa.lang +%defattr(-,root,root,-) +%license COPYING +%attr(700,sssd,sssd) %dir %{keytabdir} +%{_libdir}/%{name}/libsss_ipa.so +%attr(4750,root,sssd) %{_libexecdir}/%{servicename}/selinux_child +%{_mandir}/man5/sssd-ipa.5* + +%files ad -f sssd_ad.lang +%defattr(-,root,root,-) +%license COPYING +%{_libdir}/%{name}/libsss_ad.so +%{_libexecdir}/%{servicename}/gpo_child +%{_mandir}/man5/sssd-ad.5* + +%files proxy +%defattr(-,root,root,-) +%license COPYING +%attr(4750,root,sssd) %{_libexecdir}/%{servicename}/proxy_child +%{_libdir}/%{name}/libsss_proxy.so + +%files dbus -f sssd_dbus.lang +%defattr(-,root,root,-) +%license COPYING +%{_libexecdir}/%{servicename}/sssd_ifp +%{_mandir}/man5/sssd-ifp.5* +%{_unitdir}/sssd-ifp.service +# InfoPipe DBus plumbing +%{_sysconfdir}/dbus-1/system.d/org.freedesktop.sssd.infopipe.conf +%{_datadir}/dbus-1/system-services/org.freedesktop.sssd.infopipe.service + +%files -n libsss_simpleifp +%defattr(-,root,root,-) +%{_libdir}/libsss_simpleifp.so.* + +%files -n libsss_simpleifp-devel +%defattr(-,root,root,-) +%doc sss_simpleifp_doc/html +%{_includedir}/sss_sifp.h +%{_includedir}/sss_sifp_dbus.h +%{_libdir}/libsss_simpleifp.so +%{_libdir}/pkgconfig/sss_simpleifp.pc + +%files client -f sssd_client.lang +%defattr(-,root,root,-) +%license src/sss_client/COPYING src/sss_client/COPYING.LESSER +%{_libdir}/libnss_sss.so.2 +%{_libdir}/security/pam_sss.so +%{_libdir}/krb5/plugins/libkrb5/sssd_krb5_locator_plugin.so +%{_libdir}/krb5/plugins/authdata/sssd_pac_plugin.so +%dir %{_libdir}/cifs-utils +%{_libdir}/cifs-utils/cifs_idmap_sss.so +%dir %{_sysconfdir}/cifs-utils +%ghost %{_sysconfdir}/cifs-utils/idmap-plugin +%dir %{_libdir}/%{name} +%dir %{_libdir}/%{name}/modules +%{_libdir}/%{name}/modules/sssd_krb5_localauth_plugin.so +%{_mandir}/man8/pam_sss.8* +%{_mandir}/man8/sssd_krb5_locator_plugin.8* + +%files -n libsss_sudo +%defattr(-,root,root,-) +%license src/sss_client/COPYING +%{_libdir}/libsss_sudo.so* + +%files -n libsss_autofs +%defattr(-,root,root,-) +%license src/sss_client/COPYING src/sss_client/COPYING.LESSER +%dir %{_libdir}/%{name}/modules +%{_libdir}/%{name}/modules/libsss_autofs.so + +%files tools -f sssd_tools.lang +%defattr(-,root,root,-) +%license COPYING +%{_sbindir}/sss_obfuscate +%{_sbindir}/sss_override +%{_sbindir}/sss_debuglevel +%{_sbindir}/sss_seed +%{_sbindir}/sssctl +%{_mandir}/man8/sss_obfuscate.8* +%{_mandir}/man8/sss_override.8* +%{_mandir}/man8/sss_debuglevel.8* +%{_mandir}/man8/sss_seed.8* +%{_mandir}/man8/sssctl.8* + +%files -n python3-sssdconfig -f python3_sssdconfig.lang +%defattr(-,root,root,-) +%dir %{python3_sitelib}/SSSDConfig +%{python3_sitelib}/SSSDConfig/*.py* +%dir %{python3_sitelib}/SSSDConfig/__pycache__ +%{python3_sitelib}/SSSDConfig/__pycache__/*.py* + +%files -n python3-sss +%defattr(-,root,root,-) +%{python3_sitearch}/pysss.so + +%files -n python3-sss-murmur +%defattr(-,root,root,-) +%{python3_sitearch}/pysss_murmur.so + +%files -n libsss_idmap +%defattr(-,root,root,-) +%license src/sss_client/COPYING src/sss_client/COPYING.LESSER +%{_libdir}/libsss_idmap.so.* + +%files -n libsss_idmap-devel +%defattr(-,root,root,-) +%doc idmap_doc/html +%{_includedir}/sss_idmap.h +%{_libdir}/libsss_idmap.so +%{_libdir}/pkgconfig/sss_idmap.pc + +%files -n libipa_hbac +%defattr(-,root,root,-) +%license src/sss_client/COPYING src/sss_client/COPYING.LESSER +%{_libdir}/libipa_hbac.so.* + +%files -n libipa_hbac-devel +%defattr(-,root,root,-) +%doc hbac_doc/html +%{_includedir}/ipa_hbac.h +%{_libdir}/libipa_hbac.so +%{_libdir}/pkgconfig/ipa_hbac.pc + +%files -n libsss_nss_idmap +%defattr(-,root,root,-) +%license src/sss_client/COPYING src/sss_client/COPYING.LESSER +%{_libdir}/libsss_nss_idmap.so.* + +%files -n libsss_nss_idmap-devel +%defattr(-,root,root,-) +%doc nss_idmap_doc/html +%{_includedir}/sss_nss_idmap.h +%{_libdir}/libsss_nss_idmap.so +%{_libdir}/pkgconfig/sss_nss_idmap.pc + +%files -n python3-libsss_nss_idmap +%defattr(-,root,root,-) +%{python3_sitearch}/pysss_nss_idmap.so + +%files -n python3-libipa_hbac +%defattr(-,root,root,-) +%{python3_sitearch}/pyhbac.so + +%files libwbclient +%defattr(-,root,root,-) +%dir %{_libdir}/%{name} +%dir %{_libdir}/%{name}/modules +%{_libdir}/%{name}/modules/libwbclient.so.* + +%files libwbclient-devel +%defattr(-,root,root,-) +%{_includedir}/wbclient_sssd.h +%{_libdir}/%{name}/modules/libwbclient.so +%{_libdir}/pkgconfig/wbclient_sssd.pc + +%files winbind-idmap -f sssd_winbind_idmap.lang +%dir %{_libdir}/samba/idmap +%{_libdir}/samba/idmap/sss.so +%{_mandir}/man8/idmap_sss.8* + +%files nfs-idmap -f sssd_nfs_idmap.lang +%{_mandir}/man5/sss_rpcidmapd.5* +%{_libdir}/libnfsidmap/sss.so + +%files -n libsss_certmap -f libsss_certmap.lang +%defattr(-,root,root,-) +%license src/sss_client/COPYING src/sss_client/COPYING.LESSER +%{_libdir}/libsss_certmap.so.* +%{_mandir}/man5/sss-certmap.5* + +%files -n libsss_certmap-devel +%defattr(-,root,root,-) +%doc certmap_doc/html +%{_includedir}/sss_certmap.h +%{_libdir}/libsss_certmap.so +%{_libdir}/pkgconfig/sss_certmap.pc + +%files kcm -f sssd_kcm.lang +%{_libexecdir}/%{servicename}/sssd_kcm +%config(noreplace) %{_sysconfdir}/krb5.conf.d/kcm_default_ccache +%dir %{_datadir}/sssd-kcm +%{_datadir}/sssd-kcm/kcm_default_ccache +%{_unitdir}/sssd-kcm.socket +%{_unitdir}/sssd-kcm.service +%{_mandir}/man8/sssd-kcm.8* +%{_libdir}/%{name}/libsss_secrets.so + +%pre ipa +getent group sssd >/dev/null || groupadd -r sssd +getent passwd sssd >/dev/null || useradd -r -g sssd -d / -s /sbin/nologin -c "User for sssd" sssd + +%pre krb5-common +getent group sssd >/dev/null || groupadd -r sssd +getent passwd sssd >/dev/null || useradd -r -g sssd -d / -s /sbin/nologin -c "User for sssd" sssd + +%pre common +getent group sssd >/dev/null || groupadd -r sssd +getent passwd sssd >/dev/null || useradd -r -g sssd -d / -s /sbin/nologin -c "User for sssd" sssd + +%pre proxy +getent group sssd >/dev/null || groupadd -r sssd +getent passwd sssd >/dev/null || useradd -r -g sssd -d / -s /sbin/nologin -c "User for sssd" sssd + +%post common +%systemd_post sssd.service +%systemd_post sssd-autofs.socket +%systemd_post sssd-nss.socket +%systemd_post sssd-pac.socket +%systemd_post sssd-pam.socket +%systemd_post sssd-pam-priv.socket +%systemd_post sssd-ssh.socket +%systemd_post sssd-sudo.socket + +%preun common +%systemd_preun sssd.service +%systemd_preun sssd-autofs.socket +%systemd_preun sssd-nss.socket +%systemd_preun sssd-pac.socket +%systemd_preun sssd-pam.socket +%systemd_preun sssd-pam-priv.socket +%systemd_preun sssd-ssh.socket +%systemd_preun sssd-sudo.socket + +%postun common +%systemd_postun_with_restart sssd-autofs.socket +%systemd_postun_with_restart sssd-autofs.service +%systemd_postun_with_restart sssd-nss.socket +%systemd_postun_with_restart sssd-nss.service +%systemd_postun_with_restart sssd-pac.socket +%systemd_postun_with_restart sssd-pac.service +%systemd_postun_with_restart sssd-pam.socket +%systemd_postun_with_restart sssd-pam-priv.socket +%systemd_postun_with_restart sssd-pam.service +%systemd_postun_with_restart sssd-ssh.socket +%systemd_postun_with_restart sssd-ssh.service +%systemd_postun_with_restart sssd-sudo.socket +%systemd_postun_with_restart sssd-sudo.service + +%post dbus +%systemd_post sssd-ifp.service + +%preun dbus +%systemd_preun sssd-ifp.service + +%postun dbus +%systemd_postun_with_restart sssd-ifp.service + +%post kcm +%systemd_post sssd-kcm.socket + +%preun kcm +%systemd_preun sssd-kcm.socket + +%postun kcm +%systemd_postun_with_restart sssd-kcm.socket +%systemd_postun_with_restart sssd-kcm.service + +%post client +/sbin/ldconfig +/usr/sbin/alternatives --install /etc/cifs-utils/idmap-plugin cifs-idmap-plugin %{_libdir}/cifs-utils/cifs_idmap_sss.so 20 + +%preun client +if [ $1 -eq 0 ] ; then + /usr/sbin/alternatives --remove cifs-idmap-plugin %{_libdir}/cifs-utils/cifs_idmap_sss.so +fi + +%postun client -p /sbin/ldconfig + +%post -n libsss_sudo -p /sbin/ldconfig + +%postun -n libsss_sudo -p /sbin/ldconfig + +%post -n libipa_hbac -p /sbin/ldconfig + +%postun -n libipa_hbac -p /sbin/ldconfig + +%post -n libsss_idmap -p /sbin/ldconfig + +%postun -n libsss_idmap -p /sbin/ldconfig + +%post -n libsss_nss_idmap -p /sbin/ldconfig + +%postun -n libsss_nss_idmap -p /sbin/ldconfig + +%post -n libsss_simpleifp -p /sbin/ldconfig + +%postun -n libsss_simpleifp -p /sbin/ldconfig + +%post -n libsss_certmap -p /sbin/ldconfig + +%postun -n libsss_certmap -p /sbin/ldconfig + +%posttrans common +%systemd_postun_with_restart sssd.service + +%posttrans libwbclient +%{_sbindir}/update-alternatives \ + --install %{_libdir}/libwbclient.so.%{libwbc_alternatives_version} \ + libwbclient.so.%{libwbc_alternatives_version}%{libwbc_alternatives_suffix} \ + %{_libdir}/%{name}/modules/libwbclient.so.%{libwbc_lib_version} 5 +/sbin/ldconfig + +%preun libwbclient +%{_sbindir}/update-alternatives \ + --remove libwbclient.so.%{libwbc_alternatives_version}%{libwbc_alternatives_suffix} \ + %{_libdir}/%{name}/modules/libwbclient.so.%{libwbc_lib_version} +/sbin/ldconfig + +%posttrans libwbclient-devel +%{_sbindir}/update-alternatives --install %{_libdir}/libwbclient.so \ + libwbclient.so%{libwbc_alternatives_suffix} \ + %{_libdir}/%{name}/modules/libwbclient.so 5 + +%preun libwbclient-devel +%{_sbindir}/update-alternatives --remove \ + libwbclient.so%{libwbc_alternatives_suffix} \ + %{_libdir}/%{name}/modules/libwbclient.so + +%changelog +* Sun Feb 10 2019 Jakub Hrozek - 2.0.0-43 +- Resolves: rhbz#1672780 - gdm login not prompting for username when smart + card maps to multiple users + +* Fri Feb 08 2019 Michal Židek - 2.0.0-42 +- Resolves: rhbz#1645291 - Perform some basic ccache initialization as part + of gen_new to avoid a subsequent switch call + failure + +* Thu Feb 07 2019 Michal Židek - 2.0.0-41 +-Resolves: rhbz#1659498 - Re-setting the trusted AD domain fails due to wrong + subdomain service name being used + +* Thu Feb 07 2019 Michal Židek - 2.0.0-40 +-Resolves: rhbz#1660083 - extraAttributes is org.freedesktop.DBus.Error. + UnknownProperty: Unknown property + +* Thu Feb 07 2019 Michal Židek - 2.0.0-39 +- Resolves: rhbz#1661183 - SSSD 2.0 has drastically lower sbus timeout than + 1.x, this can result in time outs + +* Mon Jan 14 2019 Michal Židek - 2.0.0-38 +- Resolves: rhbz#1578014 - sssd does not work under non-root user +- Note: Actually the patches were in the 2.0.0-37, this one just adds this + changelog because it was missing. + +* Fri Jan 11 2019 Michal Židek - 2.0.0-36 +- Resolves: rhbz#1652563 - incorrect example in the man page of idmap_sss + suggests using * for backend sss + +* Fri Jan 11 2019 Michal Židek - 2.0.0-35 +- Resolves: rhbz#1466503 - Snippets are not used when sssd.conf does not exist + +* Thu Jan 10 2019 Michal Židek - 2.0.0-34 +- Resolves: rhbz#1622008 - Error message when IPA server uninstall calls + kdestroy caused by KCM returning a wrong error + code during the delete operation + +* Wed Jan 09 2019 Michal Židek - 2.0.0-33 +- Resolves: rhbz#1646113 - Missing concise documentation about valid options + for sssd-files-provider + +* Mon Dec 17 2018 Michal Židek - 2.0.0-32 +- Resolves: rhbz#1625670 - sssd needs to require a newer version of libtalloc + and libtevent to avoid an issue in GPO processing + +* Sun Dec 16 2018 Michal Židek - 2.0.0-31 +- Resolves: 1658813 - PKINIT with KCM does not work + +* Sun Dec 16 2018 Michal Židek - 2.0.0-30 +- Resolves: 1657898 - SSSD must be cleared/restarted periodically in order to + retrieve AD users through IPA Trust + +* Sun Dec 16 2018 Michal Židek - 2.0.0-29 +- Resolves: rhbz#1655459 - [abrt] [faf] sssd: raise(): + /usr/libexec/sssd/proxy_child killed by 6 + +* Sun Dec 16 2018 Michal Židek - 2.0.0-28 +- Resolves: rhbz#1652719 - [SECURITY] sssd returns '/' for emtpy home directories + +* Tue Dec 11 2018 Michal Židek - 2.0.0-27 +- Resolves: rhbz#1657979 - SSSD's LDAP authentication provider does not work + if ID provider is authenticated with GSSAPI + +* Tue Dec 11 2018 Michal Židek - 2.0.0-26 +- Resolves: rhbz#1657980 - sssd_nss memory leak + +* Tue Dec 11 2018 Michal Židek - 2.0.0-25 +- Resolves: rhbz#1645566 - SSSD 2.x does not sanitize domain name properly + for D-bus, resulting in a crash + +* Tue Dec 04 2018 Michal Židek - 2.0.0-24 +- Resolves: rhbz#1646168 - sssctl access-report always prints an error message +- Resolves: rhbz#1643053 - Restarting the sssd-kcm service should reload the + configuration without having to restart the whole + sssd +- Resolves: rhbz#1640576 - sssctl reports incorrect information about local + user's cache entry expiration time +- Resolves: rhbz#1645238 - Unable to su to root when logged in as a local user +- Resolves: rhbz#1639411 - sssd support for for smartcards using ECC keys + +* Thu Oct 25 2018 Jakub Hrozek - 2.0.0-23 +- Resolves: rhbz#1642508 - sssd ifp crash when trying to access ipa webui + with smart card + +* Wed Oct 24 2018 Jakub Hrozek - 2.0.0-22 +- Resolves: rhbz#1642372 - SSSD Python getgrouplist API was removed but required for IPA + +* Tue Oct 16 2018 Jakub Hrozek - 2.0.0-21 +- Related: rhbz#1638150 - session not recording for local user when groups defined +- Also add silence a Coverity warning, which is related to rhbz#1637131 + +* Mon Oct 15 2018 Jakub Hrozek - 2.0.0-20 +- Related: rhbz#1637513 - sssd crashes when refreshing expired sudo rules + +* Mon Oct 15 2018 Jakub Hrozek - 2.0.0-19 +- Add OSCP checks for p11_child +- Related: rhbz#1615417 - [RFE] Add Smart Card authentication for local + users + +* Mon Oct 15 2018 Jakub Hrozek - 2.0.0-18 +- Related: rhbz#1638006 - Files: The files provider always enumerates + which causes duplicate when running getent passwd + +* Thu Oct 11 2018 Jakub Hrozek - 2.0.0-17 +- Related: rhbz#1637131 - pam_unix unable to match fully qualified username + provided by sssd during smartcard auth using gdm + +* Thu Oct 11 2018 Jakub Hrozek - 2.0.0-16 +- Related: rhbz#1620123 - [RFE] Add option to specify a Smartcard with a + PKCS#11 URI + +* Thu Oct 11 2018 Jakub Hrozek - 2.0.0-15 +- Related: rhbz#1611011 - Support for "require smartcard for login option" + +* Thu Oct 11 2018 Jakub Hrozek - 2.0.0-14 +- Related: rhbz#1635595 - Cant login with smartcard with multiple certs + +* Thu Oct 11 2018 Jakub Hrozek - 2.0.0-13 +- Backport more sbus2 fixes +- Related: rhbz#1623878 - crash related to sbus_router_destructor() + +* Wed Oct 10 2018 Jakub Hrozek - 2.0.0-12 +- Resolves: rhbz#1636397 - SSSD not fetching all sudo rules from AD + +* Wed Oct 3 2018 Jakub Hrozek - 2.0.0-11 +- Resolves: rhbz#1628122 - Printing incorrect information about domain + with sssctl utility + +* Wed Oct 3 2018 Jakub Hrozek - 2.0.0-10 +- Resolves: rhbz#1626001 - SSSD should log to syslog if a domain is not + started due to a misconfiguration + +* Wed Oct 3 2018 Jakub Hrozek - 2.0.0-9 +- Resolves: rhbz#1624785 - Remove references of sss_user/group/add/del + commands in man pages since local provider + is deprecated + +* Wed Oct 3 2018 Jakub Hrozek - 2.0.0-8 +- Resolves: rhbz#1628126 - [abrt] [faf] sssd: unknown function(): + /usr/libexec/sssd/sssd_be killed by 11 crash + func _dbus_list_unlink + +* Wed Oct 3 2018 Jakub Hrozek - 2.0.0-7 +- Resolves: rhbz#1628503 - sssd only sets the SELinux login context if it + differs from the default + +* Wed Sep 26 2018 Jakub Hrozek - 2.0.0-6 +- Resolves: rhbz#1625842 id_provider= local causes SSSD to abort startup + +* Tue Sep 25 2018 Jakub Hrozek - 2.0.0-5 +- Resolves: rhbz#1615590 - Do not rely on "python" for el8 + +* Tue Sep 25 2018 Jakub Hrozek - 2.0.0-4 +- Resolves: rhbz#1615417 - [RFE] Add Smart Card authentication for local + users + +* Tue Sep 11 2018 Jakub Hrozek - 2.0.0-3 +- Resolves: rhbz#1623878 - crash related to sbus_router_destructor() + +* Thu Aug 30 2018 Jakub Hrozek - 2.0.0-2 +- Resolves: rhbz#1622026 - sssd 2.0 regression: Kerberos authentication + fails with the KCM ccache + +* Mon Aug 13 2018 Fabiano Fidêncio - 2.0.0-1 +- Resolves: rhbz#1615460 - Rebase SSSD to the latest released version + +* Tue Jul 03 2018 Tomas Orsava - 1.16.2-2 +- Switch hardcoded python3 shebangs into the %%{__python3} macro + +* Thu Jun 14 2018 Fabiano Fidêncio - 1.16.2-1 +- Update to 1.16.2 release +- Cleanup unused global definitions +- Remove python2 references from the spec file +- Resolves: rhbz#1585313 - Kerberos with sssd-kcm is not working on s390x + +* Fri Apr 27 2018 Fabiano Fidêncio - 1.16.1-3 +- Resolves: upstream#3684 - A group is not updated if its member is removed + with the cleanup task, but the group does not + change +- Resolves: upstream#3558 - sudo: report error when two rules share cn +- Tone down shutdown messages for socket activated responders +- IPA: Qualify the externalUser sudo attribute +- Resolves: upstream#3550 - refresh_expired_interval does not work with + netgrous in 1.15 +- Resolves: upstream#3402 - Support alternative sources for the files provider +- Resolves: upstream#3646 - SSSD's GPO code ignores ad_site option +- Resolves: upstream#3679 - Make nss netgroup requests more robust +- Resolves: upstream#3634 - sssctl COMMAND --help fails if sssd is not + configured +- Resolves: upstream#3469 - extend sss-certmap man page regarding priority + processing +- Improve docs/debug message about GC detection +- Resolves: upstream#3715 - ipa 389-ds-base crash in krb5-libs - k5_copy_etypes + list out of bound? +- Resolves: upstream#2653 - Group renaming issue when "id_provider = ldap" is + set. +- Document which principal does the AD provider use +- Resolves: upstream#3680 - GPO: SSSD fails to process GPOs If a rule is + defined, but contains no SIDs +- Resolves: upstream#3520 - Files provider supports only BE_FILTER_ENUM +- Resolves: rhbz#1540703 - FreeIPA/SSSD implicit_file sssd_nss error: The Data + Provider returned an error + [org.freedesktop.sssd.Error.DataProvider.Fatal] + +* Fri Mar 30 2018 Fabiano Fidêncio - 1.16.1-2 +- Resolves: upstream#3573 - sssd won't show netgroups with blank domain +- Resolves: upstream#3660 - confdb_expand_app_domains() always fails +- Resolves: upstream#3658 - Application domain is not interpreted correctly +- Resolves: upstream#3687 - KCM: Don't pass a non null terminated string to + json_loads() +- Resolves: upstream#3386 - KCM: Payload buffer is too small +- Resolves: upstream#3666 - Fix usage of str.decode() in our tests +- A few KCM misc fixes + +* Fri Mar 9 2018 Fabiano Fidêncio - 1.16.1-1 +- New upstream release 1.16.1 +- https://docs.pagure.org/SSSD.sssd/users/relnotes/notes_1_16_1.html + +* Tue Feb 20 2018 Lukas Slebodnik - 1.16.0-13 +- Resolves: upstream#3621 - backport bug found by static analyzers + +* Wed Feb 14 2018 Fabiano Fidêncio - 1.16.0-12 +- Resolves: rhbz#1538643 - SSSD crashes when retrieving a Desktop Profile + with no specific host/hostgroup set +- Resolves: upstream#3621 - FleetCommander integration must not require + capability DAC_OVERRIDE + +* Wed Feb 07 2018 Lukas Slebodnik - 1.16.0-11 +- Resolves: upstream#3618 - selinux_child segfaults in a docker container + +* Tue Feb 06 2018 Lukas Slebodnik - 1.16.0-10 +- Resolves: rhbz#1431153 - sssd: libsss_proxy.so needs to be linked with -ldl + +* Thu Jan 25 2018 Igor Gnatenko - 1.16.0-9 +- Fix systemd executions/requirements + +* Thu Jan 25 2018 Lukas Slebodnik - 1.16.0-8 +- Fix building on rawhide. Remove -Wl,-z,defs from LDFLAGS + +* Thu Jan 11 2018 Lukas Slebodnik - 1.16.0-7 +- Fix building of sssd-nfs-idmap with libnfsidmap.so.1 + +* Thu Jan 11 2018 Björn Esser - 1.16.0-6 +- Rebuilt for libnfsidmap.so.1 + +* Mon Dec 04 2017 Lukas Slebodnik - 1.16.0-5 +- Resolves: upstream#3523 - ABRT crash - /usr/libexec/sssd/sssd_nss in + setnetgrent_result_timeout +- Resolves: upstream#3588 - sssd_nss consumes more memory until restarted + or machine swaps +- Resolves: failure in glibc tests + https://sourceware.org/bugzilla/show_bug.cgi?id=22530 +- Resolves: upstream#3451 - When sssd is configured with id_provider proxy and + auth_provider ldap, login fails if the LDAP server + is not allowing anonymous binds +- Resolves: upstream#3285 - SSSD needs restart after incorrect clock is + corrected with AD +- Resolves: upstream#3586 - Give a more detailed debug and system-log message + if krb5_init_context() failed +- Resolves: rhbz#1431153 - SSSD ships a drop-in configuration snippet + in /etc/systemd/system +- Backport few upstream features from 1.16.1 + +* Tue Nov 21 2017 Lukas Slebodnik - 1.16.0-4 +- Resolves: rhbz#1494002 - sssd_nss crashed in cache_req_search_domains_next + +* Fri Nov 17 2017 Jakub Hrozek - 1.16.0-3 +- Backport extended NSS API from upstream master branch + +* Fri Nov 03 2017 Lukas Slebodnik - 1.16.0-2 +- Resolves: upstream#3529 - sssd-kcm Fix restart during/after upgrade + +* Fri Oct 20 2017 Lukas Slebodnik - 1.16.0-1 +- New upstream release 1.16.0 +- https://docs.pagure.org/SSSD.sssd/users/relnotes/notes_1_16_0.html + +* Wed Oct 11 2017 Lukas Slebodnik - 1.15.3-5 +- Resolves: rhbz#1499354 - CVE-2017-12173 sssd: unsanitized input when + searching in local cache database access on + the sock_file system_bus_socket + +* Mon Sep 11 2017 Lukas Slebodnik - 1.15.3-4 +- Resolves: rhbz#1488327 - SELinux is preventing selinux_child from write + access on the sock_file system_bus_socket +- Resolves: rhbz#1490402 - SSSD does not create /var/lib/sss/deskprofile and + fails to download desktop profile data +- Resolves: upstream#3485 - getsidbyid does not work with 1.15.3 +- Resolves: upstream#3488 - SUDO doesn't work for IPA users on IPA clients + after applying ID Views for them in IPA server +- Resolves: upstream#3501 - Accessing IdM kerberos ticket fails while id + mapping is applied + +* Fri Sep 01 2017 Lukas Slebodnik - 1.15.3-3 +- Backport few upstream patches/fixes + +* Thu Jul 27 2017 Fedora Release Engineering - 1.15.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Tue Jul 25 2017 Lukas Slebodnik - 1.15.3-1 +- New upstream release 1.15.3 +- https://docs.pagure.org/SSSD.sssd/users/relnotes/notes_1_15_3.html + +* Tue Jun 27 2017 Lukas Slebodnik - 1.15.3-0.beta.5 +- Rebuild with libldb-1.2.0 + +* Tue Jun 27 2017 Lukas Slebodnik - 1.15.3-0.beta.4 +- Fix build issues: Update expided certificate in unit tests + +* Sat Apr 29 2017 Lukas Slebodnik - 1.15.3-0.beta.3 +- Resolves: rhbz#1445680 - Properly fall back to local Smartcard authentication +- Resolves: rhbz#1437199 - sssd-nfs-idmap-1.15.2-1.fc25.x86_64 conflicts with + file from package sssd-common-1.15.1-1.fc25.x86_64 +- Resolves: rhbz#1063278 - sss_ssh_knownhostsproxy doesn't fall back to ipv4 + +* Thu Apr 06 2017 Lukas Slebodnik - 1.15.3-0.beta.2 +- Fix issue with IPA + SELinux in containers +- Resolves: upstream https://fedorahosted.org/sssd/ticket/3297 + +* Tue Apr 04 2017 Lukas Slebodnik - 1.15.3-0.beta.1 +- Backport upstream patches for 1.15.3 pre-release +- required for building freeipa-4.5.x in rawhide + +* Thu Mar 16 2017 Lukas Slebodnik - 1.15.2-1 +- New upstream release 1.15.2 +- https://docs.pagure.org/SSSD.sssd/users/relnotes/notes_1_15_2.html + +* Mon Mar 06 2017 Lukas Slebodnik - 1.15.1-1 +- New upstream release 1.15.1 +- https://docs.pagure.org/SSSD.sssd/users/relnotes/notes_1_15_1.html + +* Wed Feb 22 2017 Jakub Hrozek - 1.15.0-4 +- Cherry-pick patches from upstream that enable the files provider +- Enable the files domain +- Retire patch 0501-Partially-revert-CONFIG-Use-default-config-when-none.patch + which is superseded by the files domain autoconfiguration +- Related: rhbz#1357418 - SSSD fast cache for local users + +* Tue Feb 14 2017 Lukas Slebodnik - 1.15.0-3 +- Add missing %%license macro + +* Sat Feb 11 2017 Fedora Release Engineering - 1.15.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Fri Jan 27 2017 Lukas Slebodnik - 1.15.0-1 +- New upstream release 1.15.0 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.15.0 + +* Mon Dec 19 2016 Miro Hrončok - 1.14.2-3 +- Rebuild for Python 3.6 + +* Tue Dec 13 2016 Lukas Slebodnik - 1.14.2-2 +- Resolves: rhbz#1369130 - nss_sss should not link against libpthread +- Resolves: rhbz#1392916 - sssd failes to start after update +- Resolves: rhbz#1398789 - SELinux is preventing sssd from 'write' accesses + on the directory /etc/sssd + +* Thu Oct 20 2016 Lukas Slebodnik - 1.14.2-1 +- New upstream release 1.14.2 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.14.2 + +* Fri Oct 14 2016 Lukas Slebodnik - 1.14.1-4 +- libwbclient-sssd: update interface to version 0.13 + +* Thu Sep 22 2016 Lukas Slebodnik - 1.14.1-3 +- Fix regression with krb5_map_user +- Resolves: rhbz#1375552 - krb5_map_user doesn't seem effective anymore +- Resolves: rhbz#1349286 - authconfig fails with SSSDConfig.NoDomainError: + default if nonexistent domain is mentioned + +* Thu Sep 01 2016 Lukas Slebodnik - 1.14.1-2 +- Backport important patches from upstream 1.14.2 prerelease +- Resolves: upstream #3154 - sssd exits if clock is adjusted backwards after + boot +- Resolves: upstream #3163 - resolving IPA nested user group is broken in 1.14 + +* Fri Aug 19 2016 Lukas Slebodnik - 1.14.1-1 +- New upstream release 1.14.0 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.14.1 + +* Mon Aug 15 2016 Stephen Gallagher - 1.14.0-5 +- Add workaround patch for RHBZ #1366403 + +* Tue Jul 19 2016 Fedora Release Engineering - 1.14.0-4 +- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages + +* Fri Jul 08 2016 Lukas Slebodnik - 1.14.0-3 +- New upstream release 1.14.0 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.14.0 + +* Fri Jul 01 2016 Lukas Slebodnik - 1.14.0-2.beta +- New upstream release 1.14 beta +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.14.0beta + +* Tue Jun 21 2016 Lukas Slebodnik - 1.14.0-1.alpha +- New upstream release 1.14 alpha +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.14.0alpha + +* Fri May 13 2016 Lukas Slebodnik - 1.13.4-3 +- Resolves: rhbz#1335639 - [abrt] sssd-dbus: ldb_msg_find_element(): + sssd_ifp killed by SIGSEGV + +* Fri Apr 22 2016 Lukas Slebodnik - 1.13.4-2 +- Resolves: rhbz#1328108 - Protocol error with FreeIPA on CentOS 6 + +* Thu Apr 14 2016 Lukas Slebodnik - 1.13.4-1 +- New upstream release 1.13.4 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.13.4 + +* Tue Mar 22 2016 Lukas Slebodnik - 1.13.3-6 +- Resolves: rhbz#1276868 - Sudo PAM Login should support multiple password + prompts (e.g. Password + Token) +- Resolves: rhbz#1313041 - ssh with sssd proxy fails with "Connection closed + by remote host" if locale not available + +* Thu Feb 25 2016 Lukas Slebodnik - 1.13.3-5 +- Resolves: rhbz#1310664 - [RFE] IPA: resolve external group memberships of IPA + groups during getgrnam and getgrgid +- Resolves: rhbz#1301303 - sss_obfuscate: SyntaxError: Missing parentheses + in call to 'print' + +* Fri Feb 05 2016 Fedora Release Engineering - 1.13.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jan 20 2016 Lukas Slebodnik - 1.13.3-3 +- Additional upstream fixes + +* Tue Jan 19 2016 Lukas Slebodnik - 1.13.3-2 +- Resolves: rhbz#1256849 - SUDO: Support the IPA schema + +* Wed Dec 16 2015 Lukas Slebodnik - 1.13.3-1 +- New upstream release 1.13.3 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.13.3 + +* Fri Nov 20 2015 Lukas Slebodnik - 1.13.2-1 +- New upstream release 1.13.2 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.13.2 + +* Fri Nov 06 2015 Robert Kuska - 1.13.1-5 +- Rebuilt for Python3.5 rebuild + +* Tue Oct 27 2015 Lukas Slebodnik - 1.13.1-4 +- Fix building pac responder with the krb5-1.14 + +* Mon Oct 19 2015 Lukas Slebodnik - 1.13.1-3 +- python-sssdconfig: Fix parssing sssd.conf without config_file_version +- Resolves: upstream #2837 - REGRESSION: ipa-client-automout failed + +* Wed Oct 07 2015 Lukas Slebodnik - 1.13.1-2 +- Fix few segfaults +- Resolves: upstream #2811 - PAM responder crashed if user was not set +- Resolves: upstream #2810 - sssd_be crashed in ipa_srv_ad_acct_lookup_step + +* Thu Oct 01 2015 Lukas Slebodnik - 1.13.1-1 +- New upstream release 1.13.1 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.13.1 + +* Thu Sep 10 2015 Lukas Slebodnik - 1.13.0-6 +- Fix OTP bug +- Resolves: upstream #2729 - Do not send SSS_OTP if both factors were + entered separately + +* Mon Sep 07 2015 Lukas Slebodnik - 1.13.0-5 +- Backport upstream patches required by FreeIPA 4.2.1 + +* Tue Jul 21 2015 Lukas Slebodnik - 1.13.0-4 +- Fix ipa-migration bug +- Resolves: upstream #2719 - IPA: returned unknown dp error code with disabled + migration mode + +* Wed Jul 08 2015 Lukas Slebodnik - 1.13.0-3 +- New upstream release 1.13.0 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.13.0 + +* Tue Jun 30 2015 Lukas Slebodnik - 1.13.0-2.alpha +- Unify return type of list_active_domains for python{2,3} + +* Mon Jun 22 2015 Lukas Slebodnik - 1.13.0-1.alpha +- New upstream release 1.13 alpha +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.13.0alpha + +* Fri Jun 19 2015 Fedora Release Engineering - 1.12.5-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Fri Jun 12 2015 Lukas Slebodnik - 1.12.5-3 +- Fix libwbclient alternatives + +* Fri Jun 12 2015 Lukas Slebodnik - 1.12.5-2 +- Backport important patches from upstream 1.13 prerelease + +* Fri Jun 12 2015 Lukas Slebodnik - 1.12.5-1 +- New upstream release 1.12.5 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.12.5 + +* Fri May 08 2015 Lukas Slebodnik - 1.12.4-8 +- Backport important patches from upstream 1.13 prerelease +- Resolves: rhbz#1060325 - Does sssd-ad use the most suitable + attribute for group name +- Resolves: upstream #2335 - Investigate using the krb5 responder + for driving the PAM conversation with OTPs +- Enable cmocka tests for secondary architectures + +* Fri May 08 2015 Lukas Slebodnik - 1.12.4-7 +- Backport patches from upstream 1.12.5 prerelease - contains many fixes + +* Wed Apr 15 2015 Lukas Slebodnik - 1.12.4-6 +- Fix slow login with ipa and SELinux +- Resolves: upstream #2624 - Only set the selinux context if the context + differs from the local one + +* Mon Mar 23 2015 Lukas Slebodnik - 1.12.4-5 +- Fix regressions with ipa and SELinux +- Resolves: upstream #2587 - With empty ipaselinuxusermapdefault security + context on client is staff_u + +* Fri Mar 6 2015 Jakub Hrozek - 1.12.4-4 +- Also relax libldb Requires +- Remove --enable-ldb-version-check + +* Fri Mar 6 2015 Jakub Hrozek - 1.12.4-3 +- Relax libldb BuildRequires to be greater-or-equal + +* Wed Feb 25 2015 Lukas Slebodnik - 1.12.4-2 +- Add support for python3 bindings +- Add requirement to python3 or python3 bindings +- Resolves: rhbz#1014594 - sssd: Support Python 3 + +* Wed Feb 18 2015 Lukas Slebodnik - 1.12.4-1 +- New upstream release 1.12.4 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.12.4 + +* Sat Feb 14 2015 Lukas Slebodnik - 1.12.3-7 +- Backport patches with Python3 support from upstream + +* Thu Feb 12 2015 Lukas Slebodnik - 1.12.3-6 +- Fix double free in monitor +- Resolves: rhbz#1186887 [abrt] sssd-common: talloc_abort(): + sssd killed by SIGABRT + +* Wed Jan 28 2015 Jakub Hrozek - 1.12.3-5 +- Rebuild for new libldb + +* Thu Jan 22 2015 Lukas Slebodnik - 1.12.3-4 +- Decrease priority of sssd-libwbclient 20 -> 5 +- It should be lower than priority of samba veriosn of libwbclient. +- https://bugzilla.redhat.com/show_bug.cgi?id=1175511#c18 + +* Mon Jan 19 2015 Lukas Slebodnik - 1.12.3-3 +- Apply a number of patches from upstream to fix issues found 1.12.3 +- Resolves: rhbz#1176373 - dyndns_iface does not accept multiple + interfaces, or isn't documented to be able to +- Resolves: rhbz#988068 - getpwnam_r fails for non-existing users when sssd is + not running +- Resolves: upstream #2557 authentication failure with user from AD + +* Fri Jan 09 2015 Lukas Slebodnik - 1.12.3-2 +- Resolves: rhbz#1164156 - libsss_simpleifp should pull sssd-dbus +- Resolves: rhbz#1179379 - gzip: stdin: file size changed while + zipping when rotating logfile + +* Thu Jan 08 2015 Lukas Slebodnik - 1.12.3-1 +- New upstream release 1.12.3 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.12.3 +- Fix spelling errors in description (fedpkg lint) + +* Tue Jan 6 2015 Lukas Slebodnik - 1.12.2-8 +- Rebuild for libldb 1.1.19 + +* Fri Dec 19 2014 Sumit Bose - 1.12.2-7 +- Resolves: rhbz#1175511 - sssd-libwbclient conflicts with Samba's and causes + crash in wbinfo + - in addition to the patch libwbclient.so is + filtered out of the Provides list of the package + +* Wed Dec 17 2014 Lukas Slebodnik - 1.12.2-6 +- Fix regressions and bugs in sssd upstream 1.12.2 +- https://fedorahosted.org/sssd/ticket/{id} +- Regressions: #2471, #2475, #2483, #2487, #2529, #2535 +- Bugs: #2287, #2445 + +* Sun Dec 7 2014 Jakub Hrozek - 1.12.2-5 +- Rebuild for libldb 1.1.18 + +* Wed Nov 26 2014 Jakub Hrozek - 1.12.2-4 +- Fix typo in libwbclient-devel %%preun + +* Tue Nov 25 2014 Jakub Hrozek - 1.12.2-3 +- Use alternatives for libwbclient + +* Wed Oct 22 2014 Jakub Hrozek - 1.12.2-2 +- Backport several patches from upstream. +- Fix a potential crash against old (pre-4.0) IPA servers + +* Mon Oct 20 2014 Jakub Hrozek - 1.12.2-1 +- New upstream release 1.12.2 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.12.2 + +* Mon Sep 15 2014 Jakub Hrozek - 1.12.1-2 +- Resolves: rhbz#1139962 - Fedora 21, FreeIPA 4.0.2: sssd does not find user + private group from server + +* Mon Sep 8 2014 Jakub Hrozek - 1.12.1-1 +- New upstream release 1.12.1 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.12.1 + +* Fri Aug 22 2014 Jakub Hrozek - 1.12.0-7 +- Do not crash on resolving a group SID in IPA server mode + +* Mon Aug 18 2014 Fedora Release Engineering - 1.12.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Thu Jul 10 2014 Stephen Gallagher 1.12.0-5 +- Fix release version for upgrades + +* Wed Jul 09 2014 Jakub Hrozek - 1.12.0-1 +- New upstream release 1.12.0 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.12.0 + +* Sun Jun 08 2014 Fedora Release Engineering - 1.12.0-4.beta2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed Jun 04 2014 Jakub Hrozek - 1.12.0-1.beta2 +- New upstream release 1.12 beta2 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.12.0beta2 + +* Mon Jun 02 2014 Jakub Hrozek - 1.12.0-2.beta1 +- Fix tests on big-endian +- Fix previous changelog entry + +* Fri May 30 2014 Jakub Hrozek - 1.12.0-1.beta1 +- New upstream release 1.12 beta1 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.12.0beta1 + +* Thu May 29 2014 Jakub Hrozek - 1.11.5.1-4 +- Rebuild against new ding-libs + +* Thu May 08 2014 Stephen Gallagher - 1.11.5.1-3 +- Make LDB dependency a strict equivalency + +* Thu May 08 2014 Stephen Gallagher - 1.11.5.1-2 +- Rebuild against new libldb + +* Fri Apr 11 2014 Jakub Hrozek - 1.11.5.1-1 +- New upstream release 1.11.5.1 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.11.5.1 + +* Thu Apr 10 2014 Stephen Gallagher 1.11.5-2 +- Fix bug in generation of systemd unit file + +* Tue Apr 08 2014 Jakub Hrozek - 1.11.5-1 +- New upstream release 1.11.5 +- Remove upstreamed patch +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.11.5 + +* Thu Mar 13 2014 Sumit Bose - 1.11.4-3 +- Handle new error code for IPA password migration + +* Tue Mar 11 2014 Jakub Hrozek - 1.11.4-2 +- Include couple of patches from upstream 1.11 branch + +* Mon Feb 17 2014 Jakub Hrozek - 1.11.4-1 +- New upstream release 1.11.4 +- Remove upstreamed patch +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.11.4 + +* Tue Feb 11 2014 Jakub Hrozek - 1.11.3-2 +- Handle OTP response from FreeIPA server gracefully + +* Wed Oct 30 2013 Jakub Hrozek - 1.11.3-1 +- New upstream release 1.11.3 +- Remove upstreamed patches +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.11.3 + +* Wed Oct 30 2013 Jakub Hrozek - 1.11.2-1 +- New upstream release 1.11.2 +- Remove upstreamed patches +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.11.2 + +* Wed Oct 16 2013 Sumit Bose - 1.11.1-5 +- Fix potential crash with external groups in trusted IPA-AD setup + +* Mon Oct 14 2013 Sumit Bose - 1.11.1-4 +- Add plugin for cifs-utils +- Resolves: rhbz#998544 + +* Tue Oct 08 2013 Jakub Hrozek - 1.11.1-3 +- Fix failover from Global Catalog to LDAP in case GC is not available + +* Fri Oct 04 2013 Jakub Hrozek - 1.11.1-2 +- Remove the ability to create public ccachedir (#1015089) + +* Fri Sep 27 2013 Jakub Hrozek - 1.11.1-1 +- New upstream release 1.11.1 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.11.1 + +* Thu Sep 26 2013 Jakub Hrozek - 1.11.0-3 +- Fix multicast checks in the SSSD +- Resolves: rhbz#1007475 - The multicast check is wrong in the sudo source + code getting the host info + +* Wed Aug 28 2013 Jakub Hrozek - 1.11.0-2 +- Backport simplification of ccache management from 1.11.1 +- Resolves: rhbz#1010553 - sssd setting KRB5CCNAME=(null) on login + +* Wed Aug 28 2013 Jakub Hrozek - 1.11.0-1 +- New upstream release 1.11.0 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.11.0 + +* Fri Aug 23 2013 Jakub Hrozek - 1.11.0-0.4.beta2 +- Resolves: #967012 - [abrt] sssd-1.9.5-1.fc18: sss_mmap_cache_gr_invalidate_gid: + Process /usr/libexec/sssd/sssd_nss was killed by + signal 11 (SIGSEGV) +- Resolves: #996214 - sssd proxy_child segfault + +* Sun Aug 04 2013 Fedora Release Engineering - 1.11.0-0.3.beta2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Wed Jul 31 2013 Jakub Hrozek - 1.11.0.2beta2 +- Resolves: #906427 - Do not use %%{_lib} in specfile for the nss and + pam libraries + +* Wed Jul 24 2013 Jakub Hrozek - 1.11.0.1beta2 +- New upstream release 1.11 beta 2 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.11.0beta2 + +* Thu Jul 18 2013 Jakub Hrozek - 1.10.1-1 +- New upstream release 1.10.1 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.10.1 + +* Mon Jul 08 2013 Jakub Hrozek - 1.10.0-17 +- sssd-tools should require sssd-common, not sssd + +* Tue Jul 02 2013 Stephen Gallagher - 1.10.0-16 +- Move sssd_pac to the sssd-ipa and sssd-ad subpackages +- Trim out RHEL5-specific macros since we don't build on RHEL 5 +- Trim out macros for Fedora older than F18 +- Update libldb requirement to 1.1.16 +- Trim RPM changelog down to the last year + +* Tue Jul 02 2013 Stephen Gallagher - 1.10.0-15 +- Move sssd_pac to the sssd-krb5 subpackage + +* Mon Jul 01 2013 Stephen Gallagher - 1.10.0-14 +- Fix Obsoletes: to account for dist tag +- Convert post and pre scripts to run on the sssd-common subpackage +- Remove old conversion from SYSV + +* Thu Jun 27 2013 Jakub Hrozek - 1.10.0-13 +- New upstream release 1.10 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.10.0 + +* Mon Jun 17 2013 Dan Horák - 1.10.0-12.beta2 +- the cmocka toolkit exists only on selected arches + +* Sun Jun 16 2013 Jakub Hrozek - 1.10.0-11.beta2 +- Apply a number of patches from upstream to fix issues found post-beta, + in particular: + -- segfault with a high DEBUG level + -- Fix IPA password migration (upstream #1873) + -- Fix fail over when retrying SRV resolution (upstream #1886) + +* Thu Jun 13 2013 Jakub Hrozek - 1.10.0-10.beta2 +- Only BuildRequire libcmocka on Fedora + +* Thu Jun 13 2013 Jakub Hrozek - 1.10.0-9.beta2 +- Fix typo in Requires that prevented an upgrade (#973916) +- Use a hardcoded version in Conflicts, not less-than-current + +* Wed Jun 12 2013 Jakub Hrozek - 1.10.0-8.beta1 +- Enable hardened build for RHEL7 + +* Wed Jun 12 2013 Jakub Hrozek - 1.10.0-8.beta2 +- New upstream release 1.10 beta2 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.10.0beta2 +- BuildRequire libcmocka-devel in order to run all upstream tests during build +- BuildRequire libnl3 instead of libnl1 +- No longer BuildRequire initscripts, we no longer use /sbin/service +- Remove explicit krb5-libs >= 1.10 requires; this platform doensn't carry any + older krb5-libs version + +* Fri May 24 2013 Jakub Hrozek - 1.10.0-7.beta1 +- Apply a couple of patches from upstream git that resolve crashes when + ID mapping object was not initialized properly but needed later + +* Tue May 14 2013 Jakub Hrozek - 1.10.0-6.beta1 +- Resolves: rhbz#961357 - Missing dyndns_update entry in sssd.conf during + realm join +- Resolves: rhbz#961278 - Login failure: Enterprise Principal enabled by + default for AD Provider +- Resolves: rhbz#961251 - sssd does not create user's krb5 ccache dir/file + parent directory when logging in + +* Tue May 7 2013 Jakub Hrozek - 1.10.0-5.beta1 +- BuildRequire recent libini_config to ensure consistent behaviour + +* Tue May 7 2013 Jakub Hrozek - 1.10.0-4.beta1 +- Explicitly Require libini_config >= 1.0.0.1 to work around a SONAME bug + in ding-libs +- Fix SSH integration with fully-qualified domains +- Add the ability to dynamically discover the NetBIOS name + +* Fri May 3 2013 Jakub Hrozek - 1.10.0-3.beta1 +- New upstream release 1.10 beta1 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.10.0beta1 + +* Wed Apr 17 2013 Jakub Hrozek - 1.10.0-2.alpha1 +- Add a patch to fix krb5 ccache creation issue with krb5 1.11 + +* Tue Apr 2 2013 Jakub Hrozek - 1.10.0-1.alpha1 +- New upstream release 1.10 alpha1 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.10.0alpha1 + +* Fri Mar 29 2013 Jakub Hrozek - 1.9.5-10 +- Add a patch to fix krb5 unit tests + +* Fri Mar 01 2013 Stephen Gallagher - 1.9.4-9 +- Split internal helper libraries into a shared object +- Significantly reduce disk-space usage + +* Thu Feb 14 2013 Jakub Hrozek - 1.9.4-8 +- Fix the Kerberos password expiration warning (#912223) + +* Thu Feb 14 2013 Jakub Hrozek - 1.9.4-7 +- Do not write out dots in the domain-realm mapping file (#905650) + +* Mon Feb 11 2013 Jakub Hrozek - 1.9.4-6 +- Include upstream patch to build with krb5-1.11 + +* Thu Feb 07 2013 Jakub Hrozek - 1.9.4-5 +- Rebuild against new libldb + +* Mon Feb 04 2013 Jakub Hrozek - 1.9.4-4 +- Fix build with new automake versions + +* Wed Jan 30 2013 Jakub Hrozek - 1.9.4-3 +- Recreate Kerberos ccache directory if it's missing +- Resolves: rhbz#853558 - [sssd[krb5_child[PID]]]: Credential cache + directory /run/user/UID/ccdir does not exist + +* Tue Jan 29 2013 Jakub Hrozek - 1.9.4-2 +- Fix changelog dates to make F19 rpmbuild happy + +* Mon Jan 28 2013 Jakub Hrozek - 1.9.4-1 +- New upstream release 1.9.4 + +* Thu Dec 06 2012 Jakub Hrozek - 1.9.3-1 +- New upstream release 1.9.3 + +* Tue Oct 30 2012 Jakub Hrozek - 1.9.2-5 +- Resolve groups from AD correctly + +* Tue Oct 30 2012 Jakub Hrozek - 1.9.2-4 +- Check the validity of naming context + +* Thu Oct 18 2012 Jakub Hrozek - 1.9.2-3 +- Move the sss_cache tool to the main package + +* Sun Oct 14 2012 Jakub Hrozek - 1.9.2-2 +- Include the 1.9.2 tarball + +* Sun Oct 14 2012 Jakub Hrozek - 1.9.2-1 +- New upstream release 1.9.2 + +* Sun Oct 07 2012 Jakub Hrozek - 1.9.1-1 +- New upstream release 1.9.1 + +* Wed Oct 03 2012 Jakub Hrozek - 1.9.0-24 +- require the latest libldb + +* Tue Sep 25 2012 Jakub Hrozek - 1.9.0-24 +- Use mcpath insted of mcachepath macro to be consistent with + upsteam spec file + +* Tue Sep 25 2012 Jakub Hrozek - 1.9.0-23 +- New upstream release 1.9.0 + +* Fri Sep 14 2012 Jakub Hrozek - 1.9.0-22.rc1 +- New upstream release 1.9.0 rc1 + +* Thu Sep 06 2012 Jakub Hrozek - 1.9.0-21.beta7 +- New upstream release 1.9.0 beta7 +- obsoletes patches #1-#3 + +* Mon Sep 03 2012 Jakub Hrozek - 1.9.0-20.beta6 +- Rebuild against libldb 1.12 + +* Tue Aug 28 2012 Jakub Hrozek - 1.9.0-19.beta6 +- Rebuild against libldb 1.11 + +* Fri Aug 24 2012 Jakub Hrozek - 1.9.0-18.beta6 +- Change the default ccache location to DIR:/run/user/${UID}/krb5cc + and patch man page accordingly +- Resolves: rhbz#851304 + +* Mon Aug 20 2012 Jakub Hrozek - 1.9.0-17.beta6 +- Rebuild against libldb 1.10 + +* Fri Aug 17 2012 Jakub Hrozek - 1.9.0-16.beta6 +- Only create the SELinux login file if there are SELinux mappings on + the IPA server + +* Fri Aug 10 2012 Jakub Hrozek - 1.9.0-14.beta6 +- Don't discard HBAC rule processing result if SELinux is on + Resolves: rhbz#846792 (CVE-2012-3462) + +* Thu Aug 02 2012 Jakub Hrozek - 1.9.0-13.beta6 +- New upstream release 1.9.0 beta 6 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.9.0beta6 +- A new option, override_shell was added. If this option is set, all users + managed by SSSD will have their shell set to its value. +- Fixes for the support for setting default SELinux user context from FreeIPA. +- Fixed a regression introduced in beta 5 that broke LDAP SASL binds +- The SSSD supports the concept of a Primary Server and a Back Up Server in + failover +- A new command-line tool sss_seed is available to help prime the cache with + a user record when deploying a new machine +- SSSD is now able to discover and save the domain-realm mappings + between an IPA server and a trusted Active Directory server. +- Packaging changes to fix ldconfig usage in subpackages (#843995) +- Rebuild against libldb 1.1.9 + +* Fri Jul 27 2012 Fedora Release Engineering - 1.9.0-13.beta5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Thu Jul 19 2012 Jakub Hrozek - 1.9.0-12.beta5 +- New upstream release 1.9.0 beta 5 +- Obsoletes the patch for missing DP_OPTION_TERMINATOR in AD provider options +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.9.0beta5 +- Many fixes for the support for setting default SELinux user context from + FreeIPA, most notably fixed the specificity evaluation +- Fixed an incorrect default in the krb5_canonicalize option of the AD + provider which was preventing password change operation +- The shadowLastChange attribute value is now correctly updated with the + number of days since the Epoch, not seconds + +* Mon Jul 16 2012 Stephen Gallagher - 1.9.0-11.beta4 +- Fix broken ARM build +- Add missing DP_OPTION_TERMINATOR in AD provider options + +* Wed Jul 11 2012 Jakub Hrozek - 1.9.0-10.beta4 +- Own several directories create during make install (#839782) + +* Wed Jul 11 2012 Jakub Hrozek - 1.9.0-9.beta4 +- New upstream release 1.9.0 beta 4 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.9.0beta4 +- Add a new AD provider to improve integration with Active Directory 2008 R2 + or later servers +- SUDO integration was completely rewritten. The new implementation works + with multiple domains and uses an improved refresh mechanism to download + only the necessary rules +- The IPA authentication provider now supports subdomains +- Fixed regression for setups that were setting default_tkt_enctypes + manually by reverting a previous workaround. + +* Mon Jun 25 2012 Stephen Gallagher - 1.9.0-8.beta3 +- New upstream release 1.9.0 beta 3 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.9.0beta3 +- Add a new PAC responder for dealing with cross-realm Kerberos trusts +- Terminate idle connections to the NSS and PAM responders + +* Wed Jun 20 2012 Stephen Gallagher - 1.9.0-7.beta2 +- Switch unicode library from libunistring to Glib +- Drop unnecessary explicit Requires on keyutils +- Guarantee that versioned Requires include the correct architecture + +* Mon Jun 18 2012 Stephen Gallagher - 1.9.0-6.beta2 +- Fix accidental disabling of the DIR cache support + +* Fri Jun 15 2012 Stephen Gallagher - 1.9.0-5.beta2 +- New upstream release 1.9.0 beta 2 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.9.0beta2 +- Add support for the Kerberos DIR cache for storing multiple TGTs + automatically +- Major performance enhancement when storing large groups in the cache +- Major performance enhancement when performing initgroups() against Active + Directory +- SSSDConfig data file default locations can now be set during configure for + easier packaging + +* Tue May 29 2012 Stephen Gallagher - 1.9.0-4.beta1 +- Fix regression in endianness patch + +* Tue May 29 2012 Stephen Gallagher - 1.9.0-3.beta1 +- Rebuild SSSD against ding-libs 0.3.0beta1 +- Fix endianness bug in service map protocol + +* Thu May 24 2012 Stephen Gallagher - 1.9.0-2.beta1 +- Fix several regressions since 1.5.x +- Ensure that the RPM creates the /var/lib/sss/mc directory +- Add support for Netscape password warning expiration control +- Rebuild against libldb 1.1.6 + +* Fri May 11 2012 Stephen Gallagher - 1.9.0-1.beta1 +- New upstream release 1.9.0 beta 1 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.9.0beta1 +- Add native support for autofs to the IPA provider +- Support for ID-mapping when connecting to Active Directory +- Support for handling very large (> 1500 users) groups in Active Directory +- Support for sub-domains (will be used for dealing with trust relationships) +- Add a new fast in-memory cache to speed up lookups of cached data on + repeated requests + +* Thu May 03 2012 Stephen Gallagher - 1.8.3-11 +- New upstream release 1.8.3 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.8.3 +- Numerous manpage and translation updates +- LDAP: Handle situations where the RootDSE isn't available anonymously +- LDAP: Fix regression for users using non-standard LDAP attributes for user + information + +* Mon Apr 09 2012 Stephen Gallagher - 1.8.2-10 +- New upstream release 1.8.2 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.8.2 +- Several fixes to case-insensitive domain functions +- Fix for GSSAPI binds when the keytab contains unrelated principals +- Fixed several segfaults +- Workarounds added for LDAP servers with unreadable RootDSE +- SSH knownhostproxy will no longer enter an infinite loop preventing login +- The provided SYSV init script now starts SSSD earlier at startup and stops + it later during shutdown +- Assorted minor fixes for issues discovered by static analysis tools + +* Mon Mar 26 2012 Stephen Gallagher - 1.8.1-9 +- Don't duplicate libsss_autofs.so in two packages +- Set explicit package contents instead of globbing + +* Wed Mar 21 2012 Stephen Gallagher - 1.8.1-8 +- Fix uninitialized value bug causing crashes throughout the code +- Resolves: rhbz#804783 - [abrt] Segfault during LDAP 'services' lookup + +* Mon Mar 12 2012 Stephen Gallagher - 1.8.1-7 +- New upstream release 1.8.1 +- Resolve issue where we could enter an infinite loop trying to connect to an + auth server +- Fix serious issue with complex (3+ levels) nested groups +- Fix netgroup support for case-insensitivity and aliases +- Fix serious issue with lookup bundling resulting in requests never + completing +- IPA provider will now check the value of nsAccountLock during pam_acct_mgmt + in addition to pam_authenticate +- Fix several regressions in the proxy provider +- Resolves: rhbz#743133 - Performance regression with Kerberos authentication + against AD +- Resolves: rhbz#799031 - --debug option for sss_debuglevel doesn't work + +* Tue Feb 28 2012 Stephen Gallagher - 1.8.0-6 +- New upstream release 1.8.0 +- Support for the service map in NSS +- Support for setting default SELinux user context from FreeIPA +- Support for retrieving SSH user and host keys from LDAP (Experimental) +- Support for caching autofs LDAP requests (Experimental) +- Support for caching SUDO rules (Experimental) +- Include the IPA AutoFS provider +- Fixed several memory-corruption bugs +- Fixed a regression in group enumeration since 1.7.0 +- Fixed a regression in the proxy provider +- Resolves: rhbz#741981 - Separate Cache Timeouts for SSSD +- Resolves: rhbz#797968 - sssd_be: The requested tar get is not configured is + logged at each login +- Resolves: rhbz#754114 - [abrt] sssd-1.6.3-1.fc16: ping_check: Process + /usr/sbin/sssd was killed by signal 11 (SIGSEGV) +- Resolves: rhbz#743133 - Performance regression with Kerberos authentication + against AD +- Resolves: rhbz#773706 - SSSD fails during autodetection of search bases for + new LDAP features +- Resolves: rhbz#786957 - sssd and kerberos should change the default location for create the Credential Cashes to /run/usr/USERNAME/krb5cc + +* Wed Feb 22 2012 Stephen Gallagher - 1.8.0-5.beta3 +- Change default kerberos credential cache location to /run/user/ + +* Wed Feb 15 2012 Stephen Gallagher - 1.8.0-4.beta3 +- New upstream release 1.8.0 beta 3 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.8.0beta3 +- Fixed a regression in group enumeration since 1.7.0 +- Fixed several memory-corruption bugs +- Finalized the ABI for the autofs support +- Fixed a regression in the proxy provider + +* Fri Feb 10 2012 Petr Pisar - 1.8.0-3.beta2 +- Rebuild against PCRE 8.30 + +* Mon Feb 06 2012 Stephen Gallagher - 1.8.0-1.beta2 +- New upstream release +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.8.0beta2 +- Fix two minor manpage bugs +- Include the IPA AutoFS provider + +* Mon Feb 06 2012 Stephen Gallagher - 1.8.0-1.beta1 +- New upstream release +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.8.0beta1 +- Support for the service map in NSS +- Support for setting default SELinux user context from FreeIPA +- Support for retrieving SSH user and host keys from LDAP (Experimental) +- Support for caching autofs LDAP requests (Experimental) +- Support for caching SUDO rules (Experimental) + +* Wed Feb 01 2012 Stephen Gallagher - 1.7.0-5 +- Resolves: rhbz#773706 - SSSD fails during autodetection of search bases for + new LDAP features - fix netgroups and sudo as well + +* Wed Feb 01 2012 Stephen Gallagher - 1.7.0-4 +- Fixes a serious memory hierarchy bug causing unpredictable behavior in the + LDAP provider. + +* Wed Feb 01 2012 Stephen Gallagher - 1.7.0-3 +- Resolves: rhbz#773706 - SSSD fails during autodetection of search bases for + new LDAP features + +* Sat Jan 14 2012 Fedora Release Engineering - 1.7.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Thu Dec 22 2011 Stephen Gallagher - 1.7.0-1 +- New upstream release 1.7.0 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.7.0 +- Support for case-insensitive domains +- Support for multiple search bases in the LDAP provider +- Support for the native FreeIPA netgroup implementation +- Reliability improvements to the process monitor +- New DEBUG facility with more consistent log levels +- New tool to change debug log levels without restarting SSSD +- SSSD will now disconnect from LDAP server when idle +- FreeIPA HBAC rules can choose to ignore srchost options for significant + performance gains +- Assorted performance improvements in the LDAP provider + +* Mon Dec 19 2011 Stephen Gallagher - 1.6.4-1 +- New upstream release 1.6.4 +- Rolls up previous patches applied to the 1.6.3 tarball +- Fixes a rare issue causing crashes in the failover logic +- Fixes an issue where SSSD would return the wrong PAM error code for users + that it does not recognize. + +* Wed Dec 07 2011 Stephen Gallagher - 1.6.3-5 +- Rebuild against libldb 1.1.4 + +* Tue Nov 29 2011 Stephen Gallagher - 1.6.3-4 +- Resolves: rhbz#753639 - sssd_nss crashes when passed invalid UTF-8 for the + username in getpwnam() +- Resolves: rhbz#758425 - LDAP failover not working if server refuses + connections + +* Thu Nov 24 2011 Jakub Hrozek - 1.6.3-3 +- Rebuild for libldb 1.1.3 + +* Thu Nov 10 2011 Stephen Gallagher - 1.6.3-2 +- Resolves: rhbz#752495 - Crash when apply settings + +* Fri Nov 04 2011 Stephen Gallagher - 1.6.3-1 +- New upstream release 1.6.3 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.6.3 +- Fixes a major cache performance issue introduced in 1.6.2 +- Fixes a potential infinite-loop with certain LDAP layouts + +* Wed Oct 26 2011 Fedora Release Engineering - 1.6.2-5 +- Rebuilt for glibc bug#747377 + +* Sun Oct 23 2011 Stephen Gallagher - 1.6.2-4 +- Change selinux policy requirement to Conflicts: with the old version, + rather than Requires: the supported version. + +* Fri Oct 21 2011 Stephen Gallagher - 1.6.2-3 +- Add explicit requirement on selinux-policy version to address new SBUS + symlinks. + +* Wed Oct 19 2011 Stephen Gallagher - 1.6.2-2 +- Remove %%files reference to sss_debuglevel copied from wrong upstreeam + spec file. + +* Tue Oct 18 2011 Stephen Gallagher - 1.6.2-1 +- Improved handling of users and groups with multi-valued name attributes + (aliases) +- Performance enhancements + Initgroups on RFC2307bis/FreeIPA + HBAC rule processing +- Improved process-hang detection and restarting +- Enabled the midpoint cache refresh by default (fewer cache misses on + commonly-used entries) +- Cleaned up the example configuration +- New tool to change debug level on the fly + +* Mon Aug 29 2011 Stephen Gallagher - 1.6.1-1 +- New upstream release 1.6.1 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.6.1 +- Fixes a serious issue with LDAP connections when the communication is + dropped (e.g. VPN disconnection, waking from sleep) +- SSSD is now less strict when dealing with users/groups with multiple names + when a definitive primary name cannot be determined +- The LDAP provider will no longer attempt to canonicalize by default when + using SASL. An option to re-enable this has been provided. +- Fixes for non-standard LDAP attribute names (e.g. those used by Active + Directory) +- Three HBAC regressions have been fixed. +- Fix for an infinite loop in the deref code + +* Wed Aug 03 2011 Stephen Gallagher - 1.6.0-2 +- Build with _hardened_build macro + +* Wed Aug 03 2011 Stephen Gallagher - 1.6.0-1 +- New upstream release 1.6.0 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.6.0 +- Add host access control support for LDAP (similar to pam_host_attr) +- Finer-grained control on principals used with Kerberos (such as for FAST or +- validation) +- Added a new tool sss_cache to allow selective expiring of cached entries +- Added support for LDAP DEREF and ASQ controls +- Added access control features for Novell Directory Server +- FreeIPA dynamic DNS update now checks first to see if an update is needed +- Complete rewrite of the HBAC library +- New libraries: libipa_hbac and libipa_hbac-python + +* Tue Jul 05 2011 Stephen Gallagher - 1.5.11-2 +- New upstream release 1.5.11 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.5.11 +- Fix a serious regression that prevented SSSD from working with ldaps:// URIs +- IPA Provider: Fix a bug with dynamic DNS that resulted in the wrong IPv6 +- address being saved to the AAAA record + +* Fri Jul 01 2011 Stephen Gallagher - 1.5.10-1 +- New upstream release 1.5.10 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.5.10 +- Fixed a regression introduced in 1.5.9 that could result in blocking calls +- to LDAP + +* Thu Jun 30 2011 Stephen Gallagher - 1.5.9-1 +- New upstream release 1.5.9 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.5.9 +- Support for overriding home directory, shell and primary GID locally +- Properly honor TTL values from SRV record lookups +- Support non-POSIX groups in nested group chains (for RFC2307bis LDAP +- servers) +- Properly escape IPv6 addresses in the failover code +- Do not crash if inotify fails (e.g. resource exhaustion) +- Don't add multiple TGT renewal callbacks (too many log messages) + +* Fri May 27 2011 Stephen Gallagher - 1.5.8-1 +- New upstream release 1.5.8 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.5.8 +- Support for the LDAP paging control +- Support for multiple DNS servers for name resolution +- Fixes for several group membership bugs +- Fixes for rare crash bugs + +* Mon May 23 2011 Stephen Gallagher - 1.5.7-3 +- Resolves: rhbz#706740 - Orphaned links on rc0.d-rc6.d +- Make sure to properly convert to systemd if upgrading from newer +- updates for Fedora 14 + +* Mon May 02 2011 Stephen Gallagher - 1.5.7-2 +- Fix segfault in TGT renewal + +* Fri Apr 29 2011 Stephen Gallagher - 1.5.7-1 +- Resolves: rhbz#700891 - CVE-2011-1758 sssd: automatic TGT renewal overwrites +- cached password with predicatable filename + +* Wed Apr 20 2011 Stephen Gallagher - 1.5.6.1-1 +- Re-add manpage translations + +* Wed Apr 20 2011 Stephen Gallagher - 1.5.6-1 +- New upstream release 1.5.6 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.5.6 +- Fixed a serious memory leak in the memberOf plugin +- Fixed a regression with the negative cache that caused it to be essentially +- nonfunctional +- Fixed an issue where the user's full name would sometimes be removed from +- the cache +- Fixed an issue with password changes in the kerberos provider not working +- with kpasswd + +* Wed Apr 20 2011 Stephen Gallagher - 1.5.5-5 +- Resolves: rhbz#697057 - kpasswd fails when using sssd and +- kadmin server != kdc server +- Upgrades from SysV should now maintain enabled/disabled status + +* Mon Apr 18 2011 Stephen Gallagher - 1.5.5-4 +- Fix %%postun + +* Thu Apr 14 2011 Stephen Gallagher - 1.5.5-3 +- Fix systemd conversion. Upgrades from SysV to systemd weren't properly +- enabling the systemd service. +- Fix a serious memory leak in the memberOf plugin +- Fix an issue where the user's full name would sometimes be removed +- from the cache + +* Tue Apr 12 2011 Stephen Gallagher - 1.5.5-2 +- Install systemd unit file instead of sysv init script + +* Tue Apr 12 2011 Stephen Gallagher - 1.5.5-1 +- New upstream release 1.5.5 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.5.5 +- Fixes for several crash bugs +- LDAP group lookups will no longer abort if there is a zero-length member +- attribute +- Add automatic fallback to 'cn' if the 'gecos' attribute does not exist + +* Thu Mar 24 2011 Stephen Gallagher - 1.5.4-1 +- New upstream release 1.5.4 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.5.4 +- Fixes for Active Directory when not all users and groups have POSIX attributes +- Fixes for handling users and groups that have name aliases (aliases are ignored) +- Fix group memberships after initgroups in the IPA provider + +* Thu Mar 17 2011 Stephen Gallagher - 1.5.3-2 +- Resolves: rhbz#683267 - sssd 1.5.1-9 breaks AD authentication + +* Fri Mar 11 2011 Stephen Gallagher - 1.5.3-1 +- New upstream release 1.5.3 +- Support for libldb >= 1.0.0 + +* Thu Mar 10 2011 Stephen Gallagher - 1.5.2-1 +- New upstream release 1.5.2 +- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.5.2 +- Fixes for support of FreeIPA v2 +- Fixes for failover if DNS entries change +- Improved sss_obfuscate tool with better interactive mode +- Fix several crash bugs +- Don't attempt to use START_TLS over SSL. Some LDAP servers can't handle this +- Delete users from the local cache if initgroups calls return 'no such user' +- (previously only worked for getpwnam/getpwuid) +- Use new Transifex.net translations +- Better support for automatic TGT renewal (now survives restart) +- Netgroup fixes + +* Sun Feb 27 2011 Simo Sorce - 1.5.1-9 +- Rebuild sssd against libldb 1.0.2 so the memberof module loads again. +- Related: rhbz#677425 + +* Mon Feb 21 2011 Stephen Gallagher - 1.5.1-8 +- Resolves: rhbz#677768 - name service caches names, so id command shows +- recently deleted users + +* Fri Feb 11 2011 Stephen Gallagher - 1.5.1-7 +- Ensure that SSSD builds against libldb-1.0.0 on F15 and later +- Remove .la for memberOf + +* Fri Feb 11 2011 Stephen Gallagher - 1.5.1-6 +- Fix memberOf install path + +* Fri Feb 11 2011 Stephen Gallagher - 1.5.1-5 +- Add support for libldb 1.0.0 + +* Wed Feb 09 2011 Fedora Release Engineering - 1.5.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Feb 01 2011 Stephen Gallagher - 1.5.1-3 +- Fix nested group member filter sanitization for RFC2307bis +- Put translated tool manpages into the sssd-tools subpackage + +* Thu Jan 27 2011 Stephen Gallagher - 1.5.1-2 +- Restore Requires: cyrus-sasl-gssapi as it is not auto-detected during +- rpmbuild + +* Thu Jan 27 2011 Stephen Gallagher - 1.5.1-1 +- New upstream release 1.5.1 +- Addresses CVE-2010-4341 - DoS in sssd PAM responder can prevent logins +- Vast performance improvements when enumerate = true +- All PAM actions will now perform a forced initgroups lookup instead of just +- a user information lookup +- This guarantees that all group information is available to other +- providers, such as the simple provider. +- For backwards-compatibility, DNS lookups will also fall back to trying the +- SSSD domain name as a DNS discovery domain. +- Support for more password expiration policies in LDAP +- 389 Directory Server +- FreeIPA +- ActiveDirectory +- Support for ldap_tls_{cert,key,cipher_suite} config options +-Assorted bugfixes + +* Tue Jan 11 2011 Stephen Gallagher - 1.5.0-2 +- CVE-2010-4341 - DoS in sssd PAM responder can prevent logins + +* Wed Dec 22 2010 Stephen Gallagher - 1.5.0-1 +- New upstream release 1.5.0 +- Fixed issues with LDAP search filters that needed to be escaped +- Add Kerberos FAST support on platforms that support it +- Reduced verbosity of PAM_TEXT_INFO messages for cached credentials +- Added a Kerberos access provider to honor .k5login +- Addressed several thread-safety issues in the sss_client code +- Improved support for delayed online Kerberos auth +- Significantly reduced time between connecting to the network/VPN and +- acquiring a TGT +- Added feature for automatic Kerberos ticket renewal +- Provides the kerberos ticket for long-lived processes or cron jobs +- even when the user logs out +- Added several new features to the LDAP access provider +- Support for 'shadow' access control +- Support for authorizedService access control +- Ability to mix-and-match LDAP access control features +- Added an option for a separate password-change LDAP server for those +- platforms where LDAP referrals are not supported +- Added support for manpage translations + + +* Thu Nov 18 2010 Stephen Gallagher - 1.4.1-3 +- Solve a shutdown race-condition that sometimes left processes running +- Resolves: rhbz#606887 - SSSD stops on upgrade + +* Tue Nov 16 2010 Stephen Gallagher - 1.4.1-2 +- Log startup errors to the syslog +- Allow cache cleanup to be disabled in sssd.conf + +* Mon Nov 01 2010 Stephen Gallagher - 1.4.1-1 +- New upstream release 1.4.1 +- Add support for netgroups to the proxy provider +- Fixes a minor bug with UIDs/GIDs >= 2^31 +- Fixes a segfault in the kerberos provider +- Fixes a segfault in the NSS responder if a data provider crashes +- Correctly use sdap_netgroup_search_base + +* Mon Oct 18 2010 Stephen Gallagher - 1.4.0-2 +- Fix incorrect tarball URL + +* Mon Oct 18 2010 Stephen Gallagher - 1.4.0-1 +- New upstream release 1.4.0 +- Added support for netgroups to the LDAP provider +- Performance improvements made to group processing of RFC2307 LDAP servers +- Fixed nested group issues with RFC2307bis LDAP servers without a memberOf plugin +- Build-system improvements to support Gentoo +- Split out several libraries into the ding-libs tarball +- Manpage reviewed and updated + +* Mon Oct 04 2010 Stephen Gallagher - 1.3.0-35 +- Fix pre and post script requirements + +* Mon Oct 04 2010 Stephen Gallagher - 1.3.0-34 +- Resolves: rhbz#606887 - sssd stops on upgrade + +* Fri Oct 01 2010 Stephen Gallagher - 1.3.0-33 +- Resolves: rhbz#626205 - Unable to unlock screen + +* Tue Sep 28 2010 Stephen Gallagher - 1.3.0-32 +- Resolves: rhbz#637955 - libini_config-devel needs libcollection-devel but +- doesn't require it + +* Thu Sep 16 2010 Stephen Gallagher - 1.3.0-31 +- Resolves: rhbz#632615 - the krb5 locator plugin isn't packaged for multilib + +* Tue Aug 24 2010 Stephen Gallagher - 1.3.0-30 +- Resolves: CVE-2010-2940 - sssd allows null password entry to authenticate +- against LDAP + +* Thu Jul 22 2010 David Malcolm - 1.2.91-21 +- Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild + +* Fri Jul 09 2010 Stephen Gallagher - 1.2.91-20 +- New upstream version 1.2.91 (1.3.0rc1) +- Improved LDAP failover +- Synchronous sysdb API (provides performance enhancements) +- Better online reconnection detection + +* Mon Jun 21 2010 Stephen Gallagher - 1.2.1-15 +- New stable upstream version 1.2.1 +- Resolves: rhbz#595529 - spec file should eschew %%define in favor of +- %%global +- Resolves: rhbz#593644 - Empty list of simple_allow_users causes sssd service +- to fail while restart. +- Resolves: rhbz#599026 - Makefile typo causes SSSD not to use the kernel +- keyring +- Resolves: rhbz#599724 - sssd is broken on Rawhide + +* Mon May 24 2010 Stephen Gallagher - 1.2.0-12 +- New stable upstream version 1.2.0 +- Support ServiceGroups for FreeIPA v2 HBAC rules +- Fix long-standing issue with auth_provider = proxy +- Better logging for TLS issues in LDAP + +* Tue May 18 2010 Stephen Gallagher - 1.1.92-11 +- New LDAP access provider allows for filtering user access by LDAP attribute +- Reduced default timeout for detecting offline status with LDAP +- GSSAPI ticket lifetime made configurable +- Better offline->online transition support in Kerberos + +* Fri May 07 2010 Stephen Gallagher - 1.1.91-10 +- Release new upstream version 1.1.91 +- Enhancements when using SSSD with FreeIPA v2 +- Support for deferred kinit +- Support for DNS SRV records for failover + +* Fri Apr 02 2010 Simo Sorce - 1.1.1-3 +- Bump up release number to avoid library sub-packages version issues with + previous releases. + +* Thu Apr 01 2010 Stephen Gallagher - 1.1.1-1 +- New upstream release 1.1.1 +- Fixed the IPA provider (which was segfaulting at start) +- Fixed a bug in the SSSDConfig API causing some options to revert to +- their defaults +- This impacted the Authconfig UI +- Ensure that SASL binds to LDAP auto-retry when interrupted by a signal + +* Tue Mar 23 2010 Stephen Gallagher - 1.1.0-2 +- Release SSSD 1.1.0 final +- Fix two potential segfaults +- Fix memory leak in monitor +- Better error message for unusable confdb + +* Wed Mar 17 2010 Stephen Gallagher - 1.1.0-1.pre20100317git0ea7f19 +- Release candidate for SSSD 1.1 +- Add simple access provider +- Create subpackages for libcollection, libini_config, libdhash and librefarray +- Support IPv6 +- Support LDAP referrals +- Fix cache issues +- Better feedback from PAM when offline + +* Wed Feb 24 2010 Stephen Gallagehr - 1.0.5-2 +- Rebuild against new libtevent + +* Fri Feb 19 2010 Stephen Gallagher - 1.0.5-1 +- Fix licenses in sources and on RPMs + +* Mon Jan 25 2010 Stephen Gallagher - 1.0.4-1 +- Fix regression on 64-bit platforms + +* Fri Jan 22 2010 Stephen Gallagher - 1.0.3-1 +- Fixes link error on platforms that do not do implicit linking +- Fixes double-free segfault in PAM +- Fixes double-free error in async resolver +- Fixes support for TCP-based DNS lookups in async resolver +- Fixes memory alignment issues on ARM processors +- Manpage fixes + +* Thu Jan 14 2010 Stephen Gallagher - 1.0.2-1 +- Fixes a bug in the failover code that prevented the SSSD from detecting when it went back online +- Fixes a bug causing long (sometimes multiple-minute) waits for NSS requests +- Several segfault bugfixes + +* Mon Jan 11 2010 Stephen Gallagher - 1.0.1-1 +- Fix CVE-2010-0014 + +* Mon Dec 21 2009 Stephen Gallagher - 1.0.0-2 +- Patch SSSDConfig API to address +- https://bugzilla.redhat.com/show_bug.cgi?id=549482 + +* Fri Dec 18 2009 Stephen Gallagher - 1.0.0-1 +- New upstream stable release 1.0.0 + +* Fri Dec 11 2009 Stephen Gallagher - 0.99.1-1 +- New upstream bugfix release 0.99.1 + +* Mon Nov 30 2009 Stephen Gallagher - 0.99.0-1 +- New upstream release 0.99.0 + +* Tue Oct 27 2009 Stephen Gallagher - 0.7.1-1 +- Fix segfault in sssd_pam when cache_credentials was enabled +- Update the sample configuration +- Fix upgrade issues caused by data provider service removal + +* Mon Oct 26 2009 Stephen Gallagher - 0.7.0-2 +- Fix upgrade issues from old (pre-0.5.0) releases of SSSD + +* Fri Oct 23 2009 Stephen Gallagher - 0.7.0-1 +- New upstream release 0.7.0 + +* Thu Oct 15 2009 Stephen Gallagher - 0.6.1-2 +- Fix missing file permissions for sssd-clients + +* Tue Oct 13 2009 Stephen Gallagher - 0.6.1-1 +- Add SSSDConfig API +- Update polish translation for 0.6.0 +- Fix long timeout on ldap operation +- Make dp requests more robust + +* Tue Sep 29 2009 Stephen Gallagher - 0.6.0-1 +- Ensure that the configuration upgrade script always writes the config + file with 0600 permissions +- Eliminate an infinite loop in group enumerations + +* Mon Sep 28 2009 Sumit Bose - 0.6.0-0 +- New upstream release 0.6.0 + +* Mon Aug 24 2009 Simo Sorce - 0.5.0-0 +- New upstream release 0.5.0 + +* Wed Jul 29 2009 Jakub Hrozek - 0.4.1-4 +- Fix for CVE-2009-2410 - Native SSSD users with no password set could log in + without a password. (Patch by Stephen Gallagher) + +* Sun Jul 26 2009 Fedora Release Engineering - 0.4.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Mon Jun 22 2009 Simo Sorce - 0.4.1-2 +- Fix a couple of segfaults that may happen on reload + +* Thu Jun 11 2009 Simo Sorce - 0.4.1-1 +- add missing configure check that broke stopping the daemon +- also fix default config to add a missing required option + +* Mon Jun 8 2009 Simo Sorce - 0.4.1-0 +- latest upstream release. +- also add a patch that fixes debugging output (potential segfault) + +* Mon Apr 20 2009 Simo Sorce - 0.3.2-2 +- release out of the official 0.3.2 tarball + +* Mon Apr 20 2009 Jakub Hrozek - 0.3.2-1 +- bugfix release 0.3.2 +- includes previous release patches +- change permissions of the /etc/sssd/sssd.conf to 0600 + +* Tue Apr 14 2009 Simo Sorce - 0.3.1-2 +- Add last minute bug fixes, found in testing the package + +* Mon Apr 13 2009 Simo Sorce - 0.3.1-1 +- Version 0.3.1 +- includes previous release patches + +* Mon Apr 13 2009 Simo Sorce - 0.3.0-2 +- Try to fix build adding automake as an explicit BuildRequire +- Add also a couple of last minute patches from upstream + +* Mon Apr 13 2009 Simo Sorce - 0.3.0-1 +- Version 0.3.0 +- Provides file based configuration and lots of improvements + +* Tue Mar 10 2009 Simo Sorce - 0.2.1-1 +- Version 0.2.1 + +* Tue Mar 10 2009 Simo Sorce - 0.2.0-1 +- Version 0.2.0 + +* Sun Mar 08 2009 Jakub Hrozek - 0.1.0-5.20090309git691c9b3 +- package git snapshot + +* Fri Mar 06 2009 Jakub Hrozek - 0.1.0-4 +- fixed items found during review +- added initscript + +* Thu Mar 05 2009 Sumit Bose - 0.1.0-3 +- added sss_client + +* Mon Feb 23 2009 Jakub Hrozek - 0.1.0-2 +- Small cleanup and fixes in the spec file + +* Thu Feb 12 2009 Stephen Gallagher - 0.1.0-1 +- Initial release (based on version 0.1.0 upstream code)