diff --git a/.gitignore b/.gitignore index 5a65ef2..2091f63 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ -SOURCES/cert9.db -SOURCES/key4.db -SOURCES/sssd-1.16.0.tar.gz +SOURCES/sssd-1.16.2.tar.gz diff --git a/.sssd.metadata b/.sssd.metadata index d8d858c..7f29762 100644 --- a/.sssd.metadata +++ b/.sssd.metadata @@ -1,3 +1 @@ -52bc755199e2c92ae81a8f93a7c6f2e46715b771 SOURCES/cert9.db -52770a7b7564ef8e0508ae60f5dc238b78e70b99 SOURCES/key4.db -fff74b3798e163a0fe311bdfc4588524afe6dd87 SOURCES/sssd-1.16.0.tar.gz +46c59f189e5ae3286ef7878faf4801068d7bf2a7 SOURCES/sssd-1.16.2.tar.gz diff --git a/SOURCES/0001-NSS-Move-memcache-setup-to-separate-function.patch b/SOURCES/0001-NSS-Move-memcache-setup-to-separate-function.patch deleted file mode 100644 index 0d2e9f4..0000000 --- a/SOURCES/0001-NSS-Move-memcache-setup-to-separate-function.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 82d52dbfd51330cd1fda4734b9e901431e137211 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michal=20=C5=BDidek?= -Date: Thu, 19 Oct 2017 16:39:27 +0200 -Subject: [PATCH 01/21] NSS: Move memcache setup to separate function -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related: -https://pagure.io/SSSD/sssd/issue/3496 - -Reviewed-by: Sumit Bose -Reviewed-by: Pavel Březina -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Jakub Hrozek -(cherry picked from commit 878b0d42aca5839fdc1d97a68ce181e280f1ed7b) ---- - src/responder/nss/nsssrv.c | 91 ++++++++++++++++++++++++++-------------------- - 1 file changed, 51 insertions(+), 40 deletions(-) - -diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c -index d67b9fac8d770d113560e41b259e2d5edd219343..21dd198226da6cf14d7db4941806048662970fed 100644 ---- a/src/responder/nss/nsssrv.c -+++ b/src/responder/nss/nsssrv.c -@@ -252,6 +252,56 @@ static void nss_dp_reconnect_init(struct sbus_connection *conn, - /* nss_shutdown(rctx); */ - } - -+static int setup_memcaches(struct nss_ctx *nctx) -+{ -+ int ret; -+ int memcache_timeout; -+ -+ /* Remove the CLEAR_MC_FLAG file if exists. */ -+ ret = unlink(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG); -+ if (ret != 0 && errno != ENOENT) { -+ ret = errno; -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to unlink file [%s]. This can cause memory cache to " -+ "be purged when next log rotation is requested. %d: %s\n", -+ SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG, ret, strerror(ret)); -+ } -+ -+ ret = confdb_get_int(nctx->rctx->cdb, -+ CONFDB_NSS_CONF_ENTRY, -+ CONFDB_MEMCACHE_TIMEOUT, -+ 300, &memcache_timeout); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "Failed to get 'memcache_timeout' option from confdb.\n"); -+ return ret; -+ } -+ -+ /* TODO: read cache sizes from configuration */ -+ ret = sss_mmap_cache_init(nctx, "passwd", SSS_MC_PASSWD, -+ SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, -+ &nctx->pwd_mc_ctx); -+ if (ret) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n"); -+ } -+ -+ ret = sss_mmap_cache_init(nctx, "group", SSS_MC_GROUP, -+ SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, -+ &nctx->grp_mc_ctx); -+ if (ret) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n"); -+ } -+ -+ ret = sss_mmap_cache_init(nctx, "initgroups", SSS_MC_INITGROUPS, -+ SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, -+ &nctx->initgr_mc_ctx); -+ if (ret) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "initgroups mmap cache is DISABLED\n"); -+ } -+ -+ return EOK; -+} -+ - int nss_process_init(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct confdb_ctx *cdb) -@@ -260,7 +310,6 @@ int nss_process_init(TALLOC_CTX *mem_ctx, - struct sss_cmd_table *nss_cmds; - struct be_conn *iter; - struct nss_ctx *nctx; -- int memcache_timeout; - int ret, max_retries; - enum idmap_error_code err; - int fd_limit; -@@ -330,49 +379,11 @@ int nss_process_init(TALLOC_CTX *mem_ctx, - goto fail; - } - -- /* create mmap caches */ -- /* Remove the CLEAR_MC_FLAG file if exists. */ -- ret = unlink(SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG); -- if (ret != 0 && errno != ENOENT) { -- ret = errno; -- DEBUG(SSSDBG_CRIT_FAILURE, -- "Failed to unlink file [%s]. This can cause memory cache to " -- "be purged when next log rotation is requested. %d: %s\n", -- SSS_NSS_MCACHE_DIR"/"CLEAR_MC_FLAG, ret, strerror(ret)); -- } -- -- ret = confdb_get_int(nctx->rctx->cdb, -- CONFDB_NSS_CONF_ENTRY, -- CONFDB_MEMCACHE_TIMEOUT, -- 300, &memcache_timeout); -+ ret = setup_memcaches(nctx); - if (ret != EOK) { -- DEBUG(SSSDBG_FATAL_FAILURE, -- "Failed to get 'memcache_timeout' option from confdb.\n"); - goto fail; - } - -- /* TODO: read cache sizes from configuration */ -- ret = sss_mmap_cache_init(nctx, "passwd", SSS_MC_PASSWD, -- SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, -- &nctx->pwd_mc_ctx); -- if (ret) { -- DEBUG(SSSDBG_CRIT_FAILURE, "passwd mmap cache is DISABLED\n"); -- } -- -- ret = sss_mmap_cache_init(nctx, "group", SSS_MC_GROUP, -- SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, -- &nctx->grp_mc_ctx); -- if (ret) { -- DEBUG(SSSDBG_CRIT_FAILURE, "group mmap cache is DISABLED\n"); -- } -- -- ret = sss_mmap_cache_init(nctx, "initgroups", SSS_MC_INITGROUPS, -- SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, -- &nctx->initgr_mc_ctx); -- if (ret) { -- DEBUG(SSSDBG_CRIT_FAILURE, "initgroups mmap cache is DISABLED\n"); -- } -- - /* Set up file descriptor limits */ - ret = confdb_get_int(nctx->rctx->cdb, - CONFDB_NSS_CONF_ENTRY, --- -2.13.5 - diff --git a/SOURCES/0001-krb5-locator-add-support-for-multiple-addresses.patch b/SOURCES/0001-krb5-locator-add-support-for-multiple-addresses.patch new file mode 100644 index 0000000..747c2f2 --- /dev/null +++ b/SOURCES/0001-krb5-locator-add-support-for-multiple-addresses.patch @@ -0,0 +1,468 @@ +From 4b1137562c3446e85a6383010702850f9532a4f2 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 24 Feb 2017 13:55:47 +0100 +Subject: [PATCH] krb5 locator: add support for multiple addresses + +Read multiple addresses from the kdcinfo files add call the provided +callback with each of them. + +Related to https://pagure.io/SSSD/sssd/issue/941 +Reviewed-by: Jakub Hrozek + +(cherry picked from commit efae9509cb05648357e9b4c10a93c0d38558bed4) + +DOWNSTREAM: +Resolves: rhbz#1494690 - kdcinfo files are not created for subdomains of a directly joined AD client +--- + src/krb5_plugin/sssd_krb5_locator_plugin.c | 344 +++++++++++++++------ + 1 file changed, 246 insertions(+), 98 deletions(-) + +diff --git a/src/krb5_plugin/sssd_krb5_locator_plugin.c b/src/krb5_plugin/sssd_krb5_locator_plugin.c +index 7c17fcb33373293fbbbe2be967dca57b31ef13de..82fb5c7b2ffa319ed250e54cdf9a0b6798d4ff51 100644 +--- a/src/krb5_plugin/sssd_krb5_locator_plugin.c ++++ b/src/krb5_plugin/sssd_krb5_locator_plugin.c +@@ -42,7 +42,7 @@ + #define DEFAULT_KADMIN_PORT 749 + #define DEFAULT_KPASSWD_PORT 464 + +-#define BUFSIZE 512 ++#define BUFSIZE 4096 + #define PORT_STR_SIZE 7 + #define SSSD_KRB5_LOCATOR_DEBUG "SSSD_KRB5_LOCATOR_DEBUG" + #define SSSD_KRB5_LOCATOR_DISABLE "SSSD_KRB5_LOCATOR_DISABLE" +@@ -53,12 +53,15 @@ + } \ + } while(0) + ++struct addr_port { ++ char *addr; ++ uint16_t port; ++}; ++ + struct sssd_ctx { + char *sssd_realm; +- char *kdc_addr; +- uint16_t kdc_port; +- char *kpasswd_addr; +- uint16_t kpasswd_port; ++ struct addr_port *kdc_addr; ++ struct addr_port *kpasswd_addr; + bool debug; + bool disabled; + }; +@@ -82,6 +85,186 @@ void plugin_debug_fn(const char *format, ...) + free(s); + } + ++ ++static void free_addr_port_list(struct addr_port **list) ++{ ++ size_t c; ++ ++ if (list == NULL || *list == NULL) { ++ return; ++ } ++ ++ for (c = 0; (*list)[c].addr != NULL; c++) { ++ free((*list)[c].addr); ++ } ++ free(*list); ++ *list = NULL; ++} ++ ++static int copy_addr_port_list(struct addr_port *src, bool clear_port, ++ struct addr_port **dst) ++{ ++ size_t c; ++ struct addr_port *d = NULL; ++ int ret; ++ ++ /* only copy if dst is initialized to NULL */ ++ if (dst == NULL || *dst != NULL) { ++ return EINVAL; ++ } ++ ++ if (src == NULL) { ++ return 0; ++ } ++ ++ for (c = 0; src[c].addr != NULL; c++); ++ ++ d = calloc((c + 1), sizeof(struct addr_port)); ++ if (d == NULL) { ++ return ENOMEM; ++ } ++ ++ for (c = 0; src[c].addr != NULL; c++) { ++ d[c].addr = strdup(src[c].addr); ++ if (d[c].addr == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ if (clear_port) { ++ d[c].port = 0; ++ } else { ++ d[c].port = src[c].port; ++ } ++ } ++ ++ ret = EOK; ++ ++done: ++ if (ret != EOK) { ++ free_addr_port_list(&d); ++ } else { ++ *dst = d; ++ } ++ ++ return ret; ++} ++ ++static int buf_to_addr_port_list(struct sssd_ctx *ctx, ++ uint8_t *buf, size_t buf_size, ++ struct addr_port **list) ++{ ++ struct addr_port *l = NULL; ++ int ret; ++ uint8_t *p; ++ uint8_t *pn; ++ size_t c; ++ size_t len; ++ char *tmp = NULL; ++ char *port_str; ++ long port; ++ char *endptr; ++ ++ /* only create if list is initialized to NULL */ ++ if (buf == NULL || buf_size == 0 || list == NULL || *list != NULL) { ++ return EINVAL; ++ } ++ ++ c = 1; /* to account for a missing \n at the very end */ ++ p = buf; ++ while ((p - buf) < buf_size ++ && (p = memchr(p, '\n', buf_size - (p - buf))) != NULL) { ++ p++; ++ c++; ++ } ++ ++ l = calloc((c + 1), sizeof(struct addr_port)); ++ if (l == NULL) { ++ return ENOMEM; ++ } ++ ++ c = 0; ++ p = buf; ++ do { ++ pn = memchr(p, '\n', buf_size - (p - buf)); ++ if (pn != NULL) { ++ len = pn - p; ++ } else { ++ len = buf_size - (p - buf); ++ } ++ if (len == 0) { ++ /* empty line no more processing */ ++ break; ++ } ++ ++ free(tmp); ++ tmp = strndup((char *) p, len); ++ if (tmp == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ port_str = strrchr(tmp, ':'); ++ if (port_str == NULL) { ++ port = 0; ++ } else { ++ *port_str = '\0'; ++ ++port_str; ++ ++ if (isdigit(*port_str)) { ++ errno = 0; ++ port = strtol(port_str, &endptr, 10); ++ if (errno != 0) { ++ ret = errno; ++ PLUGIN_DEBUG(("strtol failed on [%s]: [%d][%s], " ++ "assuming default.\n", port_str, ret, ++ strerror(ret))); ++ port = 0; ++ } ++ if (*endptr != '\0') { ++ PLUGIN_DEBUG(("Found additional characters [%s] in port " ++ "number [%s], assuming default.\n", endptr, ++ port_str)); ++ port = 0; ++ } ++ ++ if (port < 0 || port > 65535) { ++ PLUGIN_DEBUG(("Illegal port number [%ld], assuming " ++ "default.\n", port)); ++ port = 0; ++ } ++ } else { ++ PLUGIN_DEBUG(("Illegal port number [%s], assuming default.\n", ++ port_str)); ++ port = 0; ++ } ++ } ++ ++ PLUGIN_DEBUG(("Found [%s][%d].\n", tmp, port)); ++ ++ l[c].addr = strdup(tmp); ++ if (l[c].addr == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ l[c].port = port; ++ ++ c++; ++ p = pn == NULL ? NULL : (pn + 1); ++ } while (p != NULL); ++ ++ ret = EOK; ++ ++done: ++ free(tmp); ++ if (ret != EOK) { ++ free_addr_port_list(&l); ++ } else { ++ *list = l; ++ } ++ ++ return ret; ++} ++ + static int get_krb5info(const char *realm, struct sssd_ctx *ctx, + enum locate_service_type svc) + { +@@ -91,9 +274,6 @@ static int get_krb5info(const char *realm, struct sssd_ctx *ctx, + uint8_t buf[BUFSIZE + 1]; + int fd = -1; + const char *name_tmpl = NULL; +- char *port_str; +- long port; +- char *endptr; + + switch (svc) { + case locate_service_kdc: +@@ -148,62 +328,21 @@ static int get_krb5info(const char *realm, struct sssd_ctx *ctx, + PLUGIN_DEBUG(("Content of krb5info file [%s] is [%d] or larger.\n", + krb5info_name, BUFSIZE)); + } +- PLUGIN_DEBUG(("Found [%s] in [%s].\n", buf, krb5info_name)); +- +- port_str = strrchr((char *) buf, ':'); +- if (port_str == NULL) { +- port = 0; +- } else { +- *port_str = '\0'; +- ++port_str; +- +- if (isdigit(*port_str)) { +- errno = 0; +- port = strtol(port_str, &endptr, 10); +- if (errno != 0) { +- ret = errno; +- PLUGIN_DEBUG(("strtol failed on [%s]: [%d][%s], " +- "assuming default.\n", port_str, ret, strerror(ret))); +- port = 0; +- } +- if (*endptr != '\0') { +- PLUGIN_DEBUG(("Found additional characters [%s] in port number " +- "[%s], assuming default.\n", endptr, port_str)); +- port = 0; +- } +- +- if (port < 0 || port > 65535) { +- PLUGIN_DEBUG(("Illegal port number [%ld], assuming default.\n", +- port)); +- port = 0; +- } +- } else { +- PLUGIN_DEBUG(("Illegal port number [%s], assuming default.\n", +- port_str)); +- port = 0; +- } +- } + + switch (svc) { + case locate_service_kdc: +- free(ctx->kdc_addr); +- ctx->kdc_addr = strdup((char *) buf); +- if (ctx->kdc_addr == NULL) { +- PLUGIN_DEBUG(("strdup failed.\n")); +- ret = ENOMEM; ++ free_addr_port_list(&(ctx->kdc_addr)); ++ ret = buf_to_addr_port_list(ctx, buf, len, &(ctx->kdc_addr)); ++ if (ret != EOK) { + goto done; + } +- ctx->kdc_port = (uint16_t) port; + break; + case locate_service_kpasswd: +- free(ctx->kpasswd_addr); +- ctx->kpasswd_addr = strdup((char *) buf); +- if (ctx->kpasswd_addr == NULL) { +- PLUGIN_DEBUG(("strdup failed.\n")); +- ret = ENOMEM; ++ free_addr_port_list(&(ctx->kpasswd_addr)); ++ ret = buf_to_addr_port_list(ctx, buf, len, &(ctx->kpasswd_addr)); ++ if (ret != EOK) { + goto done; + } +- ctx->kpasswd_port = (uint16_t) port; + break; + default: + PLUGIN_DEBUG(("Unsupported service [%d].\n", svc)); +@@ -256,8 +395,8 @@ void sssd_krb5_locator_close(void *private_data) + ctx = (struct sssd_ctx *) private_data; + PLUGIN_DEBUG(("sssd_krb5_locator_close called\n")); + +- free(ctx->kdc_addr); +- free(ctx->kpasswd_addr); ++ free_addr_port_list(&(ctx->kdc_addr)); ++ free_addr_port_list(&(ctx->kpasswd_addr)); + free(ctx->sssd_realm); + free(ctx); + +@@ -277,8 +416,10 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data, + struct sssd_ctx *ctx; + struct addrinfo ai_hints; + uint16_t port = 0; +- const char *addr = NULL; ++ uint16_t default_port = 0; ++ struct addr_port *addr = NULL; + char port_str[PORT_STR_SIZE]; ++ size_t c; + + if (private_data == NULL) return KRB5_PLUGIN_NO_HANDLE; + ctx = (struct sssd_ctx *) private_data; +@@ -308,9 +449,13 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data, + if (ret != EOK) { + PLUGIN_DEBUG(("reading kpasswd address failed, " + "using kdc address.\n")); +- free(ctx->kpasswd_addr); +- ctx->kpasswd_addr = strdup(ctx->kdc_addr); +- ctx->kpasswd_port = 0; ++ free_addr_port_list(&(ctx->kpasswd_addr)); ++ ret = copy_addr_port_list(ctx->kdc_addr, true, ++ &(ctx->kpasswd_addr)); ++ if (ret != EOK) { ++ PLUGIN_DEBUG(("copying address list failed.\n")); ++ return KRB5_PLUGIN_NO_HANDLE; ++ } + } + } + } +@@ -322,19 +467,19 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data, + switch (svc) { + case locate_service_kdc: + addr = ctx->kdc_addr; +- port = ctx->kdc_port ? ctx->kdc_port : DEFAULT_KERBEROS_PORT; ++ default_port = DEFAULT_KERBEROS_PORT; + break; + case locate_service_master_kdc: + addr = ctx->kpasswd_addr; +- port = DEFAULT_KERBEROS_PORT; ++ default_port = DEFAULT_KERBEROS_PORT; + break; + case locate_service_kadmin: + addr = ctx->kpasswd_addr; +- port = DEFAULT_KADMIN_PORT; ++ default_port = DEFAULT_KADMIN_PORT; + break; + case locate_service_kpasswd: + addr = ctx->kpasswd_addr; +- port = ctx->kpasswd_port ? ctx->kpasswd_port : DEFAULT_KPASSWD_PORT; ++ default_port = DEFAULT_KPASSWD_PORT; + break; + case locate_service_krb524: + return KRB5_PLUGIN_NO_HANDLE; +@@ -362,46 +507,49 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data, + if (strcmp(realm, ctx->sssd_realm) != 0) + return KRB5_PLUGIN_NO_HANDLE; + +- memset(port_str, 0, PORT_STR_SIZE); +- ret = snprintf(port_str, PORT_STR_SIZE-1, "%u", port); +- if (ret < 0 || ret >= (PORT_STR_SIZE-1)) { +- PLUGIN_DEBUG(("snprintf failed.\n")); +- return KRB5_PLUGIN_NO_HANDLE; +- } +- +- memset(&ai_hints, 0, sizeof(struct addrinfo)); +- ai_hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV; +- ai_hints.ai_socktype = socktype; +- +- ret = getaddrinfo(addr, port_str, &ai_hints, &ai); +- if (ret != 0) { +- PLUGIN_DEBUG(("getaddrinfo failed [%d][%s].\n", ret, +- gai_strerror(ret))); +- if (ret == EAI_SYSTEM) { +- PLUGIN_DEBUG(("getaddrinfo failed [%d][%s].\n", errno, +- strerror(errno))); ++ for (c = 0; addr[c].addr != NULL; c++) { ++ port = (addr[c].port == 0 ? default_port : addr[c].port); ++ memset(port_str, 0, PORT_STR_SIZE); ++ ret = snprintf(port_str, PORT_STR_SIZE-1, "%u", port); ++ if (ret < 0 || ret >= (PORT_STR_SIZE-1)) { ++ PLUGIN_DEBUG(("snprintf failed.\n")); ++ return KRB5_PLUGIN_NO_HANDLE; + } +- return KRB5_PLUGIN_NO_HANDLE; +- } + +- PLUGIN_DEBUG(("addr[%s:%s] family[%d] socktype[%d]\n", addr, port_str, +- ai->ai_family, ai->ai_socktype)); ++ memset(&ai_hints, 0, sizeof(struct addrinfo)); ++ ai_hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV; ++ ai_hints.ai_socktype = socktype; + +- if ((family == AF_UNSPEC || ai->ai_family == family) && +- ai->ai_socktype == socktype) { +- +- ret = cbfunc(cbdata, socktype, ai->ai_addr); ++ ret = getaddrinfo(addr[c].addr, port_str, &ai_hints, &ai); + if (ret != 0) { +- PLUGIN_DEBUG(("cbfunc failed\n")); +- freeaddrinfo(ai); +- return ret; ++ PLUGIN_DEBUG(("getaddrinfo failed [%d][%s].\n", ret, ++ gai_strerror(ret))); ++ if (ret == EAI_SYSTEM) { ++ PLUGIN_DEBUG(("getaddrinfo failed [%d][%s].\n", ++ errno, strerror(errno))); ++ } ++ return KRB5_PLUGIN_NO_HANDLE; ++ } ++ ++ PLUGIN_DEBUG(("addr[%s:%s] family[%d] socktype[%d]\n", addr[c].addr, ++ port_str, ai->ai_family, ai->ai_socktype)); ++ ++ if ((family == AF_UNSPEC || ai->ai_family == family) && ++ ai->ai_socktype == socktype) { ++ ++ ret = cbfunc(cbdata, socktype, ai->ai_addr); ++ if (ret != 0) { ++ PLUGIN_DEBUG(("cbfunc failed\n")); ++ freeaddrinfo(ai); ++ return ret; ++ } else { ++ PLUGIN_DEBUG(("[%s] used\n", addr[c].addr)); ++ } + } else { +- PLUGIN_DEBUG(("[%s] used\n", addr)); ++ PLUGIN_DEBUG(("[%s] NOT used\n", addr[c].addr)); + } +- } else { +- PLUGIN_DEBUG(("[%s] NOT used\n", addr)); ++ freeaddrinfo(ai); + } +- freeaddrinfo(ai); + + return 0; + } +-- +2.17.1 + diff --git a/SOURCES/0002-NSS-Specify-memcache_timeout-0-semantics.patch b/SOURCES/0002-NSS-Specify-memcache_timeout-0-semantics.patch deleted file mode 100644 index 6fb4dca..0000000 --- a/SOURCES/0002-NSS-Specify-memcache_timeout-0-semantics.patch +++ /dev/null @@ -1,118 +0,0 @@ -From f23a358915cfa27669c019fe0df21cce8851459e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michal=20=C5=BDidek?= -Date: Thu, 19 Oct 2017 16:42:19 +0200 -Subject: [PATCH 02/21] NSS: Specify memcache_timeout=0 semantics -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With this patch the memcache files will not be created when -memcache_timeout is set to zero. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3496 - -Reviewed-by: Sumit Bose -Reviewed-by: Pavel Březina -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Jakub Hrozek -(cherry picked from commit ffe29e570a9e885c2f0061c34bb6be2bbd6ab9e4) ---- - src/responder/nss/nsssrv.c | 6 ++++ - src/tests/intg/test_memory_cache.py | 59 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 65 insertions(+) - -diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c -index 21dd198226da6cf14d7db4941806048662970fed..32bfcd69bbb9b35e9932b70a826c4f99ab6a07f3 100644 ---- a/src/responder/nss/nsssrv.c -+++ b/src/responder/nss/nsssrv.c -@@ -277,6 +277,12 @@ static int setup_memcaches(struct nss_ctx *nctx) - return ret; - } - -+ if (memcache_timeout == 0) { -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "Fast in-memory cache will not be initialized."); -+ return EOK; -+ } -+ - /* TODO: read cache sizes from configuration */ - ret = sss_mmap_cache_init(nctx, "passwd", SSS_MC_PASSWD, - SSS_MC_CACHE_ELEMENTS, (time_t)memcache_timeout, -diff --git a/src/tests/intg/test_memory_cache.py b/src/tests/intg/test_memory_cache.py -index c7ba72490174a6ec2257f9d317ac96b35c674779..cac9feb00459957650c5e455db1b2712e17ccd68 100644 ---- a/src/tests/intg/test_memory_cache.py -+++ b/src/tests/intg/test_memory_cache.py -@@ -207,6 +207,32 @@ def fqname_case_insensitive_rfc2307(request, ldap_conn): - return None - - -+@pytest.fixture -+def zero_timeout_rfc2307(request, ldap_conn): -+ load_data_to_ldap(request, ldap_conn) -+ -+ conf = unindent("""\ -+ [sssd] -+ domains = LDAP -+ services = nss -+ -+ [nss] -+ memcache_timeout = 0 -+ -+ [domain/LDAP] -+ ldap_auth_disable_tls_never_use_in_production = true -+ ldap_schema = rfc2307 -+ id_provider = ldap -+ auth_provider = ldap -+ sudo_provider = ldap -+ ldap_uri = {ldap_conn.ds_inst.ldap_url} -+ ldap_search_base = {ldap_conn.ds_inst.base_dn} -+ """).format(**locals()) -+ create_conf_fixture(request, conf) -+ create_sssd_fixture(request) -+ return None -+ -+ - def test_getpwnam(ldap_conn, sanity_rfc2307): - ent.assert_passwd_by_name( - 'user1', -@@ -778,3 +804,36 @@ def test_removed_mc(ldap_conn, sanity_rfc2307): - grp.getgrnam('group1') - with pytest.raises(KeyError): - grp.getgrgid(2001) -+ -+ -+def test_mc_zero_timeout(ldap_conn, zero_timeout_rfc2307): -+ """ -+ Test that the memory cache is not created at all with memcache_timeout=0 -+ """ -+ # No memory cache files must be created -+ assert len(os.listdir(config.MCACHE_PATH)) == 0 -+ -+ ent.assert_passwd_by_name( -+ 'user1', -+ dict(name='user1', passwd='*', uid=1001, gid=2001, -+ gecos='1001', shell='/bin/bash')) -+ ent.assert_passwd_by_uid( -+ 1001, -+ dict(name='user1', passwd='*', uid=1001, gid=2001, -+ gecos='1001', shell='/bin/bash')) -+ -+ ent.assert_group_by_name("group1", dict(name="group1", gid=2001)) -+ ent.assert_group_by_gid(2001, dict(name="group1", gid=2001)) -+ stop_sssd() -+ -+ # sssd is stopped; so the memory cache should not be used -+ # in long living clients (py.test in this case) -+ with pytest.raises(KeyError): -+ pwd.getpwnam('user1') -+ with pytest.raises(KeyError): -+ pwd.getpwuid(1001) -+ -+ with pytest.raises(KeyError): -+ grp.getgrnam('group1') -+ with pytest.raises(KeyError): -+ grp.getgrgid(2001) --- -2.13.5 - diff --git a/SOURCES/0002-krb5-locator-fix-IPv6-support.patch b/SOURCES/0002-krb5-locator-fix-IPv6-support.patch new file mode 100644 index 0000000..f602116 --- /dev/null +++ b/SOURCES/0002-krb5-locator-fix-IPv6-support.patch @@ -0,0 +1,65 @@ +From 45a48b9a73f39e9ef9e622dbcf87cc05a2a54e40 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 22 May 2018 17:59:52 +0200 +Subject: [PATCH] krb5 locator: fix IPv6 support + +IPv6 addresses are added with surrounding '[' and ']' to the kdcinfo +file to be able to specify a port number properly. The Kerberos location +plugin didn't handle those entries properly. + +Related to https://pagure.io/SSSD/sssd/issue/941 +Reviewed-by: Jakub Hrozek + +(cherry picked from commit 9f683246228848173c57ad02bde241bd761481ea) +--- + src/krb5_plugin/sssd_krb5_locator_plugin.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/src/krb5_plugin/sssd_krb5_locator_plugin.c b/src/krb5_plugin/sssd_krb5_locator_plugin.c +index 82fb5c7b2ffa319ed250e54cdf9a0b6798d4ff51..58cac7f4b244903347e6f1811cd8de2d61281c4f 100644 +--- a/src/krb5_plugin/sssd_krb5_locator_plugin.c ++++ b/src/krb5_plugin/sssd_krb5_locator_plugin.c +@@ -159,6 +159,8 @@ static int buf_to_addr_port_list(struct sssd_ctx *ctx, + uint8_t *pn; + size_t c; + size_t len; ++ size_t addr_len; ++ char *addr_str = NULL; + char *tmp = NULL; + char *port_str; + long port; +@@ -206,6 +208,9 @@ static int buf_to_addr_port_list(struct sssd_ctx *ctx, + port_str = strrchr(tmp, ':'); + if (port_str == NULL) { + port = 0; ++ } else if (tmp[0] == '[' && *(port_str - 1) != ']') { ++ /* IPv6 address without port number */ ++ port = 0; + } else { + *port_str = '\0'; + ++port_str; +@@ -239,9 +244,19 @@ static int buf_to_addr_port_list(struct sssd_ctx *ctx, + } + } + +- PLUGIN_DEBUG(("Found [%s][%d].\n", tmp, port)); ++ /* make sure tmp is not modified so that it can be freed later */ ++ addr_str = tmp; ++ /* strip leading '[' and trailing ']' from IPv6 addresses */ ++ if (addr_str[0] == '[' ++ && (addr_len = strlen(addr_str)) ++ && addr_str[addr_len - 1] == ']') { ++ addr_str[addr_len -1] = '\0'; ++ addr_str++; ++ } + +- l[c].addr = strdup(tmp); ++ PLUGIN_DEBUG(("Found [%s][%d].\n", addr_str, port)); ++ ++ l[c].addr = strdup(addr_str); + if (l[c].addr == NULL) { + ret = ENOMEM; + goto done; +-- +2.17.1 + diff --git a/SOURCES/0003-MAN-Document-memcache_timeout-0-meaning.patch b/SOURCES/0003-MAN-Document-memcache_timeout-0-meaning.patch deleted file mode 100644 index a64b5a5..0000000 --- a/SOURCES/0003-MAN-Document-memcache_timeout-0-meaning.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 22bd144b48e83d812dd823298b723983c4e3288a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michal=20=C5=BDidek?= -Date: Thu, 19 Oct 2017 16:46:43 +0200 -Subject: [PATCH 03/21] MAN: Document memcache_timeout=0 meaning -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Document that by setting memcache_timeout to 0 the in-memoory cache -will be disabled. - -Related: -https://pagure.io/SSSD/sssd/issue/3496 - -Reviewed-by: Sumit Bose -Reviewed-by: Pavel Březina -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Jakub Hrozek -(cherry picked from commit 1becbb7bec29a3d418d8f19fc52433cf86bcf395) ---- - src/man/sssd.conf.5.xml | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml -index 7752e450835b5beba50ddc4c635ff985d38ca421..7443f718319e292842c670aaf47cfc537545d021 100644 ---- a/src/man/sssd.conf.5.xml -+++ b/src/man/sssd.conf.5.xml -@@ -974,12 +974,19 @@ fallback_homedir = /home/%u - - - Specifies time in seconds for which records -- in the in-memory cache will be valid. -+ in the in-memory cache will be valid. Setting this -+ option to zero will disable the in-memory cache. - - - Default: 300 - - -+ WARNING: Disabling the in-memory cache will -+ have significant negative impact on SSSD's -+ performance and should only be used for -+ testing. -+ -+ - NOTE: If the environment variable - SSS_NSS_USE_MEMCACHE is set to "NO", client - applications will not use the fast in-memory --- -2.13.5 - diff --git a/SOURCES/0003-krb5-locator-make-plugin-more-robust.patch b/SOURCES/0003-krb5-locator-make-plugin-more-robust.patch new file mode 100644 index 0000000..fb596fb --- /dev/null +++ b/SOURCES/0003-krb5-locator-make-plugin-more-robust.patch @@ -0,0 +1,35 @@ +From 4e851d1391f56c632c271fd21dd96f29565cadfe Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 22 May 2018 18:03:05 +0200 +Subject: [PATCH] krb5 locator: make plugin more robust + +Although currently libkrb5 sets all parameters of the locator plugin +calls to suitable values we should make sure that provided pointers are +not NULL before trying to dereference them. + +Related to https://pagure.io/SSSD/sssd/issue/941 +Reviewed-by: Jakub Hrozek + +(cherry picked from commit c1fbc6b64ecaf51efc4379c4c8a4960de095abf0) +--- + src/krb5_plugin/sssd_krb5_locator_plugin.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/krb5_plugin/sssd_krb5_locator_plugin.c b/src/krb5_plugin/sssd_krb5_locator_plugin.c +index 58cac7f4b244903347e6f1811cd8de2d61281c4f..9874fd2d1ce63b69099f057dd05f6e353a12ce75 100644 +--- a/src/krb5_plugin/sssd_krb5_locator_plugin.c ++++ b/src/krb5_plugin/sssd_krb5_locator_plugin.c +@@ -439,6 +439,10 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data, + if (private_data == NULL) return KRB5_PLUGIN_NO_HANDLE; + ctx = (struct sssd_ctx *) private_data; + ++ if (realm == NULL || cbfunc == NULL || cbdata == NULL) { ++ return KRB5_PLUGIN_NO_HANDLE; ++ } ++ + if (ctx->disabled) { + PLUGIN_DEBUG(("Plugin disabled, nothing to do.\n")); + return KRB5_PLUGIN_NO_HANDLE; +-- +2.17.1 + diff --git a/SOURCES/0004-CONFIG-Add-a-new-option-auto_private_groups.patch b/SOURCES/0004-CONFIG-Add-a-new-option-auto_private_groups.patch deleted file mode 100644 index 9f2a67d..0000000 --- a/SOURCES/0004-CONFIG-Add-a-new-option-auto_private_groups.patch +++ /dev/null @@ -1,159 +0,0 @@ -From 1deab05ac0820d9be261b55027a90078a758febd Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 3 Oct 2017 12:34:33 +0200 -Subject: [PATCH 04/21] CONFIG: Add a new option auto_private_groups -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The auto_private_groups option is used to configure the domain->mpg flag -which was already set automatically for subdomains, but for some time was -not settable by the admin via the configuration file. - -The new option name, instead of the old magic_private_groups, was chosen -purely because this name would hopefully be better understood by admins. - -The option doesn't do anything yet, it is just added to all the places a -new option should be added to. - -Related: - https://pagure.io/SSSD/sssd/issue/1872 - -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Pavel Březina -(cherry picked from commit d72ac2c58360cd272277b5ddde67bbff53106a74) ---- - src/confdb/confdb.c | 8 ++++++++ - src/confdb/confdb.h | 1 + - src/config/SSSDConfig/__init__.py.in | 1 + - src/config/SSSDConfigTest.py | 6 ++++-- - src/config/cfg_rules.ini | 1 + - src/config/etc/sssd.api.conf | 1 + - src/man/sssd.conf.5.xml | 20 ++++++++++++++++++++ - 7 files changed, 36 insertions(+), 2 deletions(-) - -diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c -index fefecc03d554f6eca12efe07990bfae17033bd02..a028224817f12ace2a0c4165d7b9cb0bb80ce5a1 100644 ---- a/src/confdb/confdb.c -+++ b/src/confdb/confdb.c -@@ -936,6 +936,14 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb, - goto done; - } - -+ ret = get_entry_as_bool(res->msgs[0], &domain->mpg, -+ CONFDB_DOMAIN_AUTO_UPG, 0); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "Invalid value for %s\n", CONFDB_DOMAIN_AUTO_UPG); -+ goto done; -+ } -+ - if (strcasecmp(domain->provider, "local") == 0) { - /* If this is the local provider, we need to ensure that - * no other provider was specified for other types, since -diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h -index bcea99ae49a3fa5f0393ce6b2c215b5b2d4bc3fc..2539b906993edbceb38aac9265e04deed69cf2e4 100644 ---- a/src/confdb/confdb.h -+++ b/src/confdb/confdb.h -@@ -198,6 +198,7 @@ - #define CONFDB_DEFAULT_CACHE_CREDS_MIN_FF_LENGTH 8 - #define CONFDB_DOMAIN_LEGACY_PASS "store_legacy_passwords" - #define CONFDB_DOMAIN_MPG "magic_private_groups" -+#define CONFDB_DOMAIN_AUTO_UPG "auto_private_groups" - #define CONFDB_DOMAIN_FQ "use_fully_qualified_names" - #define CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT "entry_cache_timeout" - #define CONFDB_DOMAIN_ACCOUNT_CACHE_EXPIRATION "account_cache_expiration" -diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in -index d99b718e09283d113f73639e0f94e7f1cec55f68..d2bb709d69c8790558b5c06a7e405463b508c189 100644 ---- a/src/config/SSSDConfig/__init__.py.in -+++ b/src/config/SSSDConfig/__init__.py.in -@@ -195,6 +195,7 @@ option_strings = { - 'cached_auth_timeout' : _('How long can cached credentials be used for cached authentication'), - 'full_name_format' : _('Printf-compatible format for displaying fully-qualified names'), - 're_expression' : _('Regex to parse username and domain'), -+ 'auto_private_groups' : _('Whether to automatically create private groups for users'), - - # [provider/ipa] - 'ipa_domain' : _('IPA domain'), -diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py -index 4a583bdd3124dc05a116d2e6bd48afb92aa0b54d..87d1f6e6410dfeafc77d578cf0b950dc71a1f0a2 100755 ---- a/src/config/SSSDConfigTest.py -+++ b/src/config/SSSDConfigTest.py -@@ -624,7 +624,8 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): - 'subdomain_homedir', - 'full_name_format', - 're_expression', -- 'cached_auth_timeout'] -+ 'cached_auth_timeout', -+ 'auto_private_groups'] - - self.assertTrue(type(options) == dict, - "Options should be a dictionary") -@@ -994,7 +995,8 @@ class SSSDConfigTestSSSDDomain(unittest.TestCase): - 'subdomain_homedir', - 'full_name_format', - 're_expression', -- 'cached_auth_timeout'] -+ 'cached_auth_timeout', -+ 'auto_private_groups'] - - self.assertTrue(type(options) == dict, - "Options should be a dictionary") -diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini -index e49e8d43f4aead14d833866110784fd62382cc2b..4e70bf7b6f0fa7421a0c35bd4279830265bf3470 100644 ---- a/src/config/cfg_rules.ini -+++ b/src/config/cfg_rules.ini -@@ -382,6 +382,7 @@ option = cached_auth_timeout - option = wildcard_limit - option = full_name_format - option = re_expression -+option = auto_private_groups - - #Entry cache timeouts - option = entry_cache_user_timeout -diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf -index 7f2b8977b7e67fcfc20df49056cda8ebe6da0be8..2be2e3e685ba3abd9a4a419f93332a89ff774262 100644 ---- a/src/config/etc/sssd.api.conf -+++ b/src/config/etc/sssd.api.conf -@@ -185,6 +185,7 @@ subdomain_homedir = str, None, false - cached_auth_timeout = int, None, false - full_name_format = str, None, false - re_expression = str, None, false -+auto_private_groups = str, None, false - - #Entry cache timeouts - entry_cache_user_timeout = int, None, false -diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml -index 7443f718319e292842c670aaf47cfc537545d021..47da07c33bdcfbf2fa94ff932492e9ea4bbfe846 100644 ---- a/src/man/sssd.conf.5.xml -+++ b/src/man/sssd.conf.5.xml -@@ -2823,6 +2823,26 @@ subdomain_inherit = ldap_purge_cache_timeout - - - -+ -+ auto_private_groups (string) -+ -+ -+ If this option is enabled, SSSD will automatically -+ create user private groups based on user's -+ UID number. The GID number is ignored in this case. -+ -+ -+ NOTE: Because the GID number and the user private group -+ are inferred frm the UID number, it is not supported -+ to have multiple entries with the same UID or GID number -+ with this option. In other words, enabling this option -+ enforces uniqueness across the ID space. -+ -+ -+ Default: False -+ -+ -+ - - - --- -2.13.5 - diff --git a/SOURCES/0004-krb5-locator-add-unit-tests.patch b/SOURCES/0004-krb5-locator-add-unit-tests.patch new file mode 100644 index 0000000..28fe091 --- /dev/null +++ b/SOURCES/0004-krb5-locator-add-unit-tests.patch @@ -0,0 +1,724 @@ +From 3d6b8b306cdbd4ec15b36a1e7936d219204e08dc Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 24 May 2018 17:14:42 +0200 +Subject: [PATCH] krb5 locator: add unit tests + +Unit test for existing and new functionality of the Kerberos locator +plugin. + +Related to https://pagure.io/SSSD/sssd/issue/941 +Reviewed-by: Jakub Hrozek + +(cherry picked from commit 2124275fe494a0241a552538c70f40c2291f3795) +--- + Makefile.am | 20 + + src/krb5_plugin/sssd_krb5_locator_plugin.c | 16 + + .../cmocka/test_sssd_krb5_locator_plugin.c | 631 ++++++++++++++++++ + 3 files changed, 667 insertions(+) + create mode 100644 src/tests/cmocka/test_sssd_krb5_locator_plugin.c + +diff --git a/Makefile.am b/Makefile.am +index 9539b3cff8544cf406e3e19ab23e76e9cc8234ee..9055130ed74057987795285c243ff47584cf8316 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -288,6 +288,7 @@ if HAVE_CMOCKA + krb5_common_test \ + test_iobuf \ + sss_certmap_test \ ++ test_sssd_krb5_locator_plugin \ + $(NULL) + + +@@ -3518,6 +3519,25 @@ sss_certmap_test_LDADD = \ + libsss_certmap.la \ + $(NULL) + ++test_sssd_krb5_locator_plugin_SOURCES = \ ++ src/tests/cmocka/test_sssd_krb5_locator_plugin.c \ ++ src/krb5_plugin/sssd_krb5_locator_plugin.c \ ++ $(NULL) ++test_sssd_krb5_locator_plugin_CFLAGS = \ ++ $(AM_CFLAGS) \ ++ $(POPT_CFLAGS) \ ++ $(TALLOC_CFLAGS) \ ++ $(KRB5_CFLAGS) \ ++ -DTEST_PUBCONF_PATH=\"$(abs_builddir)/src/tests/cmocka/pubconf\" \ ++ $(NULL) ++test_sssd_krb5_locator_plugin_LDADD = \ ++ $(CMOCKA_LIBS) \ ++ $(POPT_LIBS) \ ++ $(TALLOC_LIBS) \ ++ $(KRB5_LIBS) \ ++ libsss_test_common.la \ ++ $(NULL) ++ + if BUILD_KCM + test_kcm_json_SOURCES = \ + src/tests/cmocka/test_kcm_json_marshalling.c \ +diff --git a/src/krb5_plugin/sssd_krb5_locator_plugin.c b/src/krb5_plugin/sssd_krb5_locator_plugin.c +index 9874fd2d1ce63b69099f057dd05f6e353a12ce75..952d487c276ed51e0c3a018b0d0af59ca214525f 100644 +--- a/src/krb5_plugin/sssd_krb5_locator_plugin.c ++++ b/src/krb5_plugin/sssd_krb5_locator_plugin.c +@@ -38,6 +38,22 @@ + + #include "providers/krb5/krb5_common.h" + ++/* The following override of KDCINFO_TMPL and KPASSWDINFO_TMPL is not very ++ * elegant but since they are defined in krb5_common.h with the help of ++ * PUBCONF_PATH from config.h and PUBCONF_PATH can by set by a configure ++ * options I didn't found another way to change the path for a unit test. */ ++#ifdef TEST_PUBCONF_PATH ++#ifdef KDCINFO_TMPL ++#undef KDCINFO_TMPL ++#endif ++#define KDCINFO_TMPL TEST_PUBCONF_PATH"/kdcinfo.%s" ++ ++#ifdef KPASSWDINFO_TMPL ++#undef KPASSWDINFO_TMPL ++#endif ++#define KPASSWDINFO_TMPL TEST_PUBCONF_PATH"/kpasswdinfo.%s" ++#endif /* TEST_PUBCONF_PATH */ ++ + #define DEFAULT_KERBEROS_PORT 88 + #define DEFAULT_KADMIN_PORT 749 + #define DEFAULT_KPASSWD_PORT 464 +diff --git a/src/tests/cmocka/test_sssd_krb5_locator_plugin.c b/src/tests/cmocka/test_sssd_krb5_locator_plugin.c +new file mode 100644 +index 0000000000000000000000000000000000000000..3e7d00632ddb59da5474c0544eee6fc67edc5570 +--- /dev/null ++++ b/src/tests/cmocka/test_sssd_krb5_locator_plugin.c +@@ -0,0 +1,631 @@ ++/* ++ SSSD ++ ++ Unit test for SSSD's MIT Kerberos locator plugin ++ ++ Authors: ++ Sumit Bose ++ ++ 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 "config.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "tests/cmocka/common_mock.h" ++ ++#define TEST_REALM "TEST.REALM" ++#define TEST_IP_1 "123.231.132.213" ++#define TEST_IPV6_1_PURE "7025:4d2d:2b06:e321:d971:16c0:6eeb:cc41" ++#define TEST_IPV6_1 "["TEST_IPV6_1_PURE"]" ++#define TEST_SERVICE_1 "22334" ++#define TEST_SERVICE_2 "54321" ++#define TEST_IP_1_WITH_SERVICE TEST_IP_1":"TEST_SERVICE_1 ++#define TEST_IPV6_1_WITH_SERVICE TEST_IPV6_1":"TEST_SERVICE_2 ++ ++struct test_state { ++ void *dummy; ++}; ++ ++static int setup(void **state) ++{ ++ struct test_state *ts = NULL; ++ ++ assert_true(leak_check_setup()); ++ ++ ts = talloc(global_talloc_context, struct test_state); ++ assert_non_null(ts); ++ ++ check_leaks_push(ts); ++ *state = (void *)ts; ++ ++ unlink(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM); ++ rmdir(TEST_PUBCONF_PATH); ++ ++ return 0; ++} ++ ++static int teardown(void **state) ++{ ++ struct test_state *ts = talloc_get_type_abort(*state, struct test_state); ++ ++ assert_non_null(ts); ++ ++ assert_true(check_leaks_pop(ts)); ++ talloc_free(ts); ++ assert_true(leak_check_teardown()); ++ return 0; ++} ++ ++/* Taken from MIT Kerberos src/lib/krb5/os/locate_kdc.c and ++ * lib/krb5/os/os-proto.h */ ++ ++typedef enum { ++ TCP_OR_UDP = 0, ++ TCP, ++ UDP, ++ HTTPS, ++} k5_transport; ++ ++/* A single server hostname or address. */ ++struct server_entry { ++ char *hostname; /* NULL -> use addrlen/addr instead */ ++ int port; /* Used only if hostname set */ ++ k5_transport transport; /* May be 0 for UDP/TCP if hostname set */ ++ char *uri_path; /* Used only if transport is HTTPS */ ++ int family; /* May be 0 (aka AF_UNSPEC) if hostname set */ ++ int master; /* True, false, or -1 for unknown. */ ++ size_t addrlen; ++ struct sockaddr_storage addr; ++}; ++ ++/* A list of server hostnames/addresses. */ ++struct serverlist { ++ struct server_entry *servers; ++ size_t nservers; ++}; ++#define SERVERLIST_INIT { NULL, 0 } ++ ++/* Free up everything pointed to by the serverlist structure, but don't ++ * * free the structure itself. */ ++void ++k5_free_serverlist (struct serverlist *list) ++{ ++ size_t i; ++ ++ for (i = 0; i < list->nservers; i++) { ++ free(list->servers[i].hostname); ++ free(list->servers[i].uri_path); ++ } ++ free(list->servers); ++ list->servers = NULL; ++ list->nservers = 0; ++} ++ ++/* Make room for a new server entry in list and return a pointer to the new ++ * entry. (Do not increment list->nservers.) */ ++static struct server_entry * ++new_server_entry(struct serverlist *list) ++{ ++ struct server_entry *newservers, *entry; ++ size_t newspace = (list->nservers + 1) * sizeof(struct server_entry); ++ ++ newservers = realloc(list->servers, newspace); ++ if (newservers == NULL) ++ return NULL; ++ list->servers = newservers; ++ entry = &newservers[list->nservers]; ++ memset(entry, 0, sizeof(*entry)); ++ entry->master = -1; ++ return entry; ++} ++ ++/* Add an address entry to list. */ ++static int ++add_addr_to_list(struct serverlist *list, k5_transport transport, int family, ++ size_t addrlen, struct sockaddr *addr) ++{ ++ struct server_entry *entry; ++ ++ entry = new_server_entry(list); ++ if (entry == NULL) ++ return ENOMEM; ++ entry->transport = transport; ++ entry->family = family; ++ entry->hostname = NULL; ++ entry->uri_path = NULL; ++ entry->addrlen = addrlen; ++ memcpy(&entry->addr, addr, addrlen); ++ list->nservers++; ++ return 0; ++} ++ ++struct module_callback_data { ++ int out_of_mem; ++ struct serverlist *list; ++}; ++ ++static int ++module_callback(void *cbdata, int socktype, struct sockaddr *sa) ++{ ++ struct module_callback_data *d = cbdata; ++ size_t addrlen; ++ k5_transport transport; ++ ++ if (socktype != SOCK_STREAM && socktype != SOCK_DGRAM) ++ return 0; ++ if (sa->sa_family == AF_INET) ++ addrlen = sizeof(struct sockaddr_in); ++ else if (sa->sa_family == AF_INET6) ++ addrlen = sizeof(struct sockaddr_in6); ++ else ++ return 0; ++ transport = (socktype == SOCK_STREAM) ? TCP : UDP; ++ if (add_addr_to_list(d->list, transport, sa->sa_family, addrlen, ++ sa) != 0) { ++ /* Assumes only error is ENOMEM. */ ++ d->out_of_mem = 1; ++ return 1; ++ } ++ return 0; ++} ++ ++krb5_error_code sssd_krb5_locator_init(krb5_context context, ++ void **private_data); ++void sssd_krb5_locator_close(void *private_data); ++ ++krb5_error_code sssd_krb5_locator_lookup(void *private_data, ++ enum locate_service_type svc, ++ const char *realm, ++ int socktype, ++ int family, ++ int (*cbfunc)(void *, int, struct sockaddr *), ++ void *cbdata); ++ ++void test_init(void **state) ++{ ++ krb5_context ctx; ++ krb5_error_code kerr; ++ void *priv; ++ ++ kerr = krb5_init_context (&ctx); ++ assert_int_equal(kerr, 0); ++ ++ kerr = sssd_krb5_locator_init(ctx, &priv); ++ assert_int_equal(kerr, 0); ++ ++ sssd_krb5_locator_close(priv); ++ ++ krb5_free_context(ctx); ++} ++ ++void test_failed_lookup(void **state) ++{ ++ krb5_context ctx; ++ krb5_error_code kerr; ++ void *priv; ++ struct module_callback_data cbdata = { 0 }; ++ ++ ++ kerr = krb5_init_context (&ctx); ++ assert_int_equal(kerr, 0); ++ ++ kerr = sssd_krb5_locator_init(ctx, &priv); ++ assert_int_equal(kerr, 0); ++ ++ kerr = sssd_krb5_locator_lookup(NULL, -1, NULL, -1, -1, NULL, NULL); ++ assert_int_equal(kerr, KRB5_PLUGIN_NO_HANDLE); ++ ++ kerr = sssd_krb5_locator_lookup(priv, -1, NULL, -1, -1, NULL, NULL); ++ assert_int_equal(kerr, KRB5_PLUGIN_NO_HANDLE); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , NULL, -1, -1, ++ NULL, NULL); ++ assert_int_equal(kerr, KRB5_PLUGIN_NO_HANDLE); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, -1, ++ -1, NULL, NULL); ++ assert_int_equal(kerr, KRB5_PLUGIN_NO_HANDLE); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, -1, NULL, NULL); ++ assert_int_equal(kerr, KRB5_PLUGIN_NO_HANDLE); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_INET6, NULL, NULL); ++ assert_int_equal(kerr, KRB5_PLUGIN_NO_HANDLE); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_INET6, module_callback, ++ NULL); ++ assert_int_equal(kerr, KRB5_PLUGIN_NO_HANDLE); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_INET6, module_callback, ++ &cbdata); ++ assert_int_equal(kerr, KRB5_PLUGIN_NO_HANDLE); ++ ++ sssd_krb5_locator_close(priv); ++ ++ krb5_free_context(ctx); ++} ++ ++void test_empty(void **state) ++{ ++ krb5_context ctx; ++ krb5_error_code kerr; ++ void *priv; ++ int fd; ++ struct module_callback_data cbdata = { 0 }; ++ ++ kerr = krb5_init_context (&ctx); ++ assert_int_equal(kerr, 0); ++ ++ kerr = sssd_krb5_locator_init(ctx, &priv); ++ assert_int_equal(kerr, 0); ++ ++ mkdir(TEST_PUBCONF_PATH, 0777); ++ fd = open(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM, O_CREAT, 0777); ++ assert_int_not_equal(fd, -1); ++ close(fd); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_INET6, module_callback, ++ &cbdata); ++ assert_int_equal(kerr, KRB5_PLUGIN_NO_HANDLE); ++ unlink(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM); ++ rmdir(TEST_PUBCONF_PATH); ++ ++ sssd_krb5_locator_close(priv); ++ ++ krb5_free_context(ctx); ++} ++ ++void test_single(void **state) ++{ ++ krb5_context ctx; ++ krb5_error_code kerr; ++ void *priv; ++ int fd; ++ struct serverlist list = SERVERLIST_INIT; ++ struct module_callback_data cbdata = { 0 }; ++ ssize_t s; ++ int ret; ++ char host[NI_MAXHOST]; ++ char service[NI_MAXSERV]; ++ ++ cbdata.list = &list; ++ ++ kerr = krb5_init_context (&ctx); ++ assert_int_equal(kerr, 0); ++ ++ kerr = sssd_krb5_locator_init(ctx, &priv); ++ assert_int_equal(kerr, 0); ++ ++ mkdir(TEST_PUBCONF_PATH, 0777); ++ fd = open(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM, O_CREAT|O_RDWR, 0777); ++ assert_int_not_equal(fd, -1); ++ s = write(fd, TEST_IP_1, sizeof(TEST_IP_1)); ++ assert_int_equal(s, sizeof(TEST_IP_1)); ++ close(fd); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_INET6, module_callback, ++ &cbdata); ++ assert_int_equal(kerr, 0); ++ ++ /* We asked for AF_INET6, but TEST_IP_1 is IPv4 */ ++ assert_int_equal(list.nservers, 0); ++ assert_null(list.servers); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_INET, module_callback, ++ &cbdata); ++ assert_int_equal(kerr, 0); ++ assert_int_equal(list.nservers, 1); ++ assert_non_null(list.servers); ++ assert_int_equal(list.servers[0].addrlen, 16); ++ ret = getnameinfo((struct sockaddr *) &list.servers[0].addr, ++ list.servers[0].addrlen, ++ host, sizeof(host), service, sizeof(service), ++ NI_NUMERICHOST|NI_NUMERICSERV); ++ assert_int_equal(ret, 0); ++ assert_string_equal(TEST_IP_1, host); ++ assert_string_equal("88", service); ++ ++ k5_free_serverlist(&list); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_UNSPEC, module_callback, ++ &cbdata); ++ assert_int_equal(kerr, 0); ++ assert_int_equal(list.nservers, 1); ++ assert_non_null(list.servers); ++ assert_int_equal(list.servers[0].addrlen, 16); ++ ret = getnameinfo((struct sockaddr *) &list.servers[0].addr, ++ list.servers[0].addrlen, ++ host, sizeof(host), service, sizeof(service), ++ NI_NUMERICHOST|NI_NUMERICSERV); ++ assert_int_equal(ret, 0); ++ assert_string_equal(TEST_IP_1, host); ++ assert_string_equal("88", service); ++ ++ k5_free_serverlist(&list); ++ ++ unlink(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM); ++ rmdir(TEST_PUBCONF_PATH); ++ sssd_krb5_locator_close(priv); ++ ++ krb5_free_context(ctx); ++} ++ ++struct test_data { ++ const char *ip; ++ bool found; ++}; ++ ++void test_multi_check_results(struct test_data *test_data, ++ struct serverlist *list, ++ const char *exp_service) ++{ ++ int ret; ++ char host[NI_MAXHOST]; ++ char service[NI_MAXSERV]; ++ size_t c; ++ size_t d; ++ ++ /* To make sure each result from list has a matching entry in test_data we ++ * use a flag to mark found entries, this way we can properly detect is ++ * the same address is used multiple times. */ ++ for (d = 0; test_data[d].ip != NULL; d++) { ++ test_data[d].found = false; ++ } ++ ++ for (c = 0; c < list->nservers; c++) { ++ ret = getnameinfo((struct sockaddr *) &list->servers[c].addr, ++ list->servers[c].addrlen, ++ host, sizeof(host), service, sizeof(service), ++ NI_NUMERICHOST|NI_NUMERICSERV); ++ assert_int_equal(ret, 0); ++ assert_string_equal(exp_service, service); ++ for (d = 0; test_data[d].ip != NULL; d++) { ++ /* Compare result with test_data, be aware that the test_data has ++ * '[]' around IPv& addresses */ ++ if (strncmp(host, ++ test_data[d].ip + (test_data[d].ip[0] == '[' ? 1 : 0), ++ strlen(host)) == 0 && !test_data[d].found) { ++ test_data[d].found = true; ++ break; ++ } ++ } ++ /* Make sure we found the result in the list */ ++ assert_non_null(test_data[d].ip); ++ } ++} ++ ++void test_multi(void **state) ++{ ++ krb5_context ctx; ++ krb5_error_code kerr; ++ void *priv; ++ int fd; ++ struct serverlist list = SERVERLIST_INIT; ++ struct module_callback_data cbdata = { 0 }; ++ ssize_t s; ++ size_t c; ++ struct test_data test_data[] = { ++ {TEST_IP_1, false}, ++ {TEST_IPV6_1, false}, ++ {"[c89a:565b:4510:5b9f:41fe:ea81:87a0:f21b]", false}, ++ {"155.42.66.53", false}, ++ {"[f812:5941:ba69:2bae:e806:3b68:770d:d75e]", false}, ++ {"[3ad3:9dda:50e4:3c82:548f:eaa1:e120:6dd]", false}, ++ {"55.116.79.183", false}, ++ {"[ce8a:ee99:98cd:d8cd:218d:393e:d5a9:dc52]", false}, ++ /* the following address is added twice to check if ++ * an address can be added more than once. */ ++ {"37.230.88.162", false}, ++ {"37.230.88.162", false}, ++ {NULL, false} }; ++ ++ cbdata.list = &list; ++ ++ kerr = krb5_init_context (&ctx); ++ assert_int_equal(kerr, 0); ++ ++ kerr = sssd_krb5_locator_init(ctx, &priv); ++ assert_int_equal(kerr, 0); ++ ++ mkdir(TEST_PUBCONF_PATH, 0777); ++ fd = open(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM, O_CREAT|O_RDWR, 0777); ++ assert_int_not_equal(fd, -1); ++ for (c = 0; test_data[c].ip != NULL; c++) { ++ s = write(fd, test_data[c].ip, strlen(test_data[c].ip)); ++ assert_int_equal(s, strlen(test_data[c].ip)); ++ s = write(fd, "\n", 1); ++ assert_int_equal(s, 1); ++ } ++ close(fd); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_INET6, module_callback, ++ &cbdata); ++ assert_int_equal(kerr, 0); ++ ++ assert_int_equal(list.nservers, 5); ++ assert_non_null(list.servers); ++ test_multi_check_results(test_data, &list, "88"); ++ ++ k5_free_serverlist(&list); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_INET, module_callback, ++ &cbdata); ++ assert_int_equal(kerr, 0); ++ ++ assert_int_equal(list.nservers, 5); ++ assert_non_null(list.servers); ++ test_multi_check_results(test_data, &list, "88"); ++ ++ ++ k5_free_serverlist(&list); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_UNSPEC, module_callback, ++ &cbdata); ++ assert_int_equal(kerr, 0); ++ ++ assert_int_equal(list.nservers, 10); ++ assert_non_null(list.servers); ++ test_multi_check_results(test_data, &list, "88"); ++ ++ k5_free_serverlist(&list); ++ ++ unlink(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM); ++ rmdir(TEST_PUBCONF_PATH); ++ sssd_krb5_locator_close(priv); ++ ++ krb5_free_context(ctx); ++} ++ ++void test_service(void **state) ++{ ++ krb5_context ctx; ++ krb5_error_code kerr; ++ void *priv; ++ int fd; ++ struct serverlist list = SERVERLIST_INIT; ++ struct module_callback_data cbdata = { 0 }; ++ ssize_t s; ++ int ret; ++ char host[NI_MAXHOST]; ++ char service[NI_MAXSERV]; ++ ++ cbdata.list = &list; ++ ++ kerr = krb5_init_context (&ctx); ++ assert_int_equal(kerr, 0); ++ ++ kerr = sssd_krb5_locator_init(ctx, &priv); ++ assert_int_equal(kerr, 0); ++ ++ mkdir(TEST_PUBCONF_PATH, 0777); ++ fd = open(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM, O_CREAT|O_RDWR, 0777); ++ assert_int_not_equal(fd, -1); ++ s = write(fd, TEST_IP_1_WITH_SERVICE, sizeof(TEST_IP_1_WITH_SERVICE)); ++ assert_int_equal(s, sizeof(TEST_IP_1_WITH_SERVICE)); ++ s = write(fd, "\n", 1); ++ assert_int_equal(s, 1); ++ s = write(fd, TEST_IPV6_1_WITH_SERVICE, sizeof(TEST_IPV6_1_WITH_SERVICE)); ++ assert_int_equal(s, sizeof(TEST_IPV6_1_WITH_SERVICE)); ++ close(fd); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_INET6, module_callback, ++ &cbdata); ++ assert_int_equal(kerr, 0); ++ ++ assert_int_equal(list.nservers, 1); ++ assert_non_null(list.servers); ++ ret = getnameinfo((struct sockaddr *) &list.servers[0].addr, ++ list.servers[0].addrlen, ++ host, sizeof(host), service, sizeof(service), ++ NI_NUMERICHOST|NI_NUMERICSERV); ++ assert_int_equal(ret, 0); ++ assert_string_equal(TEST_IPV6_1_PURE, host); ++ assert_string_equal(TEST_SERVICE_2, service); ++ ++ k5_free_serverlist(&list); ++ ++ kerr = sssd_krb5_locator_lookup(priv, locate_service_kdc , TEST_REALM, ++ SOCK_DGRAM, AF_INET, module_callback, ++ &cbdata); ++ assert_int_equal(kerr, 0); ++ assert_int_equal(list.nservers, 1); ++ assert_non_null(list.servers); ++ ret = getnameinfo((struct sockaddr *) &list.servers[0].addr, ++ list.servers[0].addrlen, ++ host, sizeof(host), service, sizeof(service), ++ NI_NUMERICHOST|NI_NUMERICSERV); ++ assert_int_equal(ret, 0); ++ assert_string_equal(TEST_IP_1, host); ++ assert_string_equal(TEST_SERVICE_1, service); ++ ++ k5_free_serverlist(&list); ++ ++ ++ unlink(TEST_PUBCONF_PATH"/kdcinfo."TEST_REALM); ++ rmdir(TEST_PUBCONF_PATH); ++ sssd_krb5_locator_close(priv); ++ ++ krb5_free_context(ctx); ++} ++ ++int main(int argc, const char *argv[]) ++{ ++ poptContext pc; ++ int opt; ++ int ret; ++ struct poptOption long_options[] = { ++ POPT_AUTOHELP ++ SSSD_DEBUG_OPTS ++ POPT_TABLEEND ++ }; ++ ++ const struct CMUnitTest tests[] = { ++ cmocka_unit_test_setup_teardown(test_init, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(test_failed_lookup, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(test_empty, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(test_single, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(test_multi, ++ setup, teardown), ++ cmocka_unit_test_setup_teardown(test_service, ++ setup, 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); ++ ++ ret = cmocka_run_group_tests(tests, NULL, NULL); ++ ++ return ret; ++} +-- +2.17.1 + diff --git a/SOURCES/0005-AD-IPA-Create-kdcinfo-file-for-sub-domains.patch b/SOURCES/0005-AD-IPA-Create-kdcinfo-file-for-sub-domains.patch new file mode 100644 index 0000000..f6d7cd8 --- /dev/null +++ b/SOURCES/0005-AD-IPA-Create-kdcinfo-file-for-sub-domains.patch @@ -0,0 +1,148 @@ +From 660ef95e36ad73b4715656a4207aeb499ac96d16 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 24 May 2018 17:15:38 +0200 +Subject: [PATCH] AD/IPA: Create kdcinfo file for sub-domains + +With this patch kdcinfo files are created for sub-domains by the AD +provider and by the IPA provider on the IPA servers +(ipa_server_mode=True). + +Related to https://pagure.io/SSSD/sssd/issue/3652 +Reviewed-by: Jakub Hrozek + +(cherry picked from commit cc7922755dac53c69558ba060b309ac48ae82783) +--- + src/providers/ad/ad_common.c | 9 +++++++++ + src/providers/ad/ad_common.h | 1 + + src/providers/ad/ad_init.c | 1 + + src/providers/ad/ad_subdomains.c | 17 ++++++++++++++--- + src/providers/ipa/ipa_subdomains_server.c | 16 ++++++++++++++-- + 5 files changed, 39 insertions(+), 5 deletions(-) + +diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c +index be7791e6cc2527d45d3e2ff50294f9b98106ffae..0aea985e00faa996643fd7e7630d4264fb6cf233 100644 +--- a/src/providers/ad/ad_common.c ++++ b/src/providers/ad/ad_common.c +@@ -727,6 +727,7 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, + const char *ad_service, + const char *ad_gc_service, + const char *ad_domain, ++ bool use_kdcinfo, + struct ad_service **_service) + { + errno_t ret; +@@ -762,6 +763,14 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, + goto done; + } + ++ /* Set flag that controls whether we want to write the ++ * kdcinfo files at all ++ */ ++ service->krb5_service->write_kdcinfo = use_kdcinfo; ++ DEBUG(SSSDBG_CONF_SETTINGS, "write_kdcinfo for realm %s set to %s\n", ++ krb5_realm, ++ service->krb5_service->write_kdcinfo ? "true" : "false"); ++ + ret = be_fo_add_service(bectx, ad_service, ad_user_data_cmp); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create failover service!\n"); +diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h +index 6eb2ba7e9a7350d1924c45d33d8c332073767a34..dd440da33d48a5820c665f43908d1e1fb18171a6 100644 +--- a/src/providers/ad/ad_common.h ++++ b/src/providers/ad/ad_common.h +@@ -144,6 +144,7 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, + const char *ad_service, + const char *ad_gc_service, + const char *ad_domain, ++ bool use_kdcinfo, + struct ad_service **_service); + + errno_t +diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c +index b19624782000c5c7c65e766e3e01ff6ac3ab7adb..637efb761c1cf87b0a2c2b1c19b00ea0bbbe161f 100644 +--- a/src/providers/ad/ad_init.c ++++ b/src/providers/ad/ad_init.c +@@ -159,6 +159,7 @@ static errno_t ad_init_options(TALLOC_CTX *mem_ctx, + ret = ad_failover_init(ad_options, be_ctx, ad_servers, ad_backup_servers, + ad_realm, AD_SERVICE_NAME, AD_GC_SERVICE_NAME, + dp_opt_get_string(ad_options->basic, AD_DOMAIN), ++ false, /* will be set in ad_get_auth_options() */ + &ad_options->service); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, "Failed to init AD failover service: " +diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c +index 74b9f075174b1eaa6c5b5dcbaf609600ef197b52..84886e920b37f8803d85ce0903b74e6c809a8904 100644 +--- a/src/providers/ad/ad_subdomains.c ++++ b/src/providers/ad/ad_subdomains.c +@@ -249,6 +249,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx, + const char *hostname; + const char *keytab; + char *subdom_conf_path; ++ bool use_kdcinfo = false; + + realm = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_KRB5_REALM); + hostname = dp_opt_get_cstring(id_ctx->ad_options->basic, AD_HOSTNAME); +@@ -296,9 +297,19 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx, + servers = dp_opt_get_string(ad_options->basic, AD_SERVER); + backup_servers = dp_opt_get_string(ad_options->basic, AD_BACKUP_SERVER); + +- ret = ad_failover_init(ad_options, be_ctx, servers, backup_servers, realm, +- service_name, gc_service_name, +- subdom->name, &ad_options->service); ++ if (id_ctx->ad_options->auth_ctx != NULL ++ && id_ctx->ad_options->auth_ctx->opts != NULL) { ++ use_kdcinfo = dp_opt_get_bool(id_ctx->ad_options->auth_ctx->opts, ++ KRB5_USE_KDCINFO); ++ } ++ ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Init failover for [%s][%s] with use_kdcinfo [%s].\n", ++ subdom->name, subdom->realm, use_kdcinfo ? "true" : "false"); ++ ++ ret = ad_failover_init(ad_options, be_ctx, servers, backup_servers, ++ subdom->realm, service_name, gc_service_name, ++ subdom->name, use_kdcinfo, &ad_options->service); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD failover\n"); + talloc_free(ad_options); +diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c +index 1e53e7a951189120fcf3f438362e902a5a8f6d97..02577c92159d099a04cbd5cee80064309466db93 100644 +--- a/src/providers/ipa/ipa_subdomains_server.c ++++ b/src/providers/ipa/ipa_subdomains_server.c +@@ -228,6 +228,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx, + struct sdap_domain *sdom; + errno_t ret; + const char *extra_attrs; ++ bool use_kdcinfo = false; + + ad_domain = subdom->name; + DEBUG(SSSDBG_TRACE_LIBS, "Setting up AD subdomain %s\n", subdom->name); +@@ -284,12 +285,23 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx, + ad_servers = dp_opt_get_string(ad_options->basic, AD_SERVER); + ad_backup_servers = dp_opt_get_string(ad_options->basic, AD_BACKUP_SERVER); + ++ if (id_ctx->ipa_options != NULL && id_ctx->ipa_options->auth != NULL) { ++ use_kdcinfo = dp_opt_get_bool(id_ctx->ipa_options->auth, ++ KRB5_USE_KDCINFO); ++ } ++ ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Init failover for [%s][%s] with use_kdcinfo [%s].\n", ++ subdom->name, subdom->realm, use_kdcinfo ? "true" : "false"); ++ + /* Set KRB5 realm to same as the one of IPA when IPA + * is able to attach PAC. For testing, use hardcoded. */ ++ /* Why? */ + ret = ad_failover_init(ad_options, be_ctx, ad_servers, ad_backup_servers, +- id_ctx->server_mode->realm, ++ subdom->realm, + service_name, gc_service_name, +- subdom->name, &ad_options->service); ++ subdom->name, use_kdcinfo, ++ &ad_options->service); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize AD failover\n"); + talloc_free(ad_options); +-- +2.17.1 + diff --git a/SOURCES/0005-CONFDB-Remove-the-obsolete-option-magic_private_grou.patch b/SOURCES/0005-CONFDB-Remove-the-obsolete-option-magic_private_grou.patch deleted file mode 100644 index 017e97c..0000000 --- a/SOURCES/0005-CONFDB-Remove-the-obsolete-option-magic_private_grou.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 8e4858a044391cdfd7b6eae327daf043225c4536 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 3 Oct 2017 12:36:02 +0200 -Subject: [PATCH 05/21] CONFDB: Remove the obsolete option magic_private_groups -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since this confdb definition was completely unused across the codebase, -this patch just removes the definition. - -Reviewed-by: Pavel Březina -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 8fab9d6fa88824b20d3febe697147c407d31c160) ---- - src/confdb/confdb.h | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h -index 2539b906993edbceb38aac9265e04deed69cf2e4..1471949623e9dd7a8536e3ac3048a10227a5d857 100644 ---- a/src/confdb/confdb.h -+++ b/src/confdb/confdb.h -@@ -197,7 +197,6 @@ - "cache_credentials_minimal_first_factor_length" - #define CONFDB_DEFAULT_CACHE_CREDS_MIN_FF_LENGTH 8 - #define CONFDB_DOMAIN_LEGACY_PASS "store_legacy_passwords" --#define CONFDB_DOMAIN_MPG "magic_private_groups" - #define CONFDB_DOMAIN_AUTO_UPG "auto_private_groups" - #define CONFDB_DOMAIN_FQ "use_fully_qualified_names" - #define CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT "entry_cache_timeout" --- -2.13.5 - diff --git a/SOURCES/0006-SDAP-Allow-the-mpg-flag-for-the-main-domain.patch b/SOURCES/0006-SDAP-Allow-the-mpg-flag-for-the-main-domain.patch deleted file mode 100644 index 29bb20b..0000000 --- a/SOURCES/0006-SDAP-Allow-the-mpg-flag-for-the-main-domain.patch +++ /dev/null @@ -1,167 +0,0 @@ -From c28d61203655dd41cd8eb69752e435d3241e63b2 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 3 Oct 2017 12:34:49 +0200 -Subject: [PATCH 06/21] SDAP: Allow the mpg flag for the main domain -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This commit allows saving the users in the MPG domain in the SDAP -layer. - -The commit contains the following changes: - - abstracts the change where if the primary GID exists in the original - object, it is saved instead as the SYSDB_PRIMARY_GROUP_GIDNUM attribute, - which will allow the original primary GID to be exposed as a - secondary group - - - if the primary GID does not exist, no SYSDB_PRIMARY_GROUP_GIDNUM - is added. This will allow to handle LDAP objects that only contain - the UID but no GID. Since this is a new use-case, a test is added - later - - - a branch that handles the above is added to sdap_save_user() also - for joined domains that set the MPG flag. Previously, only - subdomains were handled. - - - to allow passing GID=0 to the sysdb layer, the range check is - relaxed. - -Related: - https://pagure.io/SSSD/sssd/issue/1872 - -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Pavel Březina -(cherry picked from commit cdb74b2cc6cc3fe52969712907c9eb4026c7a44f) ---- - src/providers/ldap/sdap_async_users.c | 83 +++++++++++++++++++++++++++++++---- - 1 file changed, 75 insertions(+), 8 deletions(-) - -diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c -index 09d096e84cac6c9d52bcde0e1587c47dbd88b504..7338b4a15694b1d0a16723990130a23a7280af5f 100644 ---- a/src/providers/ldap/sdap_async_users.c -+++ b/src/providers/ldap/sdap_async_users.c -@@ -136,6 +136,38 @@ static errno_t sdap_set_non_posix_flag(struct sysdb_attrs *attrs, - return EOK; - } - -+static int sdap_user_set_mpg(struct sysdb_attrs *user_attrs, -+ gid_t *_gid) -+{ -+ errno_t ret; -+ -+ if (_gid == NULL) { -+ return EINVAL; -+ } -+ -+ if (*_gid == 0) { -+ /* The original entry had no GID number. This is OK, we just won't add -+ * the SYSDB_PRIMARY_GROUP_GIDNUM attribute -+ */ -+ return EOK; -+ } -+ -+ ret = sysdb_attrs_add_uint32(user_attrs, -+ SYSDB_PRIMARY_GROUP_GIDNUM, -+ (uint32_t) *_gid); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_uint32 failed.\n"); -+ return ret; -+ } -+ -+ /* We won't really store gidNumber=0, but the zero value tells -+ * the sysdb layer that no GID is set, which sysdb requires for -+ * MPG-enabled domains -+ */ -+ *_gid = 0; -+ return EOK; -+} -+ - /* FIXME: support storing additional attributes */ - int sdap_save_user(TALLOC_CTX *memctx, - struct sdap_options *opts, -@@ -357,7 +389,7 @@ int sdap_save_user(TALLOC_CTX *memctx, - goto done; - } - -- if (IS_SUBDOMAIN(dom)) { -+ if (IS_SUBDOMAIN(dom) || dom->mpg == true) { - /* For subdomain users, only create the private group as - * the subdomain is an MPG domain. - * But we have to save the GID of the original primary group -@@ -365,14 +397,13 @@ int sdap_save_user(TALLOC_CTX *memctx, - * typically (Unix and AD) the user is not listed in his primary - * group as a member. - */ -- ret = sysdb_attrs_add_uint32(user_attrs, SYSDB_PRIMARY_GROUP_GIDNUM, -- (uint32_t) gid); -+ ret = sdap_user_set_mpg(user_attrs, &gid); - if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_uint32 failed.\n"); -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sdap_user_set_mpg failed [%d]: %s\n", ret, -+ sss_strerror(ret)); - goto done; - } -- -- gid = 0; - } - - /* Store the GID in the ldap_attrs so it doesn't get -@@ -380,6 +411,41 @@ int sdap_save_user(TALLOC_CTX *memctx, - */ - ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid); - if (ret != EOK) goto done; -+ } else if (dom->mpg) { -+ /* Likewise, if a domain is set to contain 'magic private groups', do -+ * not process the real GID, but save it in the cache as originalGID -+ * (if available) -+ */ -+ ret = sysdb_attrs_get_uint32_t(attrs, -+ opts->user_map[SDAP_AT_USER_GID].sys_name, -+ &gid); -+ if (ret == ENOENT) { -+ DEBUG(SSSDBG_TRACE_LIBS, -+ "Missing GID, won't save the %s attribute\n", -+ SYSDB_PRIMARY_GROUP_GIDNUM); -+ -+ /* Store the UID as GID (since we're in a MPG domain so that it doesn't -+ * get treated as a missing attribute and removed -+ */ -+ ret = sdap_replace_id(attrs, SYSDB_GIDNUM, uid); -+ if (ret) { -+ DEBUG(SSSDBG_OP_FAILURE, "Cannot set the id-mapped UID\n"); -+ goto done; -+ } -+ gid = 0; -+ } else if (ret != EOK) { -+ DEBUG(SSSDBG_MINOR_FAILURE, -+ "Cannot retrieve GID, won't save the %s attribute\n", -+ SYSDB_PRIMARY_GROUP_GIDNUM); -+ gid = 0; -+ } -+ -+ ret = sdap_user_set_mpg(user_attrs, &gid); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sdap_user_set_mpg failed [%d]: %s\n", ret, sss_strerror(ret)); -+ goto done; -+ } - } else { - ret = sysdb_attrs_get_uint32_t(attrs, - opts->user_map[SDAP_AT_USER_GID].sys_name, -@@ -403,8 +469,9 @@ int sdap_save_user(TALLOC_CTX *memctx, - } - - /* check that the gid is valid for this domain */ -- if (is_posix == true && IS_SUBDOMAIN(dom) == false && -- OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) { -+ if (is_posix == true && IS_SUBDOMAIN(dom) == false -+ && dom->mpg == false -+ && OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) { - DEBUG(SSSDBG_CRIT_FAILURE, - "User [%s] filtered out! (primary gid out of range)\n", - user_name); --- -2.13.5 - diff --git a/SOURCES/0006-krb5-refactor-removal-of-krb5info-files.patch b/SOURCES/0006-krb5-refactor-removal-of-krb5info-files.patch new file mode 100644 index 0000000..9787c85 --- /dev/null +++ b/SOURCES/0006-krb5-refactor-removal-of-krb5info-files.patch @@ -0,0 +1,493 @@ +From 713bc782502163251ef22eb81b09eed61a8407f7 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Tue, 5 Jun 2018 17:44:59 +0200 +Subject: [PATCH] krb5: refactor removal of krb5info files + +Currently a persistent offline callback removes the krb5info files for +the configured main domain and those files were removed by a SIGTERM +signal handlers as well. + +This does not scale if krb5info files are created for sub-domains as +well. To remove the files automatically the removal is moved into a +talloc destructor of an offline callback which is added if the file is +created and frees itself when the system goes offline. Due to the +talloc memory hierarchy we get removal on shutdown for free. + +Related to https://pagure.io/SSSD/sssd/issue/3652 +Reviewed-by: Jakub Hrozek + +(cherry picked from commit d91661e295c8e878f1bbf34e6f65f61e8301bf0e) +--- + src/providers/ad/ad_common.c | 7 +- + src/providers/ipa/ipa_common.c | 5 +- + src/providers/krb5/krb5_common.c | 176 +++++++++++++------------- + src/providers/krb5/krb5_common.h | 7 +- + src/providers/krb5/krb5_init_shared.c | 6 - + src/providers/ldap/ldap_common.c | 87 ------------- + 6 files changed, 102 insertions(+), 186 deletions(-) + +diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c +index 0aea985e00faa996643fd7e7630d4264fb6cf233..8caaba6c0d06cfe83d9741536192d662fc936273 100644 +--- a/src/providers/ad/ad_common.c ++++ b/src/providers/ad/ad_common.c +@@ -804,6 +804,8 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, + goto done; + } + ++ service->krb5_service->be_ctx = bectx; ++ + if (!primary_servers) { + DEBUG(SSSDBG_CONF_SETTINGS, + "No primary servers defined, using service discovery\n"); +@@ -984,8 +986,9 @@ ad_resolve_callback(void *private_data, struct fo_server *server) + goto done; + } + +- ret = write_krb5info_file(service->krb5_service->realm, safe_address, +- SSS_KRB5KDC_FO_SRV); ++ ret = write_krb5info_file(service->krb5_service, ++ safe_address, ++ SSS_KRB5KDC_FO_SRV); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "write_krb5info_file failed, authentication might fail.\n"); +diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c +index 87ed967673358bf833dae13c29b1f6a17b0fc19c..dcbb54a744358718e444972b9827ee64887e5e33 100644 +--- a/src/providers/ipa/ipa_common.c ++++ b/src/providers/ipa/ipa_common.c +@@ -838,7 +838,8 @@ static void ipa_resolve_callback(void *private_data, struct fo_server *server) + return; + } + +- ret = write_krb5info_file(service->krb5_service->realm, safe_address, ++ ret = write_krb5info_file(service->krb5_service, ++ safe_address, + SSS_KRB5KDC_FO_SRV); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +@@ -1012,6 +1013,8 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, + goto done; + } + ++ service->krb5_service->be_ctx = ctx; ++ + if (!primary_servers) { + DEBUG(SSSDBG_CONF_SETTINGS, + "No primary servers defined, using service discovery\n"); +diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c +index 520e7591ce1b37b4a8dea357b6dd0ec7afd76f58..c6896a6cd663da896075e72aa0a0602c198b45e8 100644 +--- a/src/providers/krb5/krb5_common.c ++++ b/src/providers/krb5/krb5_common.c +@@ -389,7 +389,76 @@ done: + return ret; + } + +-errno_t write_krb5info_file(const char *realm, const char *server, ++static int remove_info_files_destructor(void *p) ++{ ++ int ret; ++ struct remove_info_files_ctx *ctx = talloc_get_type(p, ++ struct remove_info_files_ctx); ++ ++ ret = remove_krb5_info_files(ctx, ctx->realm); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "remove_krb5_info_files failed.\n"); ++ } ++ ++ return 0; ++} ++ ++static errno_t ++krb5_add_krb5info_offline_callback(struct krb5_service *krb5_service) ++{ ++ int ret; ++ struct remove_info_files_ctx *ctx; ++ ++ if (krb5_service == NULL || krb5_service->name == NULL ++ || krb5_service->realm == NULL ++ || krb5_service->be_ctx == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Missing KDC service name or realm!\n"); ++ return EINVAL; ++ } ++ ++ ctx = talloc_zero(krb5_service->be_ctx, struct remove_info_files_ctx); ++ if (ctx == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zfree failed.\n"); ++ return ENOMEM; ++ } ++ ++ ctx->realm = talloc_strdup(ctx, krb5_service->realm); ++ if (ctx->realm == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed!\n"); ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ ctx->be_ctx = krb5_service->be_ctx; ++ ctx->kdc_service_name = talloc_strdup(ctx, krb5_service->name); ++ if (ctx->kdc_service_name == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed!\n"); ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ ret = be_add_offline_cb(ctx, krb5_service->be_ctx, ++ remove_krb5_info_files_callback, ctx, NULL); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "be_add_offline_cb failed.\n"); ++ goto done; ++ } ++ ++ talloc_set_destructor((TALLOC_CTX *) ctx, remove_info_files_destructor); ++ ++ ret = EOK; ++ ++done: ++ if (ret != EOK) { ++ talloc_zfree(ctx); ++ } ++ ++ return ret; ++} ++ ++ ++errno_t write_krb5info_file(struct krb5_service *krb5_service, ++ const char *server, + const char *service) + { + int ret; +@@ -401,17 +470,19 @@ errno_t write_krb5info_file(const char *realm, const char *server, + size_t server_len; + ssize_t written; + +- if (realm == NULL || *realm == '\0' || server == NULL || *server == '\0' || +- service == NULL || *service == '\0') { ++ if (krb5_service == NULL || krb5_service->realm == NULL ++ || *krb5_service->realm == '\0' ++ || server == NULL || *server == '\0' ++ || service == NULL || *service == '\0') { + DEBUG(SSSDBG_CRIT_FAILURE, + "Missing or empty realm, server or service.\n"); + return EINVAL; + } + +- if (sss_krb5_realm_has_proxy(realm)) { ++ if (sss_krb5_realm_has_proxy(krb5_service->realm)) { + DEBUG(SSSDBG_CONF_SETTINGS, + "KDC Proxy available for realm [%s], no kdcinfo file created.\n", +- realm); ++ krb5_service->realm); + return EOK; + } + +@@ -439,7 +510,7 @@ errno_t write_krb5info_file(const char *realm, const char *server, + goto done; + } + +- krb5info_name = talloc_asprintf(tmp_ctx, name_tmpl, realm); ++ krb5info_name = talloc_asprintf(tmp_ctx, name_tmpl, krb5_service->realm); + if (krb5info_name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n"); + ret = ENOMEM; +@@ -495,6 +566,12 @@ errno_t write_krb5info_file(const char *realm, const char *server, + goto done; + } + ++ ret = krb5_add_krb5info_offline_callback(krb5_service); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "Failed to add offline callback, krb5info " ++ "file might not be removed properly.\n"); ++ } ++ + ret = EOK; + done: + if (fd != -1) { +@@ -561,7 +638,8 @@ static void krb5_resolve_callback(void *private_data, struct fo_server *server) + return; + } + +- ret = write_krb5info_file(krb5_service->realm, safe_address, ++ ret = write_krb5info_file(krb5_service, ++ safe_address, + krb5_service->name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +@@ -761,6 +839,7 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, + } + + service->write_kdcinfo = use_kdcinfo; ++ service->be_ctx = ctx; + + if (!primary_servers) { + DEBUG(SSSDBG_CONF_SETTINGS, +@@ -839,7 +918,6 @@ errno_t remove_krb5_info_files(TALLOC_CTX *mem_ctx, const char *realm) + void remove_krb5_info_files_callback(void *pvt) + { + int ret; +- TALLOC_CTX *tmp_ctx = NULL; + struct remove_info_files_ctx *ctx = talloc_get_type(pvt, + struct remove_info_files_ctx); + +@@ -864,19 +942,10 @@ void remove_krb5_info_files_callback(void *pvt) + } + } + +- tmp_ctx = talloc_new(NULL); +- if (tmp_ctx == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, +- "talloc_new failed, cannot remove krb5 info files.\n"); +- return; +- } +- +- ret = remove_krb5_info_files(tmp_ctx, ctx->realm); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "remove_krb5_info_files failed.\n"); +- } +- +- talloc_zfree(tmp_ctx); ++ /* Freeing the remove_info_files_ctx will remove the related krb5info ++ * file. Additionally the callback from the list of callbacks is removed, ++ * it will be added again when a new krb5info file is created. */ ++ talloc_free(ctx); + } + + void krb5_finalize(struct tevent_context *ev, +@@ -886,74 +955,9 @@ void krb5_finalize(struct tevent_context *ev, + void *siginfo, + void *private_data) + { +- char *realm = (char *)private_data; +- int ret; +- +- ret = remove_krb5_info_files(se, realm); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "remove_krb5_info_files failed.\n"); +- } +- + orderly_shutdown(0); + } + +-errno_t krb5_install_offline_callback(struct be_ctx *be_ctx, +- struct krb5_ctx *krb5_ctx) +-{ +- int ret; +- struct remove_info_files_ctx *ctx; +- const char *krb5_realm; +- +- if (krb5_ctx->service == NULL || krb5_ctx->service->name == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Missing KDC service name!\n"); +- return EINVAL; +- } +- +- ctx = talloc_zero(krb5_ctx, struct remove_info_files_ctx); +- if (ctx == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zfree failed.\n"); +- return ENOMEM; +- } +- +- krb5_realm = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM); +- if (krb5_realm == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "Missing krb5_realm option!\n"); +- ret = EINVAL; +- goto done; +- } +- +- ctx->realm = talloc_strdup(ctx, krb5_realm); +- if (ctx->realm == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed!\n"); +- ret = ENOMEM; +- goto done; +- } +- +- ctx->be_ctx = be_ctx; +- ctx->kdc_service_name = krb5_ctx->service->name; +- if (krb5_ctx->kpasswd_service == NULL) { +- ctx->kpasswd_service_name =NULL; +- } else { +- ctx->kpasswd_service_name = krb5_ctx->kpasswd_service->name; +- } +- +- ret = be_add_offline_cb(ctx, be_ctx, remove_krb5_info_files_callback, ctx, +- NULL); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "be_add_offline_cb failed.\n"); +- goto done; +- } +- +- ret = EOK; +- +-done: +- if (ret != EOK) { +- talloc_zfree(ctx); +- } +- +- return ret; +-} +- + errno_t krb5_install_sigterm_handler(struct tevent_context *ev, + struct krb5_ctx *krb5_ctx) + { +diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h +index 48368a528e75947102c74cb75bf7a74ec0dd258f..a2e47b0605debdffa28305dab4f7674707f713ac 100644 +--- a/src/providers/krb5/krb5_common.h ++++ b/src/providers/krb5/krb5_common.h +@@ -67,6 +67,7 @@ enum krb5_opts { + typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type; + + struct krb5_service { ++ struct be_ctx *be_ctx; + char *name; + char *realm; + bool write_kdcinfo; +@@ -157,7 +158,8 @@ errno_t krb5_try_kdcip(struct confdb_ctx *cdb, const char *conf_path, + errno_t sss_krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, + const char *conf_path, struct dp_option **_opts); + +-errno_t write_krb5info_file(const char *realm, const char *kdc, ++errno_t write_krb5info_file(struct krb5_service *krb5_service, ++ const char *server, + const char *service); + + int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, +@@ -177,9 +179,6 @@ void krb5_finalize(struct tevent_context *ev, + void *siginfo, + void *private_data); + +-errno_t krb5_install_offline_callback(struct be_ctx *be_ctx, +- struct krb5_ctx *krb_ctx); +- + errno_t krb5_install_sigterm_handler(struct tevent_context *ev, + struct krb5_ctx *krb5_ctx); + +diff --git a/src/providers/krb5/krb5_init_shared.c b/src/providers/krb5/krb5_init_shared.c +index 3901b7272119c32930c2b6b47279a2c685bf3cfb..368d6f7b0f2bc038e4cc4aa8f0970cd0e81d7b6b 100644 +--- a/src/providers/krb5/krb5_init_shared.c ++++ b/src/providers/krb5/krb5_init_shared.c +@@ -71,12 +71,6 @@ errno_t krb5_child_init(struct krb5_ctx *krb5_auth_ctx, + goto done; + } + +- ret = krb5_install_offline_callback(bectx, krb5_auth_ctx); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "krb5_install_offline_callback failed.\n"); +- goto done; +- } +- + ret = krb5_install_sigterm_handler(bectx->ev, krb5_auth_ctx); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "krb5_install_sigterm_handler failed.\n"); +diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c +index 91e229243b9a1b43e7a57704824f5db0341f4ee9..15377ee1f062c0167aabee30ef0757ebe7271682 100644 +--- a/src/providers/ldap/ldap_common.c ++++ b/src/providers/ldap/ldap_common.c +@@ -158,14 +158,6 @@ static void sdap_finalize(struct tevent_context *ev, + void *siginfo, + void *private_data) + { +- char *realm = (char *) private_data; +- int ret; +- +- ret = remove_krb5_info_files(se, realm); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "remove_krb5_info_files failed.\n"); +- } +- + orderly_shutdown(0); + } + +@@ -196,78 +188,6 @@ errno_t sdap_install_sigterm_handler(TALLOC_CTX *mem_ctx, + return EOK; + } + +-void sdap_remove_kdcinfo_files_callback(void *pvt) +-{ +- int ret; +- TALLOC_CTX *tmp_ctx = NULL; +- struct remove_info_files_ctx *ctx = talloc_get_type(pvt, +- struct remove_info_files_ctx); +- +- ret = be_fo_run_callbacks_at_next_request(ctx->be_ctx, +- ctx->kdc_service_name); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, +- "be_fo_run_callbacks_at_next_request failed, " +- "krb5 info files will not be removed, because " +- "it is unclear if they will be recreated properly.\n"); +- return; +- } +- +- tmp_ctx = talloc_new(NULL); +- if (tmp_ctx == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, +- "talloc_new failed, cannot remove krb5 info files.\n"); +- return; +- } +- +- ret = remove_krb5_info_files(tmp_ctx, ctx->realm); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "remove_krb5_info_files failed.\n"); +- } +- +- talloc_zfree(tmp_ctx); +-} +- +- +-errno_t sdap_install_offline_callback(TALLOC_CTX *mem_ctx, +- struct be_ctx *be_ctx, +- const char *realm, +- const char *service_name) +-{ +- int ret; +- struct remove_info_files_ctx *ctx; +- +- ctx = talloc_zero(mem_ctx, struct remove_info_files_ctx); +- if (ctx == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zfree failed.\n"); +- return ENOMEM; +- } +- +- ctx->be_ctx = be_ctx; +- ctx->realm = talloc_strdup(ctx, realm); +- ctx->kdc_service_name = talloc_strdup(ctx, service_name); +- if (ctx->realm == NULL || ctx->kdc_service_name == NULL) { +- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed!\n"); +- ret = ENOMEM; +- goto done; +- } +- +- ret = be_add_offline_cb(ctx, be_ctx, +- sdap_remove_kdcinfo_files_callback, +- ctx, NULL); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "be_add_offline_cb failed.\n"); +- goto done; +- } +- +- ret = EOK; +-done: +- if (ret != EOK) { +- talloc_zfree(ctx); +- } +- return ret; +-} +- + errno_t + sdap_set_sasl_options(struct sdap_options *id_opts, + char *default_primary, +@@ -458,13 +378,6 @@ int sdap_gssapi_init(TALLOC_CTX *mem_ctx, + goto done; + } + +- ret = sdap_install_offline_callback(mem_ctx, bectx, +- krb5_realm, SSS_KRB5KDC_FO_SRV); +- if (ret != EOK) { +- DEBUG(SSSDBG_FATAL_FAILURE, "Failed to install sigterm handler\n"); +- goto done; +- } +- + sdap_service->kinit_service_name = talloc_strdup(sdap_service, + service->name); + if (sdap_service->kinit_service_name == NULL) { +-- +2.17.1 + diff --git a/SOURCES/0007-LDAP-Turn-group-request-into-user-request-for-MPG-do.patch b/SOURCES/0007-LDAP-Turn-group-request-into-user-request-for-MPG-do.patch deleted file mode 100644 index 12745ce..0000000 --- a/SOURCES/0007-LDAP-Turn-group-request-into-user-request-for-MPG-do.patch +++ /dev/null @@ -1,222 +0,0 @@ -From f048f210112a2ca6df52f10f9e47afac5996fc09 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 3 Oct 2017 14:31:18 +0200 -Subject: [PATCH 07/21] LDAP: Turn group request into user request for MPG - domains if needed -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If the primary group GID or the group name is requested before the user -is, we need to also search the user space to save the user in the back -end which then allows the responder to generate the group from the -user entry. - -Related: - https://pagure.io/SSSD/sssd/issue/1872 - -Reviewed-by: Pavel Březina -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 057e8af379aa32f7d9ea48bfff22a3304c59444b) ---- - src/providers/ldap/ldap_id.c | 162 +++++++++++++++++++++++++++++++------------ - 1 file changed, 118 insertions(+), 44 deletions(-) - -diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c -index 93204d35ea3782c9aa5d622a962c295869472631..e89fc6133316f684810afe4c1a0731b8a04f2931 100644 ---- a/src/providers/ldap/ldap_id.c -+++ b/src/providers/ldap/ldap_id.c -@@ -694,6 +694,8 @@ struct groups_get_state { - static int groups_get_retry(struct tevent_req *req); - static void groups_get_connect_done(struct tevent_req *subreq); - static void groups_get_posix_check_done(struct tevent_req *subreq); -+static void groups_get_mpg_done(struct tevent_req *subreq); -+static errno_t groups_get_handle_no_group(struct tevent_req *req); - static void groups_get_search(struct tevent_req *req); - static void groups_get_done(struct tevent_req *subreq); - -@@ -1051,8 +1053,6 @@ static void groups_get_done(struct tevent_req *subreq) - struct tevent_req); - struct groups_get_state *state = tevent_req_data(req, - struct groups_get_state); -- char *endptr; -- gid_t gid; - int dp_error = DP_ERR_FATAL; - int ret; - -@@ -1078,49 +1078,33 @@ static void groups_get_done(struct tevent_req *subreq) - return; - } - -- if (ret == ENOENT && state->noexist_delete == true) { -- switch (state->filter_type) { -- case BE_FILTER_ENUM: -- tevent_req_error(req, ret); -+ if (ret == ENOENT -+ && state->domain->mpg == true) { -+ /* The requested filter did not find a group. Before giving up, we must -+ * also check if the GID can be resolved through a primary group of a -+ * user -+ */ -+ subreq = users_get_send(state, -+ state->ev, -+ state->ctx, -+ state->sdom, -+ state->conn, -+ state->filter_value, -+ state->filter_type, -+ NULL, -+ state->noexist_delete); -+ if (subreq == NULL) { -+ tevent_req_error(req, ENOMEM); - return; -- case BE_FILTER_NAME: -- ret = sysdb_delete_group(state->domain, state->filter_value, 0); -- if (ret != EOK && ret != ENOENT) { -- tevent_req_error(req, ret); -- return; -- } -- break; -- -- case BE_FILTER_IDNUM: -- gid = (gid_t) strtouint32(state->filter_value, &endptr, 10); -- if (errno || *endptr || (state->filter_value == endptr)) { -- tevent_req_error(req, errno ? errno : EINVAL); -- return; -- } -- -- ret = sysdb_delete_group(state->domain, NULL, gid); -- if (ret != EOK && ret != ENOENT) { -- tevent_req_error(req, ret); -- return; -- } -- break; -- -- case BE_FILTER_SECID: -- case BE_FILTER_UUID: -- /* Since it is not clear if the SID/UUID belongs to a user or a -- * group we have nothing to do here. */ -- break; -- -- case BE_FILTER_WILDCARD: -- /* We can't know if all groups are up-to-date, especially in -- * a large environment. Do not delete any records, let the -- * responder fetch the entries they are requested in. -- */ -- break; -- -- -- default: -- tevent_req_error(req, EINVAL); -+ } -+ tevent_req_set_callback(subreq, groups_get_mpg_done, req); -+ return; -+ } else if (ret == ENOENT && state->noexist_delete == true) { -+ ret = groups_get_handle_no_group(req); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Could not delete group [%d]: %s\n", ret, sss_strerror(ret)); -+ tevent_req_error(req, ret); - return; - } - } -@@ -1129,6 +1113,96 @@ static void groups_get_done(struct tevent_req *subreq) - tevent_req_done(req); - } - -+static void groups_get_mpg_done(struct tevent_req *subreq) -+{ -+ errno_t ret; -+ struct tevent_req *req = tevent_req_callback_data(subreq, -+ struct tevent_req); -+ struct groups_get_state *state = tevent_req_data(req, -+ struct groups_get_state); -+ -+ ret = users_get_recv(subreq, &state->dp_error, &state->sdap_ret); -+ talloc_zfree(subreq); -+ -+ if (ret != EOK) { -+ tevent_req_error(req, ret); -+ return; -+ } -+ -+ if (state->sdap_ret == ENOENT && state->noexist_delete == true) { -+ ret = groups_get_handle_no_group(req); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Could not delete group [%d]: %s\n", ret, sss_strerror(ret)); -+ tevent_req_error(req, ret); -+ return; -+ } -+ } -+ -+ /* GID resolved to a user private group, done */ -+ tevent_req_done(req); -+ return; -+} -+ -+static errno_t groups_get_handle_no_group(struct tevent_req *req) -+{ -+ struct groups_get_state *state = tevent_req_data(req, -+ struct groups_get_state); -+ errno_t ret; -+ char *endptr; -+ gid_t gid; -+ -+ switch (state->filter_type) { -+ case BE_FILTER_ENUM: -+ ret = ENOENT; -+ break; -+ case BE_FILTER_NAME: -+ ret = sysdb_delete_group(state->domain, state->filter_value, 0); -+ if (ret != EOK && ret != ENOENT) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Cannot delete group %s [%d]: %s\n", -+ state->filter_value, ret, sss_strerror(ret)); -+ return ret; -+ } -+ ret = EOK; -+ break; -+ case BE_FILTER_IDNUM: -+ gid = (gid_t) strtouint32(state->filter_value, &endptr, 10); -+ if (errno || *endptr || (state->filter_value == endptr)) { -+ ret = errno ? errno : EINVAL; -+ break; -+ } -+ -+ ret = sysdb_delete_group(state->domain, NULL, gid); -+ if (ret != EOK && ret != ENOENT) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Cannot delete group %"SPRIgid" [%d]: %s\n", -+ gid, ret, sss_strerror(ret)); -+ return ret; -+ } -+ ret = EOK; -+ break; -+ case BE_FILTER_SECID: -+ case BE_FILTER_UUID: -+ /* Since it is not clear if the SID/UUID belongs to a user or a -+ * group we have nothing to do here. */ -+ ret = EOK; -+ break; -+ case BE_FILTER_WILDCARD: -+ /* We can't know if all groups are up-to-date, especially in -+ * a large environment. Do not delete any records, let the -+ * responder fetch the entries they are requested in. -+ */ -+ ret = EOK; -+ break; -+ default: -+ ret = EINVAL; -+ break; -+ } -+ -+ return ret; -+} -+ - int groups_get_recv(struct tevent_req *req, int *dp_error_out, int *sdap_ret) - { - struct groups_get_state *state = tevent_req_data(req, --- -2.13.5 - diff --git a/SOURCES/0007-krb5_common-add-callback-only-once.patch b/SOURCES/0007-krb5_common-add-callback-only-once.patch new file mode 100644 index 0000000..2b36703 --- /dev/null +++ b/SOURCES/0007-krb5_common-add-callback-only-once.patch @@ -0,0 +1,86 @@ +From 54ea4576ba8cb8dfbefdd3ced29fc35f836afc61 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 8 Jun 2018 08:29:04 +0200 +Subject: [PATCH] krb5_common: add callback only once + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 4759a482781bcecdb0ad1119e74dcefa1fe94337) +--- + src/providers/krb5/krb5_common.c | 12 +++++++++++- + src/providers/krb5/krb5_common.h | 2 ++ + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c +index c6896a6cd663da896075e72aa0a0602c198b45e8..d064a09ac3726c4185c2fa1eeac76ef6c261d33b 100644 +--- a/src/providers/krb5/krb5_common.c ++++ b/src/providers/krb5/krb5_common.c +@@ -399,6 +399,7 @@ static int remove_info_files_destructor(void *p) + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "remove_krb5_info_files failed.\n"); + } ++ ctx->krb5_service->removal_callback_available = false; + + return 0; + } +@@ -407,7 +408,7 @@ static errno_t + krb5_add_krb5info_offline_callback(struct krb5_service *krb5_service) + { + int ret; +- struct remove_info_files_ctx *ctx; ++ struct remove_info_files_ctx *ctx = NULL; + + if (krb5_service == NULL || krb5_service->name == NULL + || krb5_service->realm == NULL +@@ -416,6 +417,13 @@ krb5_add_krb5info_offline_callback(struct krb5_service *krb5_service) + return EINVAL; + } + ++ if (krb5_service->removal_callback_available) { ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Removal callback already available for service [%s].\n", ++ krb5_service->name); ++ return EOK; ++ } ++ + ctx = talloc_zero(krb5_service->be_ctx, struct remove_info_files_ctx); + if (ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zfree failed.\n"); +@@ -430,6 +438,7 @@ krb5_add_krb5info_offline_callback(struct krb5_service *krb5_service) + } + + ctx->be_ctx = krb5_service->be_ctx; ++ ctx->krb5_service = krb5_service; + ctx->kdc_service_name = talloc_strdup(ctx, krb5_service->name); + if (ctx->kdc_service_name == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed!\n"); +@@ -445,6 +454,7 @@ krb5_add_krb5info_offline_callback(struct krb5_service *krb5_service) + } + + talloc_set_destructor((TALLOC_CTX *) ctx, remove_info_files_destructor); ++ krb5_service->removal_callback_available = true; + + ret = EOK; + +diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h +index a2e47b0605debdffa28305dab4f7674707f713ac..3529d740b89fee91281f936fdafd1bdb99e95bd7 100644 +--- a/src/providers/krb5/krb5_common.h ++++ b/src/providers/krb5/krb5_common.h +@@ -71,6 +71,7 @@ struct krb5_service { + char *name; + char *realm; + bool write_kdcinfo; ++ bool removal_callback_available; + }; + + struct fo_service; +@@ -146,6 +147,7 @@ struct remove_info_files_ctx { + struct be_ctx *be_ctx; + const char *kdc_service_name; + const char *kpasswd_service_name; ++ struct krb5_service *krb5_service; + }; + + errno_t sss_krb5_check_options(struct dp_option *opts, +-- +2.17.1 + diff --git a/SOURCES/0008-SYSDB-Prevent-users-and-groups-ID-collision-in-MPG-d.patch b/SOURCES/0008-SYSDB-Prevent-users-and-groups-ID-collision-in-MPG-d.patch deleted file mode 100644 index b8d60e1..0000000 --- a/SOURCES/0008-SYSDB-Prevent-users-and-groups-ID-collision-in-MPG-d.patch +++ /dev/null @@ -1,97 +0,0 @@ -From d75b796151973a5d94a79f5577c15cda6eecb5ee Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Thu, 19 Oct 2017 17:18:15 +0200 -Subject: [PATCH 08/21] SYSDB: Prevent users and groups ID collision in MPG - domains except for id_provider=local -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This commit makes the check when adding an object in a MPG domain -stricter in the sense that not only same names are allowed in a MPG -domain, but also the same groups are not allowed either. - -This commit is a backwards-incompatible change, but one that is needed, -otherwise requesting the duplicate group first and then requesting the -user entry would yield two object when searching by GID. - -In order to keep backwards-compatibility, this uniqueness is NOT -enforced with id_provider=local. This constraint can be removed in -the future (or the local provider can be dropped altogether) - -Reviewed-by: Pavel Březina -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit ac962e2b286988d8666b3b81bf8b55b1705b9ac0) ---- - src/db/sysdb_ops.c | 41 ++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 38 insertions(+), 3 deletions(-) - -diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c -index 0e39a629a5823ff49ed02ec4c08a21b66119f06f..2f8e36c6c9a2c2cefe4af5fb78957763304d989a 100644 ---- a/src/db/sysdb_ops.c -+++ b/src/db/sysdb_ops.c -@@ -1960,16 +1960,34 @@ int sysdb_add_user(struct sss_domain_info *domain, - } - - if (domain->mpg) { -- /* In MPG domains you can't have groups with the same name as users, -- * search if a group with the same name exists. -+ /* In MPG domains you can't have groups with the same name or GID -+ * as users, search if a group with the same name exists. - * Don't worry about users, if we try to add a user with the same - * name the operation will fail */ - - ret = sysdb_search_group_by_name(tmp_ctx, domain, name, NULL, &msg); - if (ret != ENOENT) { -- if (ret == EOK) ret = EEXIST; -+ if (ret == EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Group named %s already exists in an MPG domain\n", -+ name); -+ ret = EEXIST; -+ } - goto done; - } -+ -+ if (strcasecmp(domain->provider, "local") != 0) { -+ ret = sysdb_search_group_by_gid(tmp_ctx, domain, uid, NULL, &msg); -+ if (ret != ENOENT) { -+ if (ret == EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Group with GID [%"SPRIgid"] already exists in an " -+ "MPG domain\n", gid); -+ ret = EEXIST; -+ } -+ goto done; -+ } -+ } - } - - /* check no other user with the same uid exist */ -@@ -2177,6 +2195,23 @@ int sysdb_add_group(struct sss_domain_info *domain, - } - goto done; - } -+ -+ if (strcasecmp(domain->provider, "local") != 0) { -+ ret = sysdb_search_user_by_uid(tmp_ctx, domain, gid, NULL, &msg); -+ if (ret != ENOENT) { -+ if (ret == EOK) { -+ DEBUG(SSSDBG_TRACE_LIBS, -+ "User with the same UID exists in MPG domain: " -+ "[%"SPRIgid"].\n", gid); -+ ret = EEXIST; -+ } else { -+ DEBUG(SSSDBG_TRACE_LIBS, -+ "sysdb_search_user_by_uid failed for gid: " -+ "[%"SPRIgid"].\n", gid); -+ } -+ goto done; -+ } -+ } - } - - /* check no other groups with the same gid exist */ --- -2.13.5 - diff --git a/SOURCES/0008-data-provider-run-offline-callbacks-only-once.patch b/SOURCES/0008-data-provider-run-offline-callbacks-only-once.patch new file mode 100644 index 0000000..fd7a973 --- /dev/null +++ b/SOURCES/0008-data-provider-run-offline-callbacks-only-once.patch @@ -0,0 +1,95 @@ +From 2d350235bc960a91233d29b97c3a205bd2e04c08 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Fri, 8 Jun 2018 18:42:28 +0200 +Subject: [PATCH] data provider: run offline callbacks only once + +Reviewed-by: Jakub Hrozek +(cherry picked from commit f28d995719db632130e9e063cb1ab7cb4e0fc8d8) +--- + src/providers/backend.h | 1 + + src/providers/data_provider_be.c | 1 + + src/providers/data_provider_callbacks.c | 36 +++++++++++++++++++------ + 3 files changed, 30 insertions(+), 8 deletions(-) + +diff --git a/src/providers/backend.h b/src/providers/backend.h +index 1914274037ce7f7ff4b6d8486b041789a865fd59..6a34b91a911fc12163fa9448ea82ff93f5bf3849 100644 +--- a/src/providers/backend.h ++++ b/src/providers/backend.h +@@ -95,6 +95,7 @@ struct be_ctx { + struct be_cb *online_cb_list; + bool run_online_cb; + struct be_cb *offline_cb_list; ++ bool run_offline_cb; + struct be_cb *reconnect_cb_list; + /* In contrast to online_cb_list which are only run if the backend is + * offline the unconditional_online_cb_list should be run whenever the +diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c +index e8cddd976bb164dc6d4655bf2ebe9a03c3d9d26a..fad6f280195b615d1de45afaf0c459bdf78c8c0a 100644 +--- a/src/providers/data_provider_be.c ++++ b/src/providers/data_provider_be.c +@@ -219,6 +219,7 @@ static void be_reset_offline(struct be_ctx *ctx) + { + ctx->offstat.went_offline = 0; + ctx->offstat.offline = false; ++ ctx->run_offline_cb = true; + + reactivate_subdoms(ctx->domain); + +diff --git a/src/providers/data_provider_callbacks.c b/src/providers/data_provider_callbacks.c +index 436357e228c0e1a689aa18b8ef41a82f63774d3a..24e125ea5be70208d7cf2cb06a80c39207e29db4 100644 +--- a/src/providers/data_provider_callbacks.c ++++ b/src/providers/data_provider_callbacks.c +@@ -265,22 +265,42 @@ void be_run_unconditional_online_cb(struct be_ctx *be) + int be_add_offline_cb(TALLOC_CTX *mem_ctx, struct be_ctx *ctx, be_callback_t cb, + void *pvt, struct be_cb **offline_cb) + { +- return be_add_cb(mem_ctx, ctx, cb, pvt, &ctx->offline_cb_list, offline_cb); ++ int ret; ++ ++ ret = be_add_cb(mem_ctx, ctx, cb, pvt, &ctx->offline_cb_list, offline_cb); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "be_add_cb failed.\n"); ++ return ret; ++ } ++ ++ /* Make sure we run the callback when SSSD goes offline */ ++ ctx->run_offline_cb = true; ++ ++ return EOK; + } + + void be_run_offline_cb(struct be_ctx *be) { + int ret; + +- if (be->offline_cb_list) { +- DEBUG(SSSDBG_MINOR_FAILURE, "Going offline. Running callbacks.\n"); ++ if (be->run_offline_cb) { ++ /* Reset the flag, we only want to run these callbacks once when going ++ * offline */ ++ be->run_offline_cb = false; + +- ret = be_run_cb(be, be->offline_cb_list); +- if (ret != EOK) { +- DEBUG(SSSDBG_CRIT_FAILURE, "be_run_cb failed.\n"); ++ if (be->offline_cb_list) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Going offline. Running callbacks.\n"); ++ ++ ret = be_run_cb(be, be->offline_cb_list); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "be_run_cb failed.\n"); ++ } ++ ++ } else { ++ DEBUG(SSSDBG_TRACE_ALL, ++ "Offline call back list is empty, nothing to do.\n"); + } +- + } else { + DEBUG(SSSDBG_TRACE_ALL, +- "Offline call back list is empty, nothing to do.\n"); ++ "Flag indicates that offline callback were already called.\n"); + } + } +-- +2.17.1 + diff --git a/SOURCES/0009-TESTS-Add-integration-tests-for-the-auto_private_gro.patch b/SOURCES/0009-TESTS-Add-integration-tests-for-the-auto_private_gro.patch deleted file mode 100644 index a9c1356..0000000 --- a/SOURCES/0009-TESTS-Add-integration-tests-for-the-auto_private_gro.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 95053cd058a9045c45c59e002fd6078048fdca76 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 3 Oct 2017 16:55:40 +0200 -Subject: [PATCH 09/21] TESTS: Add integration tests for the - auto_private_groups option -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related: - https://pagure.io/SSSD/sssd/issue/1872 - -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Pavel Březina -(cherry picked from commit 6c802b2009c1b6dd0c3306ba97056e64acc0ec9e) ---- - src/tests/intg/test_enumeration.py | 79 +++++++++++++- - src/tests/intg/test_ldap.py | 214 +++++++++++++++++++++++++++++++++++++ - 2 files changed, 290 insertions(+), 3 deletions(-) - -diff --git a/src/tests/intg/test_enumeration.py b/src/tests/intg/test_enumeration.py -index fdb8d376879f756957f8f25fd28b37d7178aeff5..c7d78155c64dc6c85cb4dc070b205bdcfceff6af 100644 ---- a/src/tests/intg/test_enumeration.py -+++ b/src/tests/intg/test_enumeration.py -@@ -237,9 +237,7 @@ def sanity_rfc2307(request, ldap_conn): - create_sssd_fixture(request) - return None - -- --@pytest.fixture --def sanity_rfc2307_bis(request, ldap_conn): -+def populate_rfc2307bis(request, ldap_conn): - ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) - ent_list.add_user("user1", 1001, 2001) - ent_list.add_user("user2", 1002, 2002) -@@ -266,6 +264,11 @@ def sanity_rfc2307_bis(request, ldap_conn): - [], ["one_user_group1", "one_user_group2"]) - - create_ldap_fixture(request, ldap_conn, ent_list) -+ -+ -+@pytest.fixture -+def sanity_rfc2307_bis(request, ldap_conn): -+ populate_rfc2307bis(request, ldap_conn) - conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) - create_conf_fixture(request, conf) - create_sssd_fixture(request) -@@ -695,3 +698,73 @@ def test_vetoed_shells(vetoed_shells): - shell="/bin/default") - ) - ) -+ -+ -+@pytest.fixture -+def sanity_rfc2307_bis_mpg(request, ldap_conn): -+ populate_rfc2307bis(request, ldap_conn) -+ -+ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) -+ ent_list.add_group_bis("conflict1", 1001) -+ ent_list.add_group_bis("conflict2", 1002) -+ create_ldap_fixture(request, ldap_conn, ent_list) -+ -+ conf = \ -+ format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) + \ -+ unindent(""" -+ [domain/LDAP] -+ auto_private_groups = True -+ """).format(**locals()) -+ create_conf_fixture(request, conf) -+ create_sssd_fixture(request) -+ return None -+ -+ -+def test_ldap_auto_private_groups_enumerate(ldap_conn, -+ sanity_rfc2307_bis_mpg): -+ """ -+ Test the auto_private_groups together with enumeration -+ """ -+ passwd_pattern = ent.contains_only( -+ dict(name='user1', passwd='*', uid=1001, gid=1001, gecos='1001', -+ dir='/home/user1', shell='/bin/bash'), -+ dict(name='user2', passwd='*', uid=1002, gid=1002, gecos='1002', -+ dir='/home/user2', shell='/bin/bash'), -+ dict(name='user3', passwd='*', uid=1003, gid=1003, gecos='1003', -+ dir='/home/user3', shell='/bin/bash') -+ ) -+ ent.assert_passwd(passwd_pattern) -+ -+ group_pattern = ent.contains_only( -+ dict(name='user1', passwd='*', gid=1001, mem=ent.contains_only()), -+ dict(name='user2', passwd='*', gid=1002, mem=ent.contains_only()), -+ dict(name='user3', passwd='*', gid=1003, mem=ent.contains_only()), -+ dict(name='group1', passwd='*', gid=2001, mem=ent.contains_only()), -+ dict(name='group2', passwd='*', gid=2002, mem=ent.contains_only()), -+ dict(name='group3', passwd='*', gid=2003, mem=ent.contains_only()), -+ dict(name='empty_group1', passwd='*', gid=2010, -+ mem=ent.contains_only()), -+ dict(name='empty_group2', passwd='*', gid=2011, -+ mem=ent.contains_only()), -+ dict(name='two_user_group', passwd='*', gid=2012, -+ mem=ent.contains_only("user1", "user2")), -+ dict(name='group_empty_group', passwd='*', gid=2013, -+ mem=ent.contains_only()), -+ dict(name='group_two_empty_groups', passwd='*', gid=2014, -+ mem=ent.contains_only()), -+ dict(name='one_user_group1', passwd='*', gid=2015, -+ mem=ent.contains_only("user1")), -+ dict(name='one_user_group2', passwd='*', gid=2016, -+ mem=ent.contains_only("user2")), -+ dict(name='group_one_user_group', passwd='*', gid=2017, -+ mem=ent.contains_only("user1")), -+ dict(name='group_two_user_group', passwd='*', gid=2018, -+ mem=ent.contains_only("user1", "user2")), -+ dict(name='group_two_one_user_groups', passwd='*', gid=2019, -+ mem=ent.contains_only("user1", "user2")) -+ ) -+ ent.assert_group(group_pattern) -+ -+ with pytest.raises(KeyError): -+ grp.getgrnam("conflict1") -+ ent.assert_group_by_gid(1002, dict(name="user2", mem=ent.contains_only())) -diff --git a/src/tests/intg/test_ldap.py b/src/tests/intg/test_ldap.py -index f2467f1ffe9890049ad73bba6432102d029510e8..a6659b1b78df4d72eb98c208d67ee5d10c9c88ea 100644 ---- a/src/tests/intg/test_ldap.py -+++ b/src/tests/intg/test_ldap.py -@@ -1169,3 +1169,217 @@ def test_nss_filters_cached(ldap_conn, sanity_nss_filter_cached): - - res, _ = call_sssd_getgrgid(0) - assert res == NssReturnCode.NOTFOUND -+ -+ -+@pytest.fixture -+def mpg_setup(request, ldap_conn): -+ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) -+ ent_list.add_user("user1", 1001, 2001) -+ ent_list.add_user("user2", 1002, 2002) -+ ent_list.add_user("user3", 1003, 2003) -+ -+ ent_list.add_group_bis("group1", 2001) -+ ent_list.add_group_bis("group2", 2002) -+ ent_list.add_group_bis("group3", 2003) -+ -+ ent_list.add_group_bis("two_user_group", 2012, ["user1", "user2"]) -+ ent_list.add_group_bis("one_user_group1", 2015, ["user1"]) -+ ent_list.add_group_bis("one_user_group2", 2016, ["user2"]) -+ -+ create_ldap_entries(ldap_conn, ent_list) -+ create_ldap_cleanup(request, ldap_conn, None) -+ -+ conf = \ -+ format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) + \ -+ unindent(""" -+ [domain/LDAP] -+ auto_private_groups = True -+ """).format(**locals()) -+ create_conf_fixture(request, conf) -+ create_sssd_fixture(request) -+ return None -+ -+ -+def test_ldap_auto_private_groups_direct(ldap_conn, mpg_setup): -+ """ -+ Integration test for auto_private_groups -+ -+ See also ticket https://pagure.io/SSSD/sssd/issue/1872 -+ """ -+ # Make sure the user's GID is taken from their uidNumber -+ ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=1001)) -+ # Make sure the private group is resolvable by name and by GID -+ ent.assert_group_by_name("user1", dict(gid=1001, mem=ent.contains_only())) -+ ent.assert_group_by_gid(1001, dict(name="user1", mem=ent.contains_only())) -+ -+ # The group referenced in user's gidNumber attribute should be still -+ # visible, but it's fine that it doesn't contain the user as a member -+ # as the group is currently added during the initgroups operation only -+ ent.assert_group_by_name("group1", dict(gid=2001, mem=ent.contains_only())) -+ ent.assert_group_by_gid(2001, dict(name="group1", mem=ent.contains_only())) -+ -+ # The user's secondary groups list must be correct as well -+ # Note that the original GID is listed as well -- this is correct and expected -+ # because we save the original GID in the SYSDB_PRIMARY_GROUP_GIDNUM attribute -+ user1_expected_gids = [1001, 2001, 2012, 2015] -+ (res, errno, gids) = sssd_id.call_sssd_initgroups("user1", 1001) -+ assert res == sssd_id.NssReturnCode.SUCCESS -+ -+ assert sorted(gids) == sorted(user1_expected_gids), \ -+ "result: %s\n expected %s" % ( -+ ", ".join(["%s" % s for s in sorted(gids)]), -+ ", ".join(["%s" % s for s in sorted(user1_expected_gids)]) -+ ) -+ -+ # Request user2's private group by GID without resolving the user first. -+ # This must trigger user resolution through by-GID resolution, since the GID -+ # doesn't exist on its own in LDAP -+ ent.assert_group_by_gid(1002, dict(name="user2", mem=ent.contains_only())) -+ -+ # Test supplementary groups for user2 as well -+ user1_expected_gids = [1002, 2002, 2012, 2016] -+ (res, errno, gids) = sssd_id.call_sssd_initgroups("user2", 1002) -+ assert res == sssd_id.NssReturnCode.SUCCESS -+ -+ assert sorted(gids) == sorted(user1_expected_gids), \ -+ "result: %s\n expected %s" % ( -+ ", ".join(["%s" % s for s in sorted(gids)]), -+ ", ".join(["%s" % s for s in sorted(user1_expected_gids)]) -+ ) -+ -+ # Request user3's private group by name without resolving the user first -+ # This must trigger user resolution through by-name resolution, since the -+ # name doesn't exist on its own in LDAP -+ ent.assert_group_by_name("user3", dict(gid=1003, mem=ent.contains_only())) -+ -+ # Remove entries and request them again to make sure they are not -+ # resolvable anymore -+ cleanup_ldap_entries(ldap_conn, None) -+ -+ if subprocess.call(["sss_cache", "-GU"]) != 0: -+ raise Exception("sssd_cache failed") -+ -+ with pytest.raises(KeyError): -+ pwd.getpwnam("user1") -+ with pytest.raises(KeyError): -+ grp.getgrnam("user1") -+ with pytest.raises(KeyError): -+ grp.getgrgid(1002) -+ with pytest.raises(KeyError): -+ grp.getgrnam("user3") -+ -+ -+@pytest.fixture -+def mpg_setup_conflict(request, ldap_conn): -+ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) -+ ent_list.add_user("user1", 1001, 2001) -+ ent_list.add_user("user2", 1002, 2002) -+ ent_list.add_user("user3", 1003, 1003) -+ ent_list.add_group_bis("group1", 1001) -+ ent_list.add_group_bis("group2", 1002) -+ ent_list.add_group_bis("group3", 1003) -+ ent_list.add_group_bis("supp_group", 2015, ["user3"]) -+ create_ldap_fixture(request, ldap_conn, ent_list) -+ -+ conf = \ -+ format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) + \ -+ unindent(""" -+ [domain/LDAP] -+ auto_private_groups = True -+ """).format(**locals()) -+ create_conf_fixture(request, conf) -+ create_sssd_fixture(request) -+ return None -+ -+ -+def test_ldap_auto_private_groups_conflict(ldap_conn, mpg_setup_conflict): -+ """ -+ Make sure that conflicts between groups that are auto-created with the -+ help of the auto_private_groups option and between 'real' LDAP groups -+ are handled in a predictable manner. -+ """ -+ # Make sure the user's GID is taken from their uidNumber -+ ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=1001)) -+ # Make sure the private group is resolvable by name and by GID -+ ent.assert_group_by_name("user1", dict(gid=1001, mem=ent.contains_only())) -+ ent.assert_group_by_gid(1001, dict(name="user1", mem=ent.contains_only())) -+ -+ # Let's request the group with the same ID as user2's private group -+ # The request should match the 'real' group -+ ent.assert_group_by_gid(1002, dict(name="group2", mem=ent.contains_only())) -+ # But because of the GID conflict, the user cannot be resolved -+ with pytest.raises(KeyError): -+ pwd.getpwnam("user2") -+ -+ # This user's GID is the same as the UID in this entry. The most important -+ # thing here is that the supplementary groups are correct and the GID -+ # resolves to the private group (as long as the user was requested first) -+ user3_expected_gids = [1003, 2015] -+ ent.assert_passwd_by_name("user3", dict(name="user3", uid=1003, gid=1003)) -+ (res, errno, gids) = sssd_id.call_sssd_initgroups("user3", 1003) -+ assert res == sssd_id.NssReturnCode.SUCCESS -+ -+ assert sorted(gids) == sorted(user3_expected_gids), \ -+ "result: %s\n expected %s" % ( -+ ", ".join(["%s" % s for s in sorted(gids)]), -+ ", ".join(["%s" % s for s in sorted(user3_expected_gids)]) -+ ) -+ # Make sure the private group is resolvable by name and by GID -+ ent.assert_group_by_gid(1003, dict(name="user3", mem=ent.contains_only())) -+ ent.assert_group_by_name("user3", dict(gid=1003, mem=ent.contains_only())) -+ -+ -+@pytest.fixture -+def mpg_setup_no_gid(request, ldap_conn): -+ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) -+ ent_list.add_user("user1", 1001, 2001) -+ -+ ent_list.add_group_bis("group1", 2001) -+ ent_list.add_group_bis("one_user_group1", 2015, ["user1"]) -+ -+ create_ldap_entries(ldap_conn, ent_list) -+ create_ldap_cleanup(request, ldap_conn, None) -+ -+ conf = \ -+ format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) + \ -+ unindent(""" -+ [domain/LDAP] -+ auto_private_groups = True -+ ldap_user_gid_number = no_such_attribute -+ """).format(**locals()) -+ create_conf_fixture(request, conf) -+ create_sssd_fixture(request) -+ return None -+ -+ -+def test_ldap_auto_private_groups_direct_no_gid(ldap_conn, mpg_setup_no_gid): -+ """ -+ Integration test for auto_private_groups - test that even a user with -+ no GID assigned at all can be resolved including their autogenerated -+ primary group. -+ -+ See also ticket https://pagure.io/SSSD/sssd/issue/1872 -+ """ -+ # Make sure the user's GID is taken from their uidNumber -+ ent.assert_passwd_by_name("user1", dict(name="user1", uid=1001, gid=1001)) -+ # Make sure the private group is resolvable by name and by GID -+ ent.assert_group_by_name("user1", dict(gid=1001, mem=ent.contains_only())) -+ ent.assert_group_by_gid(1001, dict(name="user1", mem=ent.contains_only())) -+ -+ # The group referenced in user's gidNumber attribute should be still -+ # visible, but shouldn't have any relation to the user -+ ent.assert_group_by_name("group1", dict(gid=2001, mem=ent.contains_only())) -+ ent.assert_group_by_gid(2001, dict(name="group1", mem=ent.contains_only())) -+ -+ # The user's secondary groups list must be correct as well. This time only -+ # the generated group and the explicit secondary group are added, since -+ # there is no original GID -+ user1_expected_gids = [1001, 2015] -+ (res, errno, gids) = sssd_id.call_sssd_initgroups("user1", 1001) -+ assert res == sssd_id.NssReturnCode.SUCCESS -+ -+ assert sorted(gids) == sorted(user1_expected_gids), \ -+ "result: %s\n expected %s" % ( -+ ", ".join(["%s" % s for s in sorted(gids)]), -+ ", ".join(["%s" % s for s in sorted(user1_expected_gids)]) -+ ) --- -2.13.5 - diff --git a/SOURCES/0009-TESTS-Extend-the-schema-with-sshPublicKey-attribute.patch b/SOURCES/0009-TESTS-Extend-the-schema-with-sshPublicKey-attribute.patch new file mode 100644 index 0000000..3cb7eda --- /dev/null +++ b/SOURCES/0009-TESTS-Extend-the-schema-with-sshPublicKey-attribute.patch @@ -0,0 +1,62 @@ +From 2b210b10ce54f6f2595f6ab181a51bce367d43a9 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Sun, 17 Jun 2018 21:48:36 +0200 +Subject: [PATCH] TESTS: Extend the schema with sshPublicKey attribute +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This will allow to store the users with a sshPublicKey attribute +provided that they have the right objectclass as well. + +Related to: +https://pagure.io/SSSD/sssd/issue/3747 + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit 1575ec97e080656f69b3f93e641c76e74ffb8182) + +DOWNSTREAM: +Resolves: rhbz#1583343 - Login with sshkeys stored in ipa not working after update to RHEL-7.5 +--- + src/tests/intg/data/ssh_schema.ldif | 11 +++++++++++ + src/tests/intg/ds_openldap.py | 6 ++++++ + 2 files changed, 17 insertions(+) + create mode 100644 src/tests/intg/data/ssh_schema.ldif + +diff --git a/src/tests/intg/data/ssh_schema.ldif b/src/tests/intg/data/ssh_schema.ldif +new file mode 100644 +index 0000000000000000000000000000000000000000..efe05706b9ded5614a7f3f5e0bab28a7eb869daa +--- /dev/null ++++ b/src/tests/intg/data/ssh_schema.ldif +@@ -0,0 +1,11 @@ ++dn: cn=openssh-lpk,cn=schema,cn=config ++objectClass: olcSchemaConfig ++cn: openssh-lpk ++olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' ++ DESC 'MANDATORY: OpenSSH Public key' ++ EQUALITY octetStringMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) ++olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY ++ DESC 'MANDATORY: OpenSSH LPK objectclass' ++ MAY ( sshPublicKey $ uid ) ++ ) +diff --git a/src/tests/intg/ds_openldap.py b/src/tests/intg/ds_openldap.py +index 842ff910803658834841c8f9181f3c4af29b955a..c9a4b6de8c53c6644b3de9047d657ee35ce06512 100644 +--- a/src/tests/intg/ds_openldap.py ++++ b/src/tests/intg/ds_openldap.py +@@ -186,6 +186,12 @@ class DSOpenLDAP(DS): + db_config_file.write(db_config) + db_config_file.close() + ++ # Import ad schema ++ subprocess.check_call( ++ ["slapadd", "-F", self.conf_slapd_d_dir, "-b", "cn=config", ++ "-l", "data/ssh_schema.ldif"], ++ ) ++ + def _start_daemon(self): + """Start the instance.""" + if subprocess.call(["slapd", "-F", self.conf_slapd_d_dir, +-- +2.17.1 + diff --git a/SOURCES/0010-CACHE_REQ-Copy-the-cr_domain-list-for-each-request.patch b/SOURCES/0010-CACHE_REQ-Copy-the-cr_domain-list-for-each-request.patch deleted file mode 100644 index 39c79de..0000000 --- a/SOURCES/0010-CACHE_REQ-Copy-the-cr_domain-list-for-each-request.patch +++ /dev/null @@ -1,142 +0,0 @@ -From ec3334b5a09328de492804c391654073553ff7e7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= -Date: Fri, 20 Oct 2017 09:26:43 +0200 -Subject: [PATCH 10/21] CACHE_REQ: Copy the cr_domain list for each request -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let's copy the cr_domain list for each request as this list may be -free'd due to a refresh domains request. - -Resolves: https://pagure.io/SSSD/sssd/issue/3551 - -Signed-off-by: Fabiano Fidêncio - -Reviewed-by: Pavel Březina -(cherry picked from commit 0f44eefe2ce75a0814c8688495477f6c57f3d39a) ---- - src/responder/common/cache_req/cache_req.c | 14 +++++++-- - src/responder/common/cache_req/cache_req_domain.c | 38 +++++++++++++++++++++++ - src/responder/common/cache_req/cache_req_domain.h | 5 +++ - 3 files changed, 55 insertions(+), 2 deletions(-) - -diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c -index abcb9cba351b06e833bacde26a504e5ee3445528..5fed7a2ab8beded2fee91f679a12f9a0ff6013ec 100644 ---- a/src/responder/common/cache_req/cache_req.c -+++ b/src/responder/common/cache_req/cache_req.c -@@ -699,6 +699,7 @@ struct cache_req_state { - const char *domain_name; - - /* work data */ -+ struct cache_req_domain *cr_domains; - struct cache_req_result **results; - size_t num_results; - bool first_iteration; -@@ -953,6 +954,7 @@ static errno_t cache_req_select_domains(struct tevent_req *req, - bool bypass_cache; - bool bypass_dp; - bool search; -+ errno_t ret; - - state = tevent_req_data(req, struct cache_req_state); - -@@ -964,12 +966,20 @@ static errno_t cache_req_select_domains(struct tevent_req *req, - return EOK; - } - -+ ret = cache_req_domain_copy_cr_domains(state, -+ state->cr->rctx->cr_domains, -+ &state->cr_domains); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "cache_req_copy_cr_domains() failed\n"); -+ return EINVAL; -+ } -+ - if (domain_name != NULL) { - CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, - "Performing a single domain search\n"); - - cr_domain = cache_req_domain_get_domain_by_name( -- state->cr->rctx->cr_domains, domain_name); -+ state->cr_domains, domain_name); - if (cr_domain == NULL) { - return ERR_DOMAIN_NOT_FOUND; - } -@@ -978,7 +988,7 @@ static errno_t cache_req_select_domains(struct tevent_req *req, - CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, - "Performing a multi-domain search\n"); - -- cr_domain = state->cr->rctx->cr_domains; -+ cr_domain = state->cr_domains; - check_next = true; - } - -diff --git a/src/responder/common/cache_req/cache_req_domain.c b/src/responder/common/cache_req/cache_req_domain.c -index 7b58f7c94a77881429f870bc5162fb2fe0aa57c6..15893ba548f6d0e3979010d6d5bbf27441d5fa97 100644 ---- a/src/responder/common/cache_req/cache_req_domain.c -+++ b/src/responder/common/cache_req/cache_req_domain.c -@@ -47,6 +47,44 @@ cache_req_domain_get_domain_by_name(struct cache_req_domain *domains, - return ret; - } - -+errno_t -+cache_req_domain_copy_cr_domains(TALLOC_CTX *mem_ctx, -+ struct cache_req_domain *src, -+ struct cache_req_domain **_dest) -+{ -+ struct cache_req_domain *cr_domains = NULL; -+ struct cache_req_domain *cr_domain; -+ struct cache_req_domain *iter; -+ errno_t ret; -+ -+ if (src == NULL) { -+ return EINVAL; -+ } -+ -+ DLIST_FOR_EACH(iter, src) { -+ cr_domain = talloc_zero(mem_ctx, struct cache_req_domain); -+ if (cr_domain == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ cr_domain->domain = iter->domain; -+ cr_domain->fqnames = iter->fqnames; -+ -+ DLIST_ADD_END(cr_domains, cr_domain, struct cache_req_domain *); -+ } -+ -+ *_dest = cr_domains; -+ ret = EOK; -+ -+done: -+ if (ret != EOK) { -+ cache_req_domain_list_zfree(&cr_domains); -+ } -+ -+ return ret; -+} -+ - void cache_req_domain_list_zfree(struct cache_req_domain **cr_domains) - { - struct cache_req_domain *p, *q, *r; -diff --git a/src/responder/common/cache_req/cache_req_domain.h b/src/responder/common/cache_req/cache_req_domain.h -index 3780a5d8d88d76e100738d28d1dd0e697edf5eae..ebdc71dd635d5d8a5d06e30e96c5d4101b6d98bf 100644 ---- a/src/responder/common/cache_req/cache_req_domain.h -+++ b/src/responder/common/cache_req/cache_req_domain.h -@@ -50,6 +50,11 @@ cache_req_domain_new_list_from_domain_resolution_order( - const char *domain_resolution_order, - struct cache_req_domain **_cr_domains); - -+errno_t -+cache_req_domain_copy_cr_domains(TALLOC_CTX *mem_ctx, -+ struct cache_req_domain *src, -+ struct cache_req_domain **_dest); -+ - void cache_req_domain_list_zfree(struct cache_req_domain **cr_domains); - - --- -2.13.5 - diff --git a/SOURCES/0010-TESTS-Allow-adding-sshPublicKey-for-users.patch b/SOURCES/0010-TESTS-Allow-adding-sshPublicKey-for-users.patch new file mode 100644 index 0000000..ed461cd --- /dev/null +++ b/SOURCES/0010-TESTS-Allow-adding-sshPublicKey-for-users.patch @@ -0,0 +1,78 @@ +From 4bff9d92a51bff2fabb6168f8ae69c8a8d17ba2a Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Sun, 17 Jun 2018 22:06:22 +0200 +Subject: [PATCH] TESTS: Allow adding sshPublicKey for users +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Adds the objectclass and allows storing a list of sshPublicKey +attributes for users. Since there is no harm in adding the extra +objectclass, we can do it unconditionally. + +Related to: +https://pagure.io/SSSD/sssd/issue/3747 + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit 56cda832e9f61c52e9cfde1f0864507de718ffbb) +--- + src/tests/intg/ldap_ent.py | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/src/tests/intg/ldap_ent.py b/src/tests/intg/ldap_ent.py +index 6b6d8f903cbcc277d892c3212ca382f4aaadc671..a4c987969d3dcefba2af69e095b220180e0fa54c 100644 +--- a/src/tests/intg/ldap_ent.py ++++ b/src/tests/intg/ldap_ent.py +@@ -24,7 +24,8 @@ def user(base_dn, uid, uidNumber, gidNumber, + homeDirectory=None, + loginShell=None, + cn=None, +- sn=None): ++ sn=None, ++ sshPubKey=()): + """ + Generate an RFC2307(bis) user add-modlist for passing to ldap.add* + """ +@@ -33,7 +34,8 @@ def user(base_dn, uid, uidNumber, gidNumber, + user = ( + "uid=" + uid + ",ou=Users," + base_dn, + [ +- ('objectClass', [b'top', b'inetOrgPerson', b'posixAccount']), ++ ('objectClass', [b'top', b'inetOrgPerson', ++ b'posixAccount', b'ldapPublicKey']), + ('cn', [uidNumber if cn is None else cn.encode('utf-8')]), + ('sn', [b'User' if sn is None else sn.encode('utf-8')]), + ('uidNumber', [uidNumber]), +@@ -51,6 +53,9 @@ def user(base_dn, uid, uidNumber, gidNumber, + ) + if gecos is not None: + user[1].append(('gecos', [gecos.encode('utf-8')])) ++ if len(sshPubKey) > 0: ++ pubkeys = [key.encode('utf-8') for key in sshPubKey] ++ user[1].append(('sshPublicKey', pubkeys)) + return user + + +@@ -118,7 +123,8 @@ class List(list): + homeDirectory=None, + loginShell=None, + cn=None, +- sn=None): ++ sn=None, ++ sshPubKey=()): + """Add an RFC2307(bis) user add-modlist.""" + self.append(user(base_dn or self.base_dn, + uid, uidNumber, gidNumber, +@@ -127,7 +133,8 @@ class List(list): + homeDirectory=homeDirectory, + loginShell=loginShell, + cn=cn, +- sn=sn)) ++ sn=sn, ++ sshPubKey=sshPubKey)) + + def add_group(self, cn, gidNumber, member_uids=[], + base_dn=None): +-- +2.17.1 + diff --git a/SOURCES/0011-MAN-GPO-Security-Filtering-limitation.patch b/SOURCES/0011-MAN-GPO-Security-Filtering-limitation.patch deleted file mode 100644 index 880f661..0000000 --- a/SOURCES/0011-MAN-GPO-Security-Filtering-limitation.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 314c3a0efc276b74f7a2e39da4db29d8fbf43b12 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michal=20=C5=BDidek?= -Date: Thu, 26 Oct 2017 17:12:17 +0200 -Subject: [PATCH 11/21] MAN: GPO Security Filtering limitation -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Note in the man pages that current version of SSSD does not support -host entries in the 'Security filtering' list. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3444 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 6c1661d2f4e860d1b547d6188a4fe2bd564e87cf) ---- - src/man/sssd-ad.5.xml | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml -index 08c1dd09fb829c6cffb416250b9b518668ec5790..649042d587de3d3600fff59866681e302c721af8 100644 ---- a/src/man/sssd-ad.5.xml -+++ b/src/man/sssd-ad.5.xml -@@ -346,6 +346,13 @@ DOM:dom1:(memberOf:1.2.840.113556.1.4.1941:=cn=nestedgroup,ou=groups,dc=example, - host. - - -+ NOTE: The current version of SSSD does not support -+ host (computer) entries in the GPO 'Security -+ Filtering' list. Only user and group entries are -+ supported. Host entries in the list have no -+ effect. -+ -+ - NOTE: If the operation mode is set to enforcing, it - is possible that users that were previously allowed - logon access will now be denied logon access (as --- -2.13.5 - diff --git a/SOURCES/0011-TESTS-Add-a-basic-SSH-responder-test.patch b/SOURCES/0011-TESTS-Add-a-basic-SSH-responder-test.patch new file mode 100644 index 0000000..0760c43 --- /dev/null +++ b/SOURCES/0011-TESTS-Add-a-basic-SSH-responder-test.patch @@ -0,0 +1,276 @@ +From 079464a0fd417f09cfafa2bda9ff1a4e1afdbe8a Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 18 Jun 2018 09:12:13 +0200 +Subject: [PATCH] TESTS: Add a basic SSH responder test +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Adds a basic test that makes sure that a list of SSH public keys can be +retrieved. This is to make sure we don't break the SSH integration later +on. + +Related: +https://pagure.io/SSSD/sssd/issue/3747 + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit 804c5b538ad89a1a3897b93f39d716fa50530842) +--- + src/tests/intg/Makefile.am | 1 + + src/tests/intg/test_ssh_pubkey.py | 232 ++++++++++++++++++++++++++++++ + 2 files changed, 233 insertions(+) + create mode 100644 src/tests/intg/test_ssh_pubkey.py + +diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am +index 9c5338261353f473d9051c0512c15a54ec38e1ec..a15022eb578394313155538898fe7cd7407eb9c0 100644 +--- a/src/tests/intg/Makefile.am ++++ b/src/tests/intg/Makefile.am +@@ -36,6 +36,7 @@ dist_noinst_DATA = \ + data/ad_schema.ldif \ + test_pysss_nss_idmap.py \ + test_infopipe.py \ ++ test_ssh_pubkey.py \ + $(NULL) + + EXTRA_DIST = data/cwrap-dbus-system.conf.in +diff --git a/src/tests/intg/test_ssh_pubkey.py b/src/tests/intg/test_ssh_pubkey.py +new file mode 100644 +index 0000000000000000000000000000000000000000..fbf55566e341373873057ec4e3af1d7f83202aa7 +--- /dev/null ++++ b/src/tests/intg/test_ssh_pubkey.py +@@ -0,0 +1,232 @@ ++# ++# ssh public key integration test ++# ++# Copyright (c) 2018 Red Hat, Inc. ++# ++# This 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; version 2 only ++# ++# 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 . ++# ++ ++import os ++import stat ++import signal ++import subprocess ++import time ++import ldap ++import ldap.modlist ++import pytest ++ ++import config ++import ds_openldap ++import ent ++import ldap_ent ++from util import unindent, get_call_output ++ ++LDAP_BASE_DN = "dc=example,dc=com" ++ ++USER1_PUBKEY1 = "ssh-dss AAAAB3NzaC1kc3MAAACBAPMkvcU53RVhBtjwiC3IqeRIWR9Qwdv8\ ++DmZzEsDD3Csd6jYxMsPZoXcPrHqwYcEj1s5MVqhdSFS0Cjz13e7gO6OMLInO3xMBSSFHjfp9RE1H\ ++pgc4WisazzyJaW9EMkQo/DqvkFkKh31oqAmxcSbLAFJRg4TTIqm18qu8IRKS6m/RAAAAFQC97TA5\ ++JSsMsaX1bRszC7y4PhMBvQAAAIEAt9Yo9v/h9W4nDbzUdkGwNRszlPEK+T12bJv0O9Fk6subD3Do\ ++6A4Qru/Nr6voXoq8b018Wb7iFWvKOoz5uT/plWBKLXL2NN7ovTR+dUJIzvwurQZroukmU1EghNey\ ++lkSHmDlxSoMK6Nh21uGu6l+b6x5pXNaZHMpsywG4kY8SoC0AAACAAWLHneEGvqkYA8La4Eob+Hjj\ ++mAKilx8byxm3Kfb1XO+ZrR6XxadofZOaUYRMpPKgFjKAKPxJftPLiDjWM7lSe6h8df0dUMLVXt6m\ ++eA83kE0uK5JOOGJfJDqmRed2YnfxUDNNFQGT4xFWGrNtYNbGyw9BWKbkooAsLqaO04zP3Rs= \ ++user1@LDAP" ++ ++USER1_PUBKEY2 = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwHUUF3HPH+DkU6j8k7Q1wHG\ ++RJY9NeLqSav3h95mTSCQYPSC7I9RTJ4OORgqCbEzrP/DYrrn4TtQ9dhRJar3ZY+F36SH5yFIXORb\ ++lAIbFU+/anahBuFS9vHi1MqFPckGmwJ4QCpjQhdYxo1ro0e1RuGSaQNp/w9N6S/fDz4Cj4I99xDz\ ++SeQeGHxYv0e60plQ8dUajmnaGmYRJHF9a6Ban7IWySActCja7eQP2zIRXEZMpuhl1E0U4y+gHTFI\ ++gD3zQai3QrXm8RUrQURIJ0u6BlGS910OPbHqLpLTFWG08L8sNUcYzC+DY6yoCSO0n/Df3pVRS4C9\ ++5Krf3FqppMTjdfQ== user1@LDAP" ++ ++ ++@pytest.fixture(scope="module") ++def ds_inst(request): ++ """LDAP server instance fixture""" ++ ds_inst = ds_openldap.DSOpenLDAP( ++ config.PREFIX, 10389, LDAP_BASE_DN, ++ "cn=admin", "Secret123" ++ ) ++ ++ try: ++ ds_inst.setup() ++ except: ++ ds_inst.teardown() ++ raise ++ request.addfinalizer(ds_inst.teardown) ++ return ds_inst ++ ++ ++@pytest.fixture(scope="module") ++def ldap_conn(request, ds_inst): ++ """LDAP server connection fixture""" ++ ldap_conn = ds_inst.bind() ++ ldap_conn.ds_inst = ds_inst ++ request.addfinalizer(ldap_conn.unbind_s) ++ return ldap_conn ++ ++ ++def create_ldap_entries(ldap_conn, ent_list=None): ++ """Add LDAP entries from ent_list""" ++ if ent_list is not None: ++ for entry in ent_list: ++ ldap_conn.add_s(entry[0], entry[1]) ++ ++ ++def cleanup_ldap_entries(ldap_conn, ent_list=None): ++ """Remove LDAP entries added by create_ldap_entries""" ++ if ent_list is None: ++ for ou in ("Users", "Groups", "Netgroups", "Services", "Policies"): ++ for entry in ldap_conn.search_s("ou=" + ou + "," + ++ ldap_conn.ds_inst.base_dn, ++ ldap.SCOPE_ONELEVEL, ++ attrlist=[]): ++ ldap_conn.delete_s(entry[0]) ++ else: ++ for entry in ent_list: ++ ldap_conn.delete_s(entry[0]) ++ ++ ++def create_ldap_cleanup(request, ldap_conn, ent_list=None): ++ """Add teardown for removing all user/group LDAP entries""" ++ request.addfinalizer(lambda: cleanup_ldap_entries(ldap_conn, ent_list)) ++ ++ ++def create_ldap_fixture(request, ldap_conn, ent_list=None): ++ """Add LDAP entries and add teardown for removing them""" ++ create_ldap_entries(ldap_conn, ent_list) ++ create_ldap_cleanup(request, ldap_conn, ent_list) ++ ++ ++SCHEMA_RFC2307_BIS = "rfc2307bis" ++ ++ ++def format_basic_conf(ldap_conn, schema): ++ """Format a basic SSSD configuration""" ++ schema_conf = "ldap_schema = " + schema + "\n" ++ schema_conf += "ldap_group_object_class = groupOfNames\n" ++ return unindent("""\ ++ [sssd] ++ domains = LDAP ++ services = nss, ssh ++ ++ [nss] ++ ++ [ssh] ++ debug_level=10 ++ ++ [domain/LDAP] ++ {schema_conf} ++ id_provider = ldap ++ auth_provider = ldap ++ ldap_uri = {ldap_conn.ds_inst.ldap_url} ++ ldap_search_base = {ldap_conn.ds_inst.base_dn} ++ ldap_sudo_use_host_filter = false ++ debug_level=10 ++ """).format(**locals()) ++ ++ ++def create_conf_file(contents): ++ """Create sssd.conf with specified contents""" ++ conf = open(config.CONF_PATH, "w") ++ conf.write(contents) ++ conf.close() ++ os.chmod(config.CONF_PATH, stat.S_IRUSR | stat.S_IWUSR) ++ ++ ++def cleanup_conf_file(): ++ """Remove sssd.conf, if it exists""" ++ if os.path.lexists(config.CONF_PATH): ++ os.unlink(config.CONF_PATH) ++ ++ ++def create_conf_cleanup(request): ++ """Add teardown for removing sssd.conf""" ++ request.addfinalizer(cleanup_conf_file) ++ ++ ++def create_conf_fixture(request, contents): ++ """ ++ Create sssd.conf with specified contents and add teardown for removing it ++ """ ++ create_conf_file(contents) ++ create_conf_cleanup(request) ++ ++ ++def create_sssd_process(): ++ """Start the SSSD process""" ++ if subprocess.call(["sssd", "-D", "-f"]) != 0: ++ raise Exception("sssd start failed") ++ ++ ++def get_sssd_pid(): ++ pid_file = open(config.PIDFILE_PATH, "r") ++ pid = int(pid_file.read()) ++ return pid ++ ++ ++def cleanup_sssd_process(): ++ """Stop the SSSD process and remove its state""" ++ try: ++ pid = get_sssd_pid() ++ os.kill(pid, signal.SIGTERM) ++ while True: ++ try: ++ os.kill(pid, signal.SIGCONT) ++ except: ++ break ++ time.sleep(1) ++ except: ++ pass ++ for path in os.listdir(config.DB_PATH): ++ os.unlink(config.DB_PATH + "/" + path) ++ for path in os.listdir(config.MCACHE_PATH): ++ os.unlink(config.MCACHE_PATH + "/" + path) ++ ++ ++def create_sssd_fixture(request): ++ """Start SSSD and add teardown for stopping it and removing its state""" ++ create_sssd_process() ++ create_sssd_cleanup(request) ++ ++ ++def create_sssd_cleanup(request): ++ """Add teardown for stopping SSSD and removing its state""" ++ request.addfinalizer(cleanup_sssd_process) ++ ++ ++@pytest.fixture ++def add_user_with_ssh_key(request, ldap_conn): ++ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ++ ent_list.add_user("user1", 1001, 2001, ++ sshPubKey=(USER1_PUBKEY1, USER1_PUBKEY2)) ++ ent_list.add_user("user2", 1002, 2001) ++ create_ldap_fixture(request, ldap_conn, ent_list) ++ ++ conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) ++ create_conf_fixture(request, conf) ++ create_sssd_fixture(request) ++ return None ++ ++ ++def test_ssh_pubkey_retrieve(add_user_with_ssh_key): ++ """ ++ Test that we can retrieve an SSH public key for a user who has one ++ and can't retrieve a key for a user who does not have one. ++ """ ++ sshpubkey = get_call_output(["sss_ssh_authorizedkeys", "user1"]) ++ assert sshpubkey == USER1_PUBKEY1 + '\n' + USER1_PUBKEY2 + '\n' ++ ++ sshpubkey = get_call_output(["sss_ssh_authorizedkeys", "user2"]) ++ assert len(sshpubkey) == 0 +-- +2.17.1 + diff --git a/SOURCES/0012-SSH-Do-not-exit-abruptly-if-SSHD-closes-its-end-of-t.patch b/SOURCES/0012-SSH-Do-not-exit-abruptly-if-SSHD-closes-its-end-of-t.patch new file mode 100644 index 0000000..b212cbc --- /dev/null +++ b/SOURCES/0012-SSH-Do-not-exit-abruptly-if-SSHD-closes-its-end-of-t.patch @@ -0,0 +1,88 @@ +From 60f868ac16c4678d60f17d62fa3b47534d4d07cb Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 28 May 2018 21:41:49 +0200 +Subject: [PATCH] SSH: Do not exit abruptly if SSHD closes its end of the pipe + before reading all the SSH keys +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Resolves: +https://pagure.io/SSSD/sssd/issue/3747 + +Before writing the keys to sshd, ignore SIGPIPE so that if the pipe +towards the authorizedkeys helper is closed, the sss_ssh_authorizedkeys +helper is not terminated with SIGPIPE, but instead proceeds and then the +write(2) calls would non-terminally fail with EPIPE. + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit cb138d7d060611e891d341db08477e41f9a3d17d) +--- + src/sss_client/ssh/sss_ssh_authorizedkeys.c | 35 ++++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +diff --git a/src/sss_client/ssh/sss_ssh_authorizedkeys.c b/src/sss_client/ssh/sss_ssh_authorizedkeys.c +index 782a9f44379bff5346c896b3e03570720632c0be..b0280fbf8b0ed0501d792973241b826fc4a7a04d 100644 +--- a/src/sss_client/ssh/sss_ssh_authorizedkeys.c ++++ b/src/sss_client/ssh/sss_ssh_authorizedkeys.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #include "util/util.h" + #include "util/crypto/sss_crypto.h" +@@ -99,8 +100,16 @@ int main(int argc, const char **argv) + goto fini; + } + ++ /* if sshd closes its end of the pipe, we don't want sss_ssh_authorizedkeys ++ * to exit abruptly, but to finish gracefully instead because the valid ++ * key can be present in the data already written ++ */ ++ signal(SIGPIPE, SIG_IGN); ++ + /* print results */ + for (i = 0; i < ent->num_pubkeys; i++) { ++ char *repr_break = NULL; ++ + ret = sss_ssh_format_pubkey(mem_ctx, &ent->pubkeys[i], &repr); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +@@ -109,7 +118,31 @@ int main(int argc, const char **argv) + continue; + } + +- printf("%s\n", repr); ++ /* OpenSSH expects a linebreak after each key */ ++ repr_break = talloc_asprintf(mem_ctx, "%s\n", repr); ++ talloc_zfree(repr); ++ if (repr_break == NULL) { ++ ret = ENOMEM; ++ goto fini; ++ } ++ ++ ret = sss_atomic_write_s(STDOUT_FILENO, repr_break, strlen(repr_break)); ++ /* Avoid spiking memory with too many large keys */ ++ talloc_zfree(repr_break); ++ if (ret < 0) { ++ ret = errno; ++ if (ret == EPIPE) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "SSHD closed the pipe before all keys could be written\n"); ++ /* Return 0 so that openssh doesn't abort pubkey auth */ ++ ret = 0; ++ goto fini; ++ } ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "sss_atomic_write_s() failed (%d): %s\n", ++ ret, strerror(ret)); ++ goto fini; ++ } + } + + ret = EXIT_SUCCESS; +-- +2.17.1 + diff --git a/SOURCES/0012-sudo-always-use-srv_opts-from-id-context.patch b/SOURCES/0012-sudo-always-use-srv_opts-from-id-context.patch deleted file mode 100644 index 8c782f9..0000000 --- a/SOURCES/0012-sudo-always-use-srv_opts-from-id-context.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 7738a74e6878536e155d9d589e7ec727c135f5a0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Thu, 19 Oct 2017 10:39:21 +0200 -Subject: [PATCH 12/21] sudo: always use srv_opts from id context - -Prior this patch, we remember id_ctx->srv_opts in sudo request to switch -the latest usn values. This works fine most of the time but it may cause -a crash. - -If we have two concurrent sudo refresh and one of these fails, it causes -failover to try the next server and possibly replacing the old srv_opts -with new one and it causes an access after free in the other refresh. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3562 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 2ee201dcf6bbe52abbbed3c2fc4c35ca2e0c8a43) ---- - src/providers/ldap/sdap_async_sudo.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c -index 3c69837fda313b2645c3a8497252670312f600ea..88a387422d5c9ae86cea583bb38dadf90cba37f3 100644 ---- a/src/providers/ldap/sdap_async_sudo.c -+++ b/src/providers/ldap/sdap_async_sudo.c -@@ -279,7 +279,6 @@ done: - struct sdap_sudo_refresh_state { - struct sdap_sudo_ctx *sudo_ctx; - struct tevent_context *ev; -- struct sdap_server_opts *srv_opts; - struct sdap_options *opts; - struct sdap_id_op *sdap_op; - struct sysdb_ctx *sysdb; -@@ -405,9 +404,6 @@ static void sdap_sudo_refresh_connect_done(struct tevent_req *subreq) - - DEBUG(SSSDBG_TRACE_FUNC, "SUDO LDAP connection successful\n"); - -- /* Obtain srv_opts here in case of first connection. */ -- state->srv_opts = state->sudo_ctx->id_ctx->srv_opts; -- - /* Renew host information if needed. */ - if (state->sudo_ctx->run_hostinfo) { - subreq = sdap_sudo_get_hostinfo_send(state, state->opts, -@@ -586,7 +582,6 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq) - goto done; - } - -- - /* start transaction */ - ret = sysdb_transaction_start(state->sysdb); - if (ret != EOK) { -@@ -621,7 +616,7 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq) - /* remember new usn */ - ret = sysdb_get_highest_usn(state, rules, rules_count, &usn); - if (ret == EOK) { -- sdap_sudo_set_usn(state->srv_opts, usn); -+ sdap_sudo_set_usn(state->sudo_ctx->id_ctx->srv_opts, usn); - } else { - DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get highest USN [%d]: %s\n", - ret, sss_strerror(ret)); --- -2.13.5 - diff --git a/SOURCES/0013-AD-Remember-last-site-discovered.patch b/SOURCES/0013-AD-Remember-last-site-discovered.patch deleted file mode 100644 index f1ad8c2..0000000 --- a/SOURCES/0013-AD-Remember-last-site-discovered.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 020d7f12f7c57e3a5c8f844de2b2d0cad020e662 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Wed, 18 Oct 2017 15:20:34 +0200 -Subject: [PATCH 13/21] AD: Remember last site discovered - -To discover Active Directory site for a client we must first contact any -directory controller for an LDAP ping. This is done by searching -domain-wide DNS tree which may however contain servers that are not -reachable from current site and than we face long timeouts or failure. - -This patch makes sssd remember the last successfuly discovered site -and use this for DNS search to lookup a site and forest again similar -to what we do when ad_site option is set. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3265 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit f54d202db528207d7794870aabef0656b20369f1) ---- - src/providers/ad/ad_srv.c | 44 +++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 43 insertions(+), 1 deletion(-) - -diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c -index ff01ee95c4d2c6875a989394489f1a0495cc3003..be1ba0f237add894566ae713ce5e29fd202d414c 100644 ---- a/src/providers/ad/ad_srv.c -+++ b/src/providers/ad/ad_srv.c -@@ -481,6 +481,7 @@ struct ad_srv_plugin_ctx { - const char *hostname; - const char *ad_domain; - const char *ad_site_override; -+ const char *current_site; - }; - - struct ad_srv_plugin_ctx * -@@ -518,6 +519,11 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx, - if (ctx->ad_site_override == NULL) { - goto fail; - } -+ -+ ctx->current_site = talloc_strdup(ctx, ad_site_override); -+ if (ctx->current_site == NULL) { -+ goto fail; -+ } - } - - return ctx; -@@ -527,6 +533,32 @@ fail: - return NULL; - } - -+static errno_t -+ad_srv_plugin_ctx_switch_site(struct ad_srv_plugin_ctx *ctx, -+ const char *new_site) -+{ -+ const char *site; -+ errno_t ret; -+ -+ if (new_site == NULL) { -+ return EOK; -+ } -+ -+ if (ctx->current_site != NULL && strcmp(ctx->current_site, new_site) == 0) { -+ return EOK; -+ } -+ -+ site = talloc_strdup(ctx, new_site); -+ if (site == NULL) { -+ return ENOMEM; -+ } -+ -+ talloc_zfree(ctx->current_site); -+ ctx->current_site = site; -+ -+ return EOK; -+} -+ - struct ad_srv_plugin_state { - struct tevent_context *ev; - struct ad_srv_plugin_ctx *ctx; -@@ -613,7 +645,7 @@ struct tevent_req *ad_srv_plugin_send(TALLOC_CTX *mem_ctx, - - subreq = ad_get_dc_servers_send(state, ev, ctx->be_res->resolv, - state->discovery_domain, -- state->ctx->ad_site_override); -+ state->ctx->current_site); - if (subreq == NULL) { - ret = ENOMEM; - goto immediately; -@@ -709,6 +741,16 @@ static void ad_srv_plugin_site_done(struct tevent_req *subreq) - backup_domain = NULL; - - if (ret == EOK) { -+ /* Remember current site so it can be used during next lookup so -+ * we can contact directory controllers within a known reachable -+ * site first. */ -+ ret = ad_srv_plugin_ctx_switch_site(state->ctx, state->site); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set site [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ goto done; -+ } -+ - if (strcmp(state->service, "gc") == 0) { - if (state->forest != NULL) { - if (state->site != NULL) { --- -2.13.5 - diff --git a/SOURCES/0013-TESTS-Add-a-helper-binary-that-can-trigger-the-SIGPI.patch b/SOURCES/0013-TESTS-Add-a-helper-binary-that-can-trigger-the-SIGPI.patch new file mode 100644 index 0000000..a9da871 --- /dev/null +++ b/SOURCES/0013-TESTS-Add-a-helper-binary-that-can-trigger-the-SIGPI.patch @@ -0,0 +1,213 @@ +From ef28a3bdc50d0da6fab86b0d27e4c548ac61a749 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 28 May 2018 21:49:41 +0200 +Subject: [PATCH] TESTS: Add a helper binary that can trigger the SIGPIPE to + authorizedkeys +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Adds a test tool that simulates the behaviour of OpenSSH in the sense +that it starts to read the output from the sss_ssh_authorizedkeys tool, +but then closes the pipe before reading the whole output. + +Related: +https://pagure.io/SSSD/sssd/issue/3747 + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit 909c16edb26a3c48b10a49e7919a35d13d31c52e) +--- + Makefile.am | 15 +++- + src/tests/test_ssh_client.c | 133 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 147 insertions(+), 1 deletion(-) + create mode 100644 src/tests/test_ssh_client.c + +diff --git a/Makefile.am b/Makefile.am +index 9055130ed74057987795285c243ff47584cf8316..99974cf0e94e1ec6086a53585042653ec5966c2c 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -331,6 +331,7 @@ endif # HAVE_CMOCKA + check_PROGRAMS = \ + stress-tests \ + krb5-child-test \ ++ test_ssh_client \ + $(non_interactive_cmocka_based_tests) \ + $(non_interactive_check_based_tests) + +@@ -2291,6 +2292,18 @@ krb5_child_test_LDADD = \ + $(SSSD_INTERNAL_LTLIBS) \ + libsss_test_common.la + ++test_ssh_client_SOURCES = \ ++ src/tests/test_ssh_client.c \ ++ $(NULL) ++test_ssh_client_CFLAGS = \ ++ $(AM_CFLAGS) \ ++ -DSSH_CLIENT_DIR=\"$(abs_top_builddir)\" \ ++ $(NULL) ++test_ssh_client_LDADD = \ ++ $(SSSD_INTERNAL_LTLIBS) \ ++ $(SSSD_LIBS) \ ++ $(NULL) ++ + if BUILD_DBUS_TESTS + + sbus_tests_SOURCES = \ +@@ -3446,7 +3459,6 @@ test_iobuf_LDADD = \ + $(SSSD_LIBS) \ + $(NULL) + +- + EXTRA_simple_access_tests_DEPENDENCIES = \ + $(ldblib_LTLIBRARIES) + simple_access_tests_SOURCES = \ +@@ -3655,6 +3667,7 @@ intgcheck-prepare: + $(INTGCHECK_CONFIGURE_FLAGS) \ + CFLAGS="-O2 -g $$CFLAGS -DKCM_PEER_UID=$$(id -u)"; \ + $(MAKE) $(AM_MAKEFLAGS) ; \ ++ $(MAKE) $(AM_MAKEFLAGS) test_ssh_client; \ + : Force single-thread install to workaround concurrency issues; \ + $(MAKE) $(AM_MAKEFLAGS) -j1 install; \ + : Remove .la files from LDB module directory to avoid loader warnings; \ +diff --git a/src/tests/test_ssh_client.c b/src/tests/test_ssh_client.c +new file mode 100644 +index 0000000000000000000000000000000000000000..8f963941f3249561178436d6f6dfc376780a4cda +--- /dev/null ++++ b/src/tests/test_ssh_client.c +@@ -0,0 +1,133 @@ ++/* ++ 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 ++#include "util/util.h" ++ ++#ifdef SSH_CLIENT_DIR ++#define SSH_AK_CLIENT_PATH SSH_CLIENT_DIR"/sss_ssh_authorizedkeys" ++#else ++#error "The path to the ssh authorizedkeys helper is not defined" ++#endif /* SSH_CLIENT_DIR */ ++ ++int main(int argc, const char *argv[]) ++{ ++ poptContext pc; ++ int opt; ++ struct poptOption long_options[] = { ++ POPT_AUTOHELP ++ SSSD_DEBUG_OPTS ++ POPT_TABLEEND ++ }; ++ struct stat sb; ++ int ret; ++ int status; ++ int p[2]; ++ pid_t pid; ++ const char *pc_user = NULL; ++ char *av[3]; ++ char buf[5]; /* Ridiculously small buffer by design */ ++ ++ /* 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); ++ poptSetOtherOptionHelp(pc, "USER"); ++ 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 3; ++ } ++ } ++ ++ pc_user = poptGetArg(pc); ++ if (pc_user == NULL) { ++ fprintf(stderr, "No user specified\n"); ++ return 3; ++ } ++ ++ poptFreeContext(pc); ++ ++ DEBUG_CLI_INIT(debug_level); ++ ++ ret = stat(SSH_AK_CLIENT_PATH, &sb); ++ if (ret != 0) { ++ ret = errno; ++ DEBUG(SSSDBG_CRIT_FAILURE, ++ "Could not stat %s [%d]: %s\n", ++ SSH_AK_CLIENT_PATH, ret, strerror(ret)); ++ return 3; ++ } ++ ++ ret = pipe(p); ++ if (ret != 0) { ++ perror("pipe"); ++ return 3; ++ } ++ ++ switch (pid = fork()) { ++ case -1: ++ ret = errno; ++ close(p[0]); ++ close(p[1]); ++ DEBUG(SSSDBG_CRIT_FAILURE, "fork failed: %d\n", ret); ++ return 3; ++ case 0: ++ /* child */ ++ av[0] = discard_const(SSH_AK_CLIENT_PATH); ++ av[1] = discard_const(pc_user); ++ av[2] = NULL; ++ ++ close(p[0]); ++ ret = dup2(p[1], STDOUT_FILENO); ++ if (ret == -1) { ++ perror("dup2"); ++ return 3; ++ } ++ ++ execv(av[0], av); ++ return 3; ++ default: ++ /* parent */ ++ break; ++ } ++ ++ close(p[1]); ++ read(p[0], buf, sizeof(buf)); ++ close(p[0]); ++ ++ pid = waitpid(pid, &status, 0); ++ if (pid == -1) { ++ perror("waitpid"); ++ return 3; ++ } ++ ++ if (WIFEXITED(status)) { ++ printf("sss_ssh_authorizedkeys exited with return code %d\n", WEXITSTATUS(status)); ++ return 0; ++ } else if (WIFSIGNALED(status)) { ++ printf("sss_ssh_authorizedkeys exited with signal %d\n", WTERMSIG(status)); ++ return 1; ++ } ++ ++ printf("sss_ssh_authorizedkeys exited for another reason\n"); ++ return 2; ++} +-- +2.17.1 + diff --git a/SOURCES/0014-TESTS-Add-a-regression-test-for-SIGHUP-handling-in-s.patch b/SOURCES/0014-TESTS-Add-a-regression-test-for-SIGHUP-handling-in-s.patch new file mode 100644 index 0000000..ccb7133 --- /dev/null +++ b/SOURCES/0014-TESTS-Add-a-regression-test-for-SIGHUP-handling-in-s.patch @@ -0,0 +1,94 @@ +From 0adf4f50e9773afda2dc422b04163f19d946c150 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 19 Jun 2018 11:39:02 +0200 +Subject: [PATCH] TESTS: Add a regression test for SIGHUP handling in + sss_ssh_authorizedkeys +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A regression test for: +https://pagure.io/SSSD/sssd/issue/3747 + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit 4cc3c1a1b1070c12bcc4351880d8207e47b37496) +--- + src/tests/intg/test_ssh_pubkey.py | 58 +++++++++++++++++++++++++++++++ + 1 file changed, 58 insertions(+) + +diff --git a/src/tests/intg/test_ssh_pubkey.py b/src/tests/intg/test_ssh_pubkey.py +index fbf55566e341373873057ec4e3af1d7f83202aa7..8fb41c62d87ec210c9aad8582023fe1cb00f2b4e 100644 +--- a/src/tests/intg/test_ssh_pubkey.py ++++ b/src/tests/intg/test_ssh_pubkey.py +@@ -24,6 +24,8 @@ import time + import ldap + import ldap.modlist + import pytest ++import string ++import random + + import config + import ds_openldap +@@ -230,3 +232,59 @@ def test_ssh_pubkey_retrieve(add_user_with_ssh_key): + + sshpubkey = get_call_output(["sss_ssh_authorizedkeys", "user2"]) + assert len(sshpubkey) == 0 ++ ++ ++@pytest.fixture() ++def sighup_client(request): ++ test_ssh_cli_path = os.path.join(config.ABS_BUILDDIR, ++ "..", "..", "..", "test_ssh_client") ++ assert os.access(test_ssh_cli_path, os.X_OK) ++ return test_ssh_cli_path ++ ++ ++@pytest.fixture ++def add_user_with_many_keys(request, ldap_conn): ++ # Generate a large list of unique ssh pubkeys ++ pubkey_list = [] ++ while len(pubkey_list) < 50: ++ new_pubkey = list(USER1_PUBKEY1) ++ new_pubkey[10] = random.choice(string.ascii_uppercase) ++ new_pubkey[11] = random.choice(string.ascii_uppercase) ++ new_pubkey[12] = random.choice(string.ascii_uppercase) ++ str_new_pubkey = ''.join(c for c in new_pubkey) ++ if str_new_pubkey in pubkey_list: ++ continue ++ pubkey_list.append(str_new_pubkey) ++ ++ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ++ ent_list.add_user("user1", 1001, 2001, sshPubKey=pubkey_list) ++ create_ldap_fixture(request, ldap_conn, ent_list) ++ ++ conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) ++ create_conf_fixture(request, conf) ++ create_sssd_fixture(request) ++ return None ++ ++ ++def test_ssh_sighup(add_user_with_many_keys, sighup_client): ++ """ ++ A regression test for https://pagure.io/SSSD/sssd/issue/3747 ++ ++ OpenSSH can close its end of the pipe towards sss_ssh_authorizedkeys ++ before all of the output is read. In that case, older versions ++ of sss_ssh_authorizedkeys were receiving a SIGPIPE ++ """ ++ cli_path = sighup_client ++ ++ # python actually does the sensible, but unexpected (for a C programmer) ++ # thing and handles SIGPIPE. In order to reproduce the bug, we need ++ # to unset the SIGPIPE handler ++ signal.signal(signal.SIGPIPE, signal.SIG_DFL) ++ ++ process = subprocess.Popen([cli_path, "user1"], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE) ++ _, _ = process.communicate() ++ # If the test tool detects that sss_ssh_authorizedkeys was killed with a ++ # signal, it would have returned 1 ++ assert process.returncode == 0 +-- +2.17.1 + diff --git a/SOURCES/0014-sysdb-add-functions-to-get-set-client-site.patch b/SOURCES/0014-sysdb-add-functions-to-get-set-client-site.patch deleted file mode 100644 index 7fc6ff1..0000000 --- a/SOURCES/0014-sysdb-add-functions-to-get-set-client-site.patch +++ /dev/null @@ -1,206 +0,0 @@ -From fafc90b8c225fd77e30e94d985c72f5f2980e59e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Tue, 24 Oct 2017 12:09:39 +0200 -Subject: [PATCH 14/21] sysdb: add functions to get/set client site - -Reviewed-by: Jakub Hrozek -(cherry picked from commit e16539779668dacff868999bd59dbf33e3eab872) ---- - src/db/sysdb.h | 10 +++ - src/db/sysdb_subdomains.c | 108 +++++++++++++++++++++++++++++++ - src/tests/cmocka/test_sysdb_subdomains.c | 28 ++++++++ - 3 files changed, 146 insertions(+) - -diff --git a/src/db/sysdb.h b/src/db/sysdb.h -index fbbe321072385bd43353ef2f7d0e30667887d128..4192f9085d941814eccd2ac60ce8fb6d4e1bfa67 100644 ---- a/src/db/sysdb.h -+++ b/src/db/sysdb.h -@@ -154,6 +154,7 @@ - #define SYSDB_SUBDOMAIN_FOREST "memberOfForest" - #define SYSDB_SUBDOMAIN_TRUST_DIRECTION "trustDirection" - #define SYSDB_UPN_SUFFIXES "upnSuffixes" -+#define SYSDB_SITE "site" - - #define SYSDB_BASE_ID "baseID" - #define SYSDB_ID_RANGE_SIZE "idRangeSize" -@@ -509,6 +510,15 @@ errno_t sysdb_domain_update_domain_resolution_order( - const char *domain_name, - const char *domain_resolution_order); - -+errno_t -+sysdb_get_site(TALLOC_CTX *mem_ctx, -+ struct sss_domain_info *dom, -+ const char **_site); -+ -+errno_t -+sysdb_set_site(struct sss_domain_info *dom, -+ const char *site); -+ - errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb, - const char *name, const char *realm, - const char *flat_name, const char *domain_id, -diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c -index 2789cc4949fb7be9ad272d7613ed18a64fa8a20a..cb5de1afe3e8c9692789c5d2679eb3a4e6e1cdb2 100644 ---- a/src/db/sysdb_subdomains.c -+++ b/src/db/sysdb_subdomains.c -@@ -1284,3 +1284,111 @@ done: - talloc_free(tmp_ctx); - return ret; - } -+ -+errno_t -+sysdb_get_site(TALLOC_CTX *mem_ctx, -+ struct sss_domain_info *dom, -+ const char **_site) -+{ -+ TALLOC_CTX *tmp_ctx; -+ struct ldb_res *res; -+ struct ldb_dn *dn; -+ const char *attrs[] = { SYSDB_SITE, NULL }; -+ errno_t ret; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ return ENOMEM; -+ } -+ -+ dn = ldb_dn_new_fmt(tmp_ctx, dom->sysdb->ldb, SYSDB_DOM_BASE, dom->name); -+ if (dn == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = ldb_search(dom->sysdb->ldb, tmp_ctx, &res, dn, LDB_SCOPE_BASE, -+ attrs, NULL); -+ if (ret != LDB_SUCCESS) { -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ -+ if (res->count == 0) { -+ *_site = NULL; -+ ret = EOK; -+ goto done; -+ } else if (res->count != 1) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Got more than one reply for base search!\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ *_site = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_SITE, NULL); -+ talloc_steal(mem_ctx, *_site); -+ -+ ret = EOK; -+ -+done: -+ talloc_free(tmp_ctx); -+ return ret; -+} -+ -+errno_t -+sysdb_set_site(struct sss_domain_info *dom, -+ const char *site) -+{ -+ TALLOC_CTX *tmp_ctx; -+ struct ldb_message *msg; -+ struct ldb_dn *dn; -+ errno_t ret; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ return ENOMEM; -+ } -+ -+ dn = ldb_dn_new_fmt(tmp_ctx, dom->sysdb->ldb, SYSDB_DOM_BASE, dom->name); -+ if (dn == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ msg = ldb_msg_new(tmp_ctx); -+ if (msg == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ msg->dn = dn; -+ -+ ret = ldb_msg_add_empty(msg, SYSDB_SITE, LDB_FLAG_MOD_REPLACE, NULL); -+ if (ret != LDB_SUCCESS) { -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ -+ if (site != NULL) { -+ ret = ldb_msg_add_string(msg, SYSDB_SITE, site); -+ if (ret != LDB_SUCCESS) { -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ } -+ -+ ret = ldb_modify(dom->sysdb->ldb, msg); -+ if (ret != LDB_SUCCESS) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "ldb_modify()_failed: [%s][%d][%s]\n", -+ ldb_strerror(ret), ret, ldb_errstring(dom->sysdb->ldb)); -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ -+ ret = EOK; -+ -+done: -+ talloc_free(tmp_ctx); -+ return ret; -+} -diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c -index 84bcdc17b39dbc8822097c2006f157a09ea5e466..f8e3e1d915dba0f3a79adbf5af733980bf23a265 100644 ---- a/src/tests/cmocka/test_sysdb_subdomains.c -+++ b/src/tests/cmocka/test_sysdb_subdomains.c -@@ -513,6 +513,31 @@ static void test_sysdb_link_ad_multidom(void **state) - - } - -+static void test_sysdb_set_and_get_site(void **state) -+{ -+ TALLOC_CTX *tmp_ctx; -+ struct subdom_test_ctx *test_ctx = -+ talloc_get_type(*state, struct subdom_test_ctx); -+ const char *site; -+ errno_t ret; -+ -+ tmp_ctx = talloc_new(NULL); -+ assert_non_null(test_ctx); -+ -+ ret = sysdb_get_site(test_ctx, test_ctx->tctx->dom, &site); -+ assert_int_equal(ret, EOK); -+ assert_null(site); -+ -+ ret = sysdb_set_site(test_ctx->tctx->dom, "TestSite"); -+ assert_int_equal(ret, EOK); -+ -+ ret = sysdb_get_site(tmp_ctx, test_ctx->tctx->dom, &site); -+ assert_int_equal(ret, EOK); -+ assert_string_equal(site, "TestSite"); -+ -+ talloc_free(tmp_ctx); -+} -+ - int main(int argc, const char *argv[]) - { - int rv; -@@ -546,6 +571,9 @@ int main(int argc, const char *argv[]) - cmocka_unit_test_setup_teardown(test_sysdb_link_ad_multidom, - test_sysdb_subdom_setup, - test_sysdb_subdom_teardown), -+ cmocka_unit_test_setup_teardown(test_sysdb_set_and_get_site, -+ test_sysdb_subdom_setup, -+ test_sysdb_subdom_teardown), - }; - - /* Set debug level to invalid value so we can deside if -d 0 was used. */ --- -2.13.5 - diff --git a/SOURCES/0015-AD-Remember-last-site-discovered-in-sysdb.patch b/SOURCES/0015-AD-Remember-last-site-discovered-in-sysdb.patch deleted file mode 100644 index 9c14628..0000000 --- a/SOURCES/0015-AD-Remember-last-site-discovered-in-sysdb.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 1be48c91f3d80b51dc2361217f5c840656e0b088 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Wed, 1 Nov 2017 14:57:17 +0100 -Subject: [PATCH 15/21] AD: Remember last site discovered in sysdb - -This can speed up sssd startup. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3265 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit fb0431b13a9fcd8ac31e622503acbd10d2b73ac9) ---- - src/db/sysdb_subdomains.c | 2 +- - src/providers/ad/ad_init.c | 2 +- - src/providers/ad/ad_srv.c | 21 +++++++++++++++++++++ - src/providers/ad/ad_srv.h | 1 + - src/providers/ad/ad_subdomains.c | 2 +- - src/providers/ipa/ipa_subdomains_server.c | 2 +- - 6 files changed, 26 insertions(+), 4 deletions(-) - -diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c -index cb5de1afe3e8c9692789c5d2679eb3a4e6e1cdb2..353561765904efe4bd698c38949a1b290ecf0b80 100644 ---- a/src/db/sysdb_subdomains.c -+++ b/src/db/sysdb_subdomains.c -@@ -1291,7 +1291,7 @@ sysdb_get_site(TALLOC_CTX *mem_ctx, - const char **_site) - { - TALLOC_CTX *tmp_ctx; -- struct ldb_res *res; -+ struct ldb_result *res; - struct ldb_dn *dn; - const char *attrs[] = { SYSDB_SITE, NULL }; - errno_t ret; -diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c -index 131e960d4c623398506f834742400df9c786b86b..e62025d4acd24844a5c7082d00c597516f35de16 100644 ---- a/src/providers/ad/ad_init.c -+++ b/src/providers/ad/ad_init.c -@@ -199,7 +199,7 @@ static errno_t ad_init_srv_plugin(struct be_ctx *be_ctx, - return EOK; - } - -- srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res, -+ srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx, be_ctx->be_res, - default_host_dbs, ad_options->id, - hostname, ad_domain, - ad_site_override); -diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c -index be1ba0f237add894566ae713ce5e29fd202d414c..4fa1668605e131b2e31802b1401f49fc6e00a23b 100644 ---- a/src/providers/ad/ad_srv.c -+++ b/src/providers/ad/ad_srv.c -@@ -34,6 +34,7 @@ - #include "providers/fail_over_srv.h" - #include "providers/ldap/sdap.h" - #include "providers/ldap/sdap_async.h" -+#include "db/sysdb.h" - - #define AD_SITE_DOMAIN_FMT "%s._sites.%s" - -@@ -475,6 +476,7 @@ int ad_get_client_site_recv(TALLOC_CTX *mem_ctx, - } - - struct ad_srv_plugin_ctx { -+ struct be_ctx *be_ctx; - struct be_resolv_ctx *be_res; - enum host_database *host_dbs; - struct sdap_options *opts; -@@ -486,6 +488,7 @@ struct ad_srv_plugin_ctx { - - struct ad_srv_plugin_ctx * - ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx, -+ struct be_ctx *be_ctx, - struct be_resolv_ctx *be_res, - enum host_database *host_dbs, - struct sdap_options *opts, -@@ -494,12 +497,14 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx, - const char *ad_site_override) - { - struct ad_srv_plugin_ctx *ctx = NULL; -+ errno_t ret; - - ctx = talloc_zero(mem_ctx, struct ad_srv_plugin_ctx); - if (ctx == NULL) { - return NULL; - } - -+ ctx->be_ctx = be_ctx; - ctx->be_res = be_res; - ctx->host_dbs = host_dbs; - ctx->opts = opts; -@@ -524,6 +529,15 @@ ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx, - if (ctx->current_site == NULL) { - goto fail; - } -+ } else { -+ ret = sysdb_get_site(ctx, be_ctx->domain, &ctx->current_site); -+ if (ret != EOK) { -+ /* Not fatal. */ -+ DEBUG(SSSDBG_MINOR_FAILURE, -+ "Unable to get current site from cache [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ ctx->current_site = NULL; -+ } - } - - return ctx; -@@ -556,6 +570,13 @@ ad_srv_plugin_ctx_switch_site(struct ad_srv_plugin_ctx *ctx, - talloc_zfree(ctx->current_site); - ctx->current_site = site; - -+ ret = sysdb_set_site(ctx->be_ctx->domain, ctx->current_site); -+ if (ret != EOK) { -+ /* Not fatal. */ -+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to store site information " -+ "[%d]: %s\n", ret, sss_strerror(ret)); -+ } -+ - return EOK; - } - -diff --git a/src/providers/ad/ad_srv.h b/src/providers/ad/ad_srv.h -index ae5efe44755fa09f74064014cce749e35b1831da..fddef686762e57bb95d648247131d39a797aa516 100644 ---- a/src/providers/ad/ad_srv.h -+++ b/src/providers/ad/ad_srv.h -@@ -25,6 +25,7 @@ struct ad_srv_plugin_ctx; - - struct ad_srv_plugin_ctx * - ad_srv_plugin_ctx_init(TALLOC_CTX *mem_ctx, -+ struct be_ctx *be_ctx, - struct be_resolv_ctx *be_res, - enum host_database *host_dbs, - struct sdap_options *opts, -diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c -index 280aa54c23bf61e60d23ea91bd44a39f9f43d155..3fb9b950f171d85817cce35ac92ad7c4974ccb68 100644 ---- a/src/providers/ad/ad_subdomains.c -+++ b/src/providers/ad/ad_subdomains.c -@@ -245,7 +245,7 @@ ad_subdom_ad_ctx_new(struct be_ctx *be_ctx, - ad_options->id_ctx = ad_id_ctx; - - /* use AD plugin */ -- srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res, -+ srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx, be_ctx->be_res, - default_host_dbs, - ad_id_ctx->ad_options->id, - hostname, -diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c -index 10166d162f746fde176e6c7c2bfbe3906b1bfddc..d670a156b37608d20d49d79131138f02e4abf82b 100644 ---- a/src/providers/ipa/ipa_subdomains_server.c -+++ b/src/providers/ipa/ipa_subdomains_server.c -@@ -305,7 +305,7 @@ ipa_ad_ctx_new(struct be_ctx *be_ctx, - ad_site_override = dp_opt_get_string(ad_options->basic, AD_SITE); - - /* use AD plugin */ -- srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx->be_res, -+ srv_ctx = ad_srv_plugin_ctx_init(be_ctx, be_ctx, be_ctx->be_res, - default_host_dbs, - ad_id_ctx->ad_options->id, - id_ctx->server_mode->hostname, --- -2.13.5 - diff --git a/SOURCES/0015-Revert-LDAP-IPA-add-local-email-address-to-aliases.patch b/SOURCES/0015-Revert-LDAP-IPA-add-local-email-address-to-aliases.patch new file mode 100644 index 0000000..fb6b1da --- /dev/null +++ b/SOURCES/0015-Revert-LDAP-IPA-add-local-email-address-to-aliases.patch @@ -0,0 +1,141 @@ +From 9efaade255e59b4a2f5cff2ab78c1db61132a40a Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Thu, 21 Jun 2018 12:27:32 +0200 +Subject: [PATCH] Revert "LDAP/IPA: add local email address to aliases" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This reverts commit 9a310913d696d190db14c625080678db853a33fd. + +Storing the e-mail address as a nameAlias was a performance optimization +to avoid having to fall back to the UPN lookup, but had the disadvantage +of returning multiple results for cases where an e-mail address is the +same as a user's fully qualified name. + +Since the e-mail lookups would still work without this optimization, +just after one more lookup, let's revert the patch. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3607 + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit b0ec3875da281a9c29eda2cb19c1026510866d5b) + +DOWNSTREAM: +Resolves: rhbz#1527662 - Handle conflicting e-mail addresses more gracefully +--- + src/providers/ipa/ipa_s2n_exop.c | 49 -------------------------------- + src/providers/ldap/sdap_utils.c | 22 -------------- + 2 files changed, 71 deletions(-) + +diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c +index 9cb735526293ff5a209d732366b86fdb95dc8679..6f3974637a08b9d70e32fb6d79724be4f6e8dbde 100644 +--- a/src/providers/ipa/ipa_s2n_exop.c ++++ b/src/providers/ipa/ipa_s2n_exop.c +@@ -2118,49 +2118,6 @@ done: + return ret; + } + +-static errno_t add_emails_to_aliases(struct sysdb_attrs *attrs, +- struct sss_domain_info *dom) +-{ +- int ret; +- const char **emails; +- size_t c; +- TALLOC_CTX *tmp_ctx; +- +- tmp_ctx = talloc_new(NULL); +- if (tmp_ctx == NULL) { +- DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); +- return ENOMEM; +- } +- +- ret = sysdb_attrs_get_string_array(attrs, SYSDB_USER_EMAIL, tmp_ctx, +- &emails); +- if (ret == EOK) { +- for (c = 0; emails[c] != NULL; c++) { +- if (is_email_from_domain(emails[c], dom)) { +- ret = sysdb_attrs_add_lc_name_alias_safe(attrs, emails[c]); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, +- "Failed to add lower-cased version of email [%s] " +- "into the alias list\n", emails[c]); +- goto done; +- } +- } +- } +- } else if (ret == ENOENT) { +- DEBUG(SSSDBG_TRACE_ALL, "No email addresses available.\n"); +- } else { +- DEBUG(SSSDBG_OP_FAILURE, +- "sysdb_attrs_get_string_array failed, skipping ...\n"); +- } +- +- ret = EOK; +- +-done: +- talloc_free(tmp_ctx); +- +- return ret; +-} +- + static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, + struct req_input *req_input, + struct resp_attrs *attrs, +@@ -2314,12 +2271,6 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, + goto done; + } + +- ret = add_emails_to_aliases(attrs->sysdb_attrs, dom); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, +- "add_emails_to_aliases failed, skipping ...\n"); +- } +- + if (upn == NULL) { + /* We also have to store a fake UPN here, because otherwise the + * krb5 child later won't be able to properly construct one as +diff --git a/src/providers/ldap/sdap_utils.c b/src/providers/ldap/sdap_utils.c +index 0ac3ab2e416d887d00480b5123859c611f514274..6d543101f06ce3cd3925a675af6cabdacb8ebcaa 100644 +--- a/src/providers/ldap/sdap_utils.c ++++ b/src/providers/ldap/sdap_utils.c +@@ -87,7 +87,6 @@ sdap_save_all_names(const char *name, + int i; + bool lowercase = !dom->case_sensitive; + bool store_as_fqdn; +- const char **emails; + + switch (entry_type) { + case SYSDB_MEMBER_USER: +@@ -144,27 +143,6 @@ sdap_save_all_names(const char *name, + + } + +- ret = sysdb_attrs_get_string_array(ldap_attrs, SYSDB_USER_EMAIL, tmp_ctx, +- &emails); +- if (ret == EOK) { +- for (i = 0; emails[i] != NULL; i++) { +- if (is_email_from_domain(emails[i], dom)) { +- ret = sysdb_attrs_add_lc_name_alias_safe(attrs, emails[i]); +- if (ret) { +- DEBUG(SSSDBG_OP_FAILURE, +- "Failed to add lower-cased version of email [%s] " +- "into the alias list\n", emails[i]); +- goto done; +- } +- } +- } +- } else if (ret == ENOENT) { +- DEBUG(SSSDBG_TRACE_ALL, "No email addresses available.\n"); +- } else { +- DEBUG(SSSDBG_OP_FAILURE, +- "sysdb_attrs_get_string_array failed, skipping ...\n"); +- } +- + ret = EOK; + done: + talloc_free(tmp_ctx); +-- +2.17.1 + diff --git a/SOURCES/0016-UTIL-Add-wrapper-function-to-configure-logger.patch b/SOURCES/0016-UTIL-Add-wrapper-function-to-configure-logger.patch deleted file mode 100644 index a4dea5f..0000000 --- a/SOURCES/0016-UTIL-Add-wrapper-function-to-configure-logger.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 34fa82bc07c4da14606d7a8a9b68a872fe210a9f Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Mon, 23 Oct 2017 14:58:14 +0200 -Subject: [PATCH 16/21] UTIL: Add wrapper function to configure logger -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Let's use one enum for logger type instead of many integers (debug_to_file, -debug_to_stderr plus some weird combination for journald). -Old variable were also transformed to enum for backward compatibility - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 09e3f0af96cecb94be69084c025f0355b3111993) ---- - src/util/debug.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/util/debug.h | 18 ++++++++++++++++++ - 2 files changed, 72 insertions(+) - -diff --git a/src/util/debug.c b/src/util/debug.c -index ca4fa4c6f5b150700a0a136d8a7ca9df30c29d73..4e469447e5ab8aa89cd57bcd6d00269875a12bc6 100644 ---- a/src/util/debug.c -+++ b/src/util/debug.c -@@ -43,9 +43,63 @@ int debug_timestamps = SSSDBG_TIMESTAMP_UNRESOLVED; - int debug_microseconds = SSSDBG_MICROSECONDS_UNRESOLVED; - int debug_to_file = 0; - int debug_to_stderr = 0; -+enum sss_logger_t sss_logger; - const char *debug_log_file = "sssd"; - FILE *debug_file = NULL; - -+const char *sss_logger_str[] = { -+ [STDERR_LOGGER] = "stderr", -+ [FILES_LOGGER] = "files", -+#ifdef WITH_JOURNALD -+ [JOURNALD_LOGGER] = "journald", -+#endif -+ NULL, -+}; -+ -+#ifdef WITH_JOURNALD -+#define JOURNALD_STR " journald," -+#else -+#define JOURNALD_STR "" -+#endif -+ -+void sss_set_logger(const char *logger) -+{ -+ /* use old flags */ -+ if (logger == NULL) { -+ if (debug_to_stderr != 0) { -+ sss_logger = STDERR_LOGGER; -+ } -+ /* It is never described what should be used in case of -+ * debug_to_stderr == 1 && debug_to_file == 1. Because neither -+ * of binaries provide both command line arguments. -+ * Let files have higher priority. -+ */ -+ if (debug_to_file != 0) { -+ sss_logger = FILES_LOGGER; -+ } -+#ifdef WITH_JOURNALD -+ if (debug_to_file == 0 && debug_to_stderr == 0) { -+ sss_logger = JOURNALD_LOGGER; -+ } -+#endif -+ } else { -+ if (strcmp(logger, "stderr") == 0) { -+ sss_logger = STDERR_LOGGER; -+ } else if (strcmp(logger, "files") == 0) { -+ sss_logger = FILES_LOGGER; -+#ifdef WITH_JOURNALD -+ } else if (strcmp(logger, "journald") == 0) { -+ sss_logger = JOURNALD_LOGGER; -+#endif -+ } else { -+ /* unexpected value */ -+ fprintf(stderr, "Unexpected logger: %s\nExpected:%s stderr, " -+ "files\n", logger, JOURNALD_STR); -+ sss_logger = STDERR_LOGGER; -+ } -+ } -+} -+ - errno_t set_debug_file_from_fd(const int fd) - { - FILE *dummy; -diff --git a/src/util/debug.h b/src/util/debug.h -index 2a1bd4ffd30817d7128805996c21105fe40982a2..4adafb7cfc03f7381c4d03071eb44edad04bee00 100644 ---- a/src/util/debug.h -+++ b/src/util/debug.h -@@ -31,13 +31,26 @@ - - #define APPEND_LINE_FEED 0x1 - -+enum sss_logger_t { -+ STDERR_LOGGER = 0, -+ FILES_LOGGER, -+#ifdef WITH_JOURNALD -+ JOURNALD_LOGGER, -+#endif -+}; -+ -+extern const char *sss_logger_str[]; - extern const char *debug_prg_name; - extern int debug_level; - extern int debug_timestamps; - extern int debug_microseconds; - extern int debug_to_file; - extern int debug_to_stderr; -+extern enum sss_logger_t sss_logger; - extern const char *debug_log_file; -+ -+void sss_set_logger(const char *logger); -+ - void sss_vdebug_fn(const char *file, - long line, - const char *function, -@@ -80,6 +93,11 @@ int get_fd_from_debug_file(void); - #define SSSDBG_MICROSECONDS_UNRESOLVED -1 - #define SSSDBG_MICROSECONDS_DEFAULT 0 - -+#define SSSD_LOGGER_OPTS \ -+ {"logger", '\0', POPT_ARG_STRING, &opt_logger, 0, \ -+ _("Set logger"), "stderr|files|journald"}, -+ -+ - #define SSSD_DEBUG_OPTS \ - {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, \ - _("Debug level"), NULL}, \ --- -2.13.5 - diff --git a/SOURCES/0016-util-Remove-the-unused-function-is_email_from_domain.patch b/SOURCES/0016-util-Remove-the-unused-function-is_email_from_domain.patch new file mode 100644 index 0000000..ba26190 --- /dev/null +++ b/SOURCES/0016-util-Remove-the-unused-function-is_email_from_domain.patch @@ -0,0 +1,117 @@ +From 5651a893f7dddb13fa9edc94e96d7bc95ec13f8b Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Thu, 21 Jun 2018 12:40:44 +0200 +Subject: [PATCH] util: Remove the unused function is_email_from_domain +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This commit pretty much reverts commit +04d4c4d45f3942a813b7f772737f801f877f4e64, it's just coded manually, +because "git revert 04d4c4d45f3942a813b7f772737f801f877f4e64" +resulted in conflicts. It's easier to just remove the single +function. + +Related: +https://pagure.io/SSSD/sssd/issue/3607 + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit 58f60a0949f5d84b1fe5d15e52adfceb84053569) +--- + src/tests/cmocka/test_utils.c | 21 --------------------- + src/util/domain_info_utils.c | 27 --------------------------- + src/util/util.h | 1 - + 3 files changed, 49 deletions(-) + +diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c +index cf314abe2db4056fe92c167454a4ddc31be98a51..1a8699a2a87d57ab43c70ceebf9bc71da4def4d4 100644 +--- a/src/tests/cmocka/test_utils.c ++++ b/src/tests/cmocka/test_utils.c +@@ -1849,25 +1849,6 @@ static void test_sss_get_domain_mappings_content(void **state) + * capaths might not be as expected. */ + } + +-static void test_is_email_from_domain(void **state) +-{ +- struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, +- struct dom_list_test_ctx); +- struct sss_domain_info *d; +- +- d = find_domain_by_name(test_ctx->dom_list, "name_0.dom", false); +- assert_non_null(d); +- +- assert_false(is_email_from_domain(NULL, NULL)); +- assert_false(is_email_from_domain("hello", NULL)); +- assert_false(is_email_from_domain(NULL, d)); +- assert_false(is_email_from_domain("hello", d)); +- assert_false(is_email_from_domain("hello@hello", d)); +- +- assert_true(is_email_from_domain("hello@name_0.dom", d)); +- assert_true(is_email_from_domain("hello@NaMe_0.DoM", d)); +-} +- + int main(int argc, const char *argv[]) + { + poptContext pc; +@@ -1896,8 +1877,6 @@ int main(int argc, const char *argv[]) + setup_dom_list, teardown_dom_list), + cmocka_unit_test_setup_teardown(test_find_domain_by_name_disabled, + setup_dom_list, teardown_dom_list), +- cmocka_unit_test_setup_teardown(test_is_email_from_domain, +- setup_dom_list, teardown_dom_list), + + cmocka_unit_test_setup_teardown(test_sss_names_init, + confdb_test_setup, +diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c +index 66077092a40111967a98b0937506d9e4472f50d5..9d608ef2079cadbf3c66187e3bb8c81d2d7b4604 100644 +--- a/src/util/domain_info_utils.c ++++ b/src/util/domain_info_utils.c +@@ -889,33 +889,6 @@ bool sss_domain_is_forest_root(struct sss_domain_info *dom) + return (dom->forest_root == dom); + } + +-bool is_email_from_domain(const char *email, struct sss_domain_info *dom) +-{ +- const char *p; +- +- if (email == NULL || dom == NULL) { +- return false; +- } +- +- p = strchr(email, '@'); +- if (p == NULL) { +- DEBUG(SSSDBG_TRACE_ALL, +- "Input [%s] does not look like an email address.\n", email); +- return false; +- } +- +- if (strcasecmp(p+1, dom->name) == 0) { +- DEBUG(SSSDBG_TRACE_ALL, "Email [%s] is from domain [%s].\n", email, +- dom->name); +- return true; +- } +- +- DEBUG(SSSDBG_TRACE_ALL, "Email [%s] is not from domain [%s].\n", email, +- dom->name); +- +- return false; +-} +- + char *subdomain_create_conf_path(TALLOC_CTX *mem_ctx, + struct sss_domain_info *subdomain) + { +diff --git a/src/util/util.h b/src/util/util.h +index 4657ab0c691e3e0442f340b94ae149e9d6602bb5..2785ac2e285cfb4dd6a309fe5d73dd755e07b8ad 100644 +--- a/src/util/util.h ++++ b/src/util/util.h +@@ -539,7 +539,6 @@ struct sss_domain_info *find_domain_by_sid(struct sss_domain_info *domain, + enum sss_domain_state sss_domain_get_state(struct sss_domain_info *dom); + void sss_domain_set_state(struct sss_domain_info *dom, + enum sss_domain_state state); +-bool is_email_from_domain(const char *email, struct sss_domain_info *dom); + bool sss_domain_is_forest_root(struct sss_domain_info *dom); + const char *sss_domain_type_str(struct sss_domain_info *dom); + +-- +2.17.1 + diff --git a/SOURCES/0017-Add-parameter-logger-to-daemons.patch b/SOURCES/0017-Add-parameter-logger-to-daemons.patch deleted file mode 100644 index 1a547c3..0000000 --- a/SOURCES/0017-Add-parameter-logger-to-daemons.patch +++ /dev/null @@ -1,830 +0,0 @@ -From de26ea6f603e87ef306f08fa1b458b8a180bdf2d Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Mon, 23 Oct 2017 15:18:47 +0200 -Subject: [PATCH 17/21] Add parameter --logger to daemons -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Different binary handled information about logging differently - e,g, --debug-to-files --debug-to-stderr -And logging to journald was a special case of previous options -(!debug_file && !debug_to_stderr). It was also tied to the monitor option -"--daemon" and therefore loggind to stderr was used in interactive mode -+ systemd Type=notify. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3433 - -Reviewed-by: Justin Stephenson -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit cb75b275d15beedd1fdecc1f8ced657fba282218) ---- - src/man/sssd.8.xml | 31 +++++++++++++++++++++++++ - src/monitor/monitor.c | 48 ++++++++++++--------------------------- - src/p11_child/p11_child_nss.c | 3 +++ - src/providers/ad/ad_gpo_child.c | 4 ++++ - src/providers/data_provider_be.c | 4 ++++ - src/providers/ipa/selinux_child.c | 4 ++++ - src/providers/krb5/krb5_child.c | 4 ++++ - src/providers/ldap/ldap_child.c | 4 ++++ - src/providers/proxy/proxy_auth.c | 4 ++-- - src/providers/proxy/proxy_child.c | 4 ++++ - src/responder/autofs/autofssrv.c | 4 ++++ - src/responder/ifp/ifpsrv.c | 4 ++++ - src/responder/kcm/kcm.c | 4 ++++ - src/responder/nss/nsssrv.c | 4 ++++ - src/responder/pac/pacsrv.c | 4 ++++ - src/responder/pam/pamsrv.c | 4 ++++ - src/responder/secrets/secsrv.c | 4 ++++ - src/responder/ssh/sshsrv.c | 4 ++++ - src/responder/sudo/sudosrv.c | 4 ++++ - src/tests/cmocka/dummy_child.c | 4 ++++ - src/tests/debug-tests.c | 10 ++++++++ - src/util/child_common.c | 2 +- - src/util/debug.c | 4 ++-- - src/util/server.c | 12 ++++++---- - 24 files changed, 135 insertions(+), 43 deletions(-) - -diff --git a/src/man/sssd.8.xml b/src/man/sssd.8.xml -index 923da6824907f0d2d140d9ca83f87338e7664f83..0b725628ff93f48f832140dd5dc15b040a8b179f 100644 ---- a/src/man/sssd.8.xml -+++ b/src/man/sssd.8.xml -@@ -94,6 +94,37 @@ - - - -+ value -+ -+ -+ -+ Location where SSSD will send log messages. This option -+ overrides the value of the deprecated option -+ . The deprecated -+ option will still work if the -+ is not used. -+ -+ -+ stderr: Redirect debug messages to -+ standard error output. -+ -+ -+ files: Redirect debug messages to -+ the log files. By default, the log files are stored in -+ /var/log/sssd and there are -+ separate log files for every SSSD service and domain. -+ -+ -+ journald: Redirect debug messages -+ to systemd-journald -+ -+ -+ Default: not set -+ -+ -+ -+ -+ - , - - -diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c -index 7726548bbb666bb189667efc1de2295f8a001105..3c0b7ab2dac10fe15a8a5b807cb68ea4b7ab8461 100644 ---- a/src/monitor/monitor.c -+++ b/src/monitor/monitor.c -@@ -1211,22 +1211,11 @@ static int get_service_config(struct mt_ctx *ctx, const char *name, - } - } - -- if (debug_to_file) { -- svc->command = talloc_strdup_append( -- svc->command, " --debug-to-files" -- ); -- if (!svc->command) { -- talloc_free(svc); -- return ENOMEM; -- } -- } else if (ctx->is_daemon == false) { -- svc->command = talloc_strdup_append( -- svc->command, " --debug-to-stderr" -- ); -- if (!svc->command) { -- talloc_free(svc); -- return ENOMEM; -- } -+ svc->command = talloc_asprintf_append( -+ svc->command, " --logger=%s", sss_logger_str[sss_logger]); -+ if (!svc->command) { -+ talloc_free(svc); -+ return ENOMEM; - } - } - -@@ -1374,22 +1363,11 @@ static int get_provider_config(struct mt_ctx *ctx, const char *name, - } - } - -- if (debug_to_file) { -- svc->command = talloc_strdup_append( -- svc->command, " --debug-to-files" -- ); -- if (!svc->command) { -- talloc_free(svc); -- return ENOMEM; -- } -- } else if (ctx->is_daemon == false) { -- svc->command = talloc_strdup_append( -- svc->command, " --debug-to-stderr" -- ); -- if (!svc->command) { -- talloc_free(svc); -- return ENOMEM; -- } -+ svc->command = talloc_asprintf_append( -+ svc->command, " --logger=%s", sss_logger_str[sss_logger]); -+ if (!svc->command) { -+ talloc_free(svc); -+ return ENOMEM; - } - } - -@@ -2454,6 +2432,7 @@ int main(int argc, const char *argv[]) - int opt_version = 0; - int opt_netlinkoff = 0; - char *opt_config_file = NULL; -+ char *opt_logger = NULL; - char *config_file = NULL; - int flags = 0; - struct main_context *main_ctx; -@@ -2465,6 +2444,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - {"daemon", 'D', POPT_ARG_NONE, &opt_daemon, 0, \ - _("Become a daemon (default)"), NULL }, \ - {"interactive", 'i', POPT_ARG_NONE, &opt_interactive, 0, \ -@@ -2551,6 +2531,8 @@ int main(int argc, const char *argv[]) - debug_to_stderr = 1; - } - -+ sss_set_logger(opt_logger); -+ - if (opt_config_file) { - config_file = talloc_strdup(tmp_ctx, opt_config_file); - } else { -@@ -2575,7 +2557,7 @@ int main(int argc, const char *argv[]) - - /* Open before server_setup() does to have logging - * during configuration checking */ -- if (debug_to_file) { -+ if (sss_logger == FILES_LOGGER) { - ret = open_debug_file(); - if (ret) { - return 7; -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index f165b58e63d2b8a6f26acf8bd89e7b41713e7359..e7dbcb689220d1cd2585fbde5f26e84f8fa15cc2 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -537,6 +537,7 @@ int main(int argc, const char *argv[]) - int opt; - poptContext pc; - int debug_fd = -1; -+ char *opt_logger = NULL; - errno_t ret; - TALLOC_CTX *main_ctx = NULL; - char *cert; -@@ -564,6 +565,7 @@ int main(int argc, const char *argv[]) - {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, - &debug_to_stderr, 0, - _("Send the debug output to stderr directly."), NULL }, -+ SSSD_LOGGER_OPTS - {"auth", 0, POPT_ARG_NONE, NULL, 'a', _("Run in auth mode"), NULL}, - {"pre", 0, POPT_ARG_NONE, NULL, 'p', _("Run in pre-auth mode"), NULL}, - {"pin", 0, POPT_ARG_NONE, NULL, 'i', _("Expect PIN on stdin"), NULL}, -@@ -672,6 +674,7 @@ int main(int argc, const char *argv[]) - DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n"); - } - } -+ sss_set_logger(opt_logger); - - DEBUG(SSSDBG_TRACE_FUNC, "p11_child started.\n"); - -diff --git a/src/providers/ad/ad_gpo_child.c b/src/providers/ad/ad_gpo_child.c -index 8e5e062547721567cb450f9d0f72f1ec8cb99f96..5375cc691e8649c289672b74c4bfe5266c8222c9 100644 ---- a/src/providers/ad/ad_gpo_child.c -+++ b/src/providers/ad/ad_gpo_child.c -@@ -687,6 +687,7 @@ main(int argc, const char *argv[]) - int opt; - poptContext pc; - int debug_fd = -1; -+ char *opt_logger = NULL; - errno_t ret; - int sysvol_gpt_version; - int result; -@@ -710,6 +711,7 @@ main(int argc, const char *argv[]) - {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, - &debug_to_stderr, 0, - _("Send the debug output to stderr directly."), NULL }, -+ SSSD_LOGGER_OPTS - POPT_TABLEEND - }; - -@@ -744,6 +746,8 @@ main(int argc, const char *argv[]) - } - } - -+ sss_set_logger(opt_logger); -+ - DEBUG(SSSDBG_TRACE_FUNC, "gpo_child started.\n"); - - main_ctx = talloc_new(NULL); -diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c -index 2e55dc4e3fe9ba1aa8c1c51c426efee00b9ae91d..56ddac112a209b6937313d3d3c94a73d2067331f 100644 ---- a/src/providers/data_provider_be.c -+++ b/src/providers/data_provider_be.c -@@ -537,6 +537,7 @@ int main(int argc, const char *argv[]) - { - int opt; - poptContext pc; -+ char *opt_logger = NULL; - char *be_domain = NULL; - char *srv_name = NULL; - struct main_context *main_ctx; -@@ -548,6 +549,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - SSSD_SERVER_OPTS(uid, gid) - {"domain", 0, POPT_ARG_STRING, &be_domain, 0, - _("Domain of the information provider (mandatory)"), NULL }, -@@ -582,6 +584,8 @@ int main(int argc, const char *argv[]) - debug_log_file = talloc_asprintf(NULL, "sssd_%s", be_domain); - if (!debug_log_file) return 2; - -+ sss_set_logger(opt_logger); -+ - srv_name = talloc_asprintf(NULL, "sssd[be[%s]]", be_domain); - if (!srv_name) return 2; - -diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c -index 073475094ee491bd5453898c6ba65214fa14fe59..120492686963241b7e419413f489cc38953e32f2 100644 ---- a/src/providers/ipa/selinux_child.c -+++ b/src/providers/ipa/selinux_child.c -@@ -206,6 +206,7 @@ int main(int argc, const char *argv[]) - struct response *resp = NULL; - ssize_t written; - bool needs_update; -+ char *opt_logger = NULL; - - struct poptOption long_options[] = { - POPT_AUTOHELP -@@ -220,6 +221,7 @@ int main(int argc, const char *argv[]) - {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, - &debug_to_stderr, 0, - _("Send the debug output to stderr directly."), NULL }, -+ SSSD_LOGGER_OPTS - POPT_TABLEEND - }; - -@@ -254,6 +256,8 @@ int main(int argc, const char *argv[]) - } - } - -+ sss_set_logger(opt_logger); -+ - DEBUG(SSSDBG_TRACE_FUNC, "selinux_child started.\n"); - DEBUG(SSSDBG_TRACE_INTERNAL, - "Running with effective IDs: [%"SPRIuid"][%"SPRIgid"].\n", -diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c -index 888cc5d6f5c554901cc46d4315844d7bbbe582b8..700338e47a3f9ac6fcf11b4c92364dbdb4f9bcf7 100644 ---- a/src/providers/krb5/krb5_child.c -+++ b/src/providers/krb5/krb5_child.c -@@ -3020,6 +3020,7 @@ int main(int argc, const char *argv[]) - int opt; - poptContext pc; - int debug_fd = -1; -+ char *opt_logger = NULL; - errno_t ret; - krb5_error_code kerr; - uid_t fast_uid; -@@ -3039,6 +3040,7 @@ int main(int argc, const char *argv[]) - {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, - &debug_to_stderr, 0, - _("Send the debug output to stderr directly."), NULL }, -+ SSSD_LOGGER_OPTS - {CHILD_OPT_FAST_CCACHE_UID, 0, POPT_ARG_INT, &fast_uid, 0, - _("The user to create FAST ccache as"), NULL}, - {CHILD_OPT_FAST_CCACHE_GID, 0, POPT_ARG_INT, &fast_gid, 0, -@@ -3097,6 +3099,8 @@ int main(int argc, const char *argv[]) - } - } - -+ sss_set_logger(opt_logger); -+ - DEBUG(SSSDBG_TRACE_FUNC, "krb5_child started.\n"); - - kr = talloc_zero(NULL, struct krb5_req); -diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c -index b796e5cae01517c85c2fc1605b1e5877454691dc..baeed239db5dc7ffa482edcbc155f25f718c8249 100644 ---- a/src/providers/ldap/ldap_child.c -+++ b/src/providers/ldap/ldap_child.c -@@ -599,6 +599,7 @@ int main(int argc, const char *argv[]) - int kerr; - int opt; - int debug_fd = -1; -+ char *opt_logger = NULL; - poptContext pc; - TALLOC_CTX *main_ctx = NULL; - uint8_t *buf = NULL; -@@ -622,6 +623,7 @@ int main(int argc, const char *argv[]) - _("An open file descriptor for the debug logs"), NULL}, - {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, \ - _("Send the debug output to stderr directly."), NULL }, \ -+ SSSD_LOGGER_OPTS - POPT_TABLEEND - }; - -@@ -657,6 +659,8 @@ int main(int argc, const char *argv[]) - } - } - -+ sss_set_logger(opt_logger); -+ - BlockSignals(false, SIGTERM); - CatchSignal(SIGTERM, sig_term_handler); - -diff --git a/src/providers/proxy/proxy_auth.c b/src/providers/proxy/proxy_auth.c -index a05586e60b6ef894b0fcf1b8b3f30fdbf51a808d..665a29cf779290b8d35973245a36a1b5224bca78 100644 ---- a/src/providers/proxy/proxy_auth.c -+++ b/src/providers/proxy/proxy_auth.c -@@ -178,9 +178,9 @@ static struct tevent_req *proxy_child_init_send(TALLOC_CTX *mem_ctx, - - state->command = talloc_asprintf(req, - "%s/proxy_child -d %#.4x --debug-timestamps=%d " -- "--debug-microseconds=%d%s --domain %s --id %d", -+ "--debug-microseconds=%d --logger=%s --domain %s --id %d", - SSSD_LIBEXEC_PATH, debug_level, debug_timestamps, -- debug_microseconds, (debug_to_file ? " --debug-to-files" : ""), -+ debug_microseconds, sss_logger_str[sss_logger], - auth_ctx->be->domain->name, - child_ctx->id); - if (state->command == NULL) { -diff --git a/src/providers/proxy/proxy_child.c b/src/providers/proxy/proxy_child.c -index be58622eb8b26231eeb6699976d51f57dc44de98..ae4855adeb5cc68f1a19003355a5d94f5b1bb378 100644 ---- a/src/providers/proxy/proxy_child.c -+++ b/src/providers/proxy/proxy_child.c -@@ -504,6 +504,7 @@ int main(int argc, const char *argv[]) - { - int opt; - poptContext pc; -+ char *opt_logger = NULL; - char *domain = NULL; - char *srv_name = NULL; - char *conf_entry = NULL; -@@ -517,6 +518,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - SSSD_SERVER_OPTS(uid, gid) - {"domain", 0, POPT_ARG_STRING, &domain, 0, - _("Domain of the information provider (mandatory)"), NULL }, -@@ -561,6 +563,8 @@ int main(int argc, const char *argv[]) - debug_log_file = talloc_asprintf(NULL, "proxy_child_%s", domain); - if (!debug_log_file) return 2; - -+ sss_set_logger(opt_logger); -+ - srv_name = talloc_asprintf(NULL, "sssd[proxy_child[%s]]", domain); - if (!srv_name) return 2; - -diff --git a/src/responder/autofs/autofssrv.c b/src/responder/autofs/autofssrv.c -index cfb2233fdfc346bf27b128ee8c4261f4c73e3470..b0762a2b685a7c5ab3abfa281f0906ad8bfe1c88 100644 ---- a/src/responder/autofs/autofssrv.c -+++ b/src/responder/autofs/autofssrv.c -@@ -185,6 +185,7 @@ int main(int argc, const char *argv[]) - { - int opt; - poptContext pc; -+ char *opt_logger = NULL; - struct main_context *main_ctx; - int ret; - uid_t uid; -@@ -193,6 +194,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - SSSD_SERVER_OPTS(uid, gid) - SSSD_RESPONDER_OPTS - POPT_TABLEEND -@@ -221,6 +223,8 @@ int main(int argc, const char *argv[]) - /* set up things like debug, signals, daemonization, etc... */ - debug_log_file = "sssd_autofs"; - -+ sss_set_logger(opt_logger); -+ - ret = server_setup("sssd[autofs]", 0, uid, gid, - CONFDB_AUTOFS_CONF_ENTRY, &main_ctx); - if (ret != EOK) { -diff --git a/src/responder/ifp/ifpsrv.c b/src/responder/ifp/ifpsrv.c -index 0dc61a42200cc79fc6f12515a8f581ad0201a043..85dfbacc217e2870dd7517e36a1d39e7f2054a8b 100644 ---- a/src/responder/ifp/ifpsrv.c -+++ b/src/responder/ifp/ifpsrv.c -@@ -355,6 +355,7 @@ int main(int argc, const char *argv[]) - { - int opt; - poptContext pc; -+ char *opt_logger = NULL; - struct main_context *main_ctx; - int ret; - uid_t uid; -@@ -363,6 +364,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - SSSD_SERVER_OPTS(uid, gid) - SSSD_RESPONDER_OPTS - POPT_TABLEEND -@@ -391,6 +393,8 @@ int main(int argc, const char *argv[]) - /* set up things like debug, signals, daemonization, etc... */ - debug_log_file = "sssd_ifp"; - -+ sss_set_logger(opt_logger); -+ - ret = server_setup("sssd[ifp]", 0, 0, 0, - CONFDB_IFP_CONF_ENTRY, &main_ctx); - if (ret != EOK) return 2; -diff --git a/src/responder/kcm/kcm.c b/src/responder/kcm/kcm.c -index 2202f96381a2622a2c5433e281172287b325f960..358fcc18165dec7b41a7389a3ef22660ac04b4a8 100644 ---- a/src/responder/kcm/kcm.c -+++ b/src/responder/kcm/kcm.c -@@ -258,6 +258,7 @@ int main(int argc, const char *argv[]) - { - int opt; - poptContext pc; -+ char *opt_logger = NULL; - struct main_context *main_ctx; - int ret; - uid_t uid; -@@ -266,6 +267,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - SSSD_SERVER_OPTS(uid, gid) - POPT_TABLEEND - }; -@@ -293,6 +295,8 @@ int main(int argc, const char *argv[]) - /* set up things like debug, signals, daemonization, etc... */ - debug_log_file = "sssd_kcm"; - -+ sss_set_logger(opt_logger); -+ - ret = server_setup("sssd[kcm]", 0, uid, gid, CONFDB_KCM_CONF_ENTRY, - &main_ctx); - if (ret != EOK) return 2; -diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c -index 32bfcd69bbb9b35e9932b70a826c4f99ab6a07f3..11d19fd30c86283d537623db12e52caa6cc4dcd3 100644 ---- a/src/responder/nss/nsssrv.c -+++ b/src/responder/nss/nsssrv.c -@@ -422,6 +422,7 @@ int main(int argc, const char *argv[]) - { - int opt; - poptContext pc; -+ char *opt_logger = NULL; - struct main_context *main_ctx; - int ret; - uid_t uid; -@@ -430,6 +431,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - SSSD_SERVER_OPTS(uid, gid) - SSSD_RESPONDER_OPTS - POPT_TABLEEND -@@ -458,6 +460,8 @@ int main(int argc, const char *argv[]) - /* set up things like debug, signals, daemonization, etc... */ - debug_log_file = "sssd_nss"; - -+ sss_set_logger(opt_logger); -+ - ret = server_setup("sssd[nss]", 0, uid, gid, CONFDB_NSS_CONF_ENTRY, - &main_ctx); - if (ret != EOK) return 2; -diff --git a/src/responder/pac/pacsrv.c b/src/responder/pac/pacsrv.c -index 1f820c07f5c55fe8df75cce05b403c41075d9f94..b72e5c8d2a42bc85f0974dcb81a1290d3f740986 100644 ---- a/src/responder/pac/pacsrv.c -+++ b/src/responder/pac/pacsrv.c -@@ -209,6 +209,7 @@ int main(int argc, const char *argv[]) - { - int opt; - poptContext pc; -+ char *opt_logger = NULL; - struct main_context *main_ctx; - int ret; - uid_t uid; -@@ -217,6 +218,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - SSSD_SERVER_OPTS(uid, gid) - SSSD_RESPONDER_OPTS - POPT_TABLEEND -@@ -245,6 +247,8 @@ int main(int argc, const char *argv[]) - /* set up things like debug, signals, daemonization, etc... */ - debug_log_file = "sssd_pac"; - -+ sss_set_logger(opt_logger); -+ - ret = server_setup("sssd[pac]", 0, uid, gid, - CONFDB_PAC_CONF_ENTRY, &main_ctx); - if (ret != EOK) return 2; -diff --git a/src/responder/pam/pamsrv.c b/src/responder/pam/pamsrv.c -index 79470823d18138da6ef9235e6336a3220ead1797..cc0e4bddcdbecfadabea78a6d2815d0ac6d651b6 100644 ---- a/src/responder/pam/pamsrv.c -+++ b/src/responder/pam/pamsrv.c -@@ -355,6 +355,7 @@ int main(int argc, const char *argv[]) - { - int opt; - poptContext pc; -+ char *opt_logger = NULL; - struct main_context *main_ctx; - int ret; - uid_t uid; -@@ -365,6 +366,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - SSSD_SERVER_OPTS(uid, gid) - SSSD_RESPONDER_OPTS - POPT_TABLEEND -@@ -393,6 +395,8 @@ int main(int argc, const char *argv[]) - /* set up things like debug, signals, daemonization, etc... */ - debug_log_file = "sssd_pam"; - -+ sss_set_logger(opt_logger); -+ - if (!is_socket_activated()) { - /* Crate pipe file descriptors here before privileges are dropped - * in server_setup() */ -diff --git a/src/responder/secrets/secsrv.c b/src/responder/secrets/secsrv.c -index 2b661b165ef0c174557f53012b2dbaa236a6e359..59c0f3a56040a6fc0c092247fbd124a069f97153 100644 ---- a/src/responder/secrets/secsrv.c -+++ b/src/responder/secrets/secsrv.c -@@ -324,6 +324,7 @@ int main(int argc, const char *argv[]) - { - int opt; - poptContext pc; -+ char *opt_logger = NULL; - struct main_context *main_ctx; - int ret; - uid_t uid; -@@ -332,6 +333,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - SSSD_SERVER_OPTS(uid, gid) - POPT_TABLEEND - }; -@@ -359,6 +361,8 @@ int main(int argc, const char *argv[]) - /* set up things like debug, signals, daemonization, etc... */ - debug_log_file = "sssd_secrets"; - -+ sss_set_logger(opt_logger); -+ - ret = server_setup("sssd[secrets]", 0, uid, gid, CONFDB_SEC_CONF_ENTRY, - &main_ctx); - if (ret != EOK) return 2; -diff --git a/src/responder/ssh/sshsrv.c b/src/responder/ssh/sshsrv.c -index 440f0e2b9dc06e3dc52ff96d7207b8a3727865c0..8b0e7cc2d71044d7ab3bd2439041f678ddedb4cd 100644 ---- a/src/responder/ssh/sshsrv.c -+++ b/src/responder/ssh/sshsrv.c -@@ -177,6 +177,7 @@ int main(int argc, const char *argv[]) - { - int opt; - poptContext pc; -+ char *opt_logger = NULL; - struct main_context *main_ctx; - int ret; - uid_t uid; -@@ -185,6 +186,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - SSSD_SERVER_OPTS(uid, gid) - SSSD_RESPONDER_OPTS - POPT_TABLEEND -@@ -213,6 +215,8 @@ int main(int argc, const char *argv[]) - /* set up things like debug, signals, daemonization, etc... */ - debug_log_file = "sssd_ssh"; - -+ sss_set_logger(opt_logger); -+ - ret = server_setup("sssd[ssh]", 0, uid, gid, - CONFDB_SSH_CONF_ENTRY, &main_ctx); - if (ret != EOK) { -diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c -index dca70ea4afc0e6df6d1b1864338c7b1091a98fee..19058321a25022d7704556ec0ef79729db3ac1f2 100644 ---- a/src/responder/sudo/sudosrv.c -+++ b/src/responder/sudo/sudosrv.c -@@ -178,6 +178,7 @@ int main(int argc, const char *argv[]) - { - int opt; - poptContext pc; -+ char *opt_logger = NULL; - struct main_context *main_ctx; - int ret; - uid_t uid; -@@ -186,6 +187,7 @@ int main(int argc, const char *argv[]) - struct poptOption long_options[] = { - POPT_AUTOHELP - SSSD_MAIN_OPTS -+ SSSD_LOGGER_OPTS - SSSD_SERVER_OPTS(uid, gid) - SSSD_RESPONDER_OPTS - POPT_TABLEEND -@@ -214,6 +216,8 @@ int main(int argc, const char *argv[]) - /* set up things like debug, signals, daemonization, etc... */ - debug_log_file = "sssd_sudo"; - -+ sss_set_logger(opt_logger); -+ - ret = server_setup("sssd[sudo]", 0, uid, gid, CONFDB_SUDO_CONF_ENTRY, - &main_ctx); - if (ret != EOK) { -diff --git a/src/tests/cmocka/dummy_child.c b/src/tests/cmocka/dummy_child.c -index bcaa9455037a0604422750bf7cc719a25cef4a99..811cb40490c89c4250401e0d8d3e9d1c277f57af 100644 ---- a/src/tests/cmocka/dummy_child.c -+++ b/src/tests/cmocka/dummy_child.c -@@ -34,6 +34,7 @@ int main(int argc, const char *argv[]) - { - int opt; - int debug_fd = -1; -+ char *opt_logger = NULL; - poptContext pc; - ssize_t len; - ssize_t written; -@@ -55,6 +56,7 @@ int main(int argc, const char *argv[]) - _("An open file descriptor for the debug logs"), NULL}, - {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, \ - _("Send the debug output to stderr directly."), NULL }, -+ SSSD_LOGGER_OPTS - {"guitar", 0, POPT_ARG_STRING, &guitar, 0, _("Who plays guitar"), NULL }, - {"drums", 0, POPT_ARG_STRING, &drums, 0, _("Who plays drums"), NULL }, - POPT_TABLEEND -@@ -76,6 +78,8 @@ int main(int argc, const char *argv[]) - } - poptFreeContext(pc); - -+ sss_set_logger(opt_logger); -+ - action = getenv("TEST_CHILD_ACTION"); - if (action) { - if (strcasecmp(action, "check_extra_args") == 0) { -diff --git a/src/tests/debug-tests.c b/src/tests/debug-tests.c -index d904d7eb8b5418608023faca0d62067f3106d23b..1446ec0474ab4bf72e66b58831fef59defd7be76 100644 ---- a/src/tests/debug-tests.c -+++ b/src/tests/debug-tests.c -@@ -343,6 +343,7 @@ START_TEST(test_debug_is_set_single_no_timestamp) - debug_microseconds = 0; - debug_to_file = 1; - debug_prg_name = "sssd"; -+ sss_set_logger(sss_logger_str[FILES_LOGGER]); - - for (i = 0; i <= 9; i++) { - debug_level = levels[i]; -@@ -385,6 +386,8 @@ START_TEST(test_debug_is_set_single_timestamp) - debug_microseconds = 0; - debug_to_file = 1; - debug_prg_name = "sssd"; -+ sss_set_logger(sss_logger_str[FILES_LOGGER]); -+ - - for (i = 0; i <= 9; i++) { - debug_level = levels[i]; -@@ -432,6 +435,8 @@ START_TEST(test_debug_is_set_single_timestamp_microseconds) - debug_microseconds = 1; - debug_to_file = 1; - debug_prg_name = "sssd"; -+ sss_set_logger(sss_logger_str[FILES_LOGGER]); -+ - - for (i = 0; i <= 9; i++) { - debug_level = levels[i]; -@@ -480,6 +485,8 @@ START_TEST(test_debug_is_notset_no_timestamp) - debug_microseconds = 0; - debug_to_file = 1; - debug_prg_name = "sssd"; -+ sss_set_logger(sss_logger_str[FILES_LOGGER]); -+ - - for (i = 0; i <= 9; i++) { - debug_level = all_set & ~levels[i]; -@@ -525,6 +532,8 @@ START_TEST(test_debug_is_notset_timestamp) - debug_microseconds = 0; - debug_to_file = 1; - debug_prg_name = "sssd"; -+ sss_set_logger(sss_logger_str[FILES_LOGGER]); -+ - - for (i = 0; i <= 9; i++) { - debug_level = all_set & ~levels[i]; -@@ -570,6 +579,7 @@ START_TEST(test_debug_is_notset_timestamp_microseconds) - debug_microseconds = 1; - debug_to_file = 1; - debug_prg_name = "sssd"; -+ sss_set_logger(sss_logger_str[FILES_LOGGER]); - - for (i = 0; i <= 9; i++) { - debug_level = all_set & ~levels[i]; -diff --git a/src/util/child_common.c b/src/util/child_common.c -index b300d84bf432608db96de36e04637b5fb115212e..dc070f26446305e07cbb34edd1e4d72db72aedc5 100644 ---- a/src/util/child_common.c -+++ b/src/util/child_common.c -@@ -676,7 +676,7 @@ static errno_t prepare_child_argv(TALLOC_CTX *mem_ctx, - } - - if (child_debug_stderr) { -- argv[--argc] = talloc_strdup(argv, "--debug-to-stderr"); -+ argv[--argc] = talloc_strdup(argv, "--logger=stderr"); - if (argv[argc] == NULL) { - ret = ENOMEM; - goto fail; -diff --git a/src/util/debug.c b/src/util/debug.c -index 4e469447e5ab8aa89cd57bcd6d00269875a12bc6..30801fce7c27b115d1cafd4ed826a57c7d444a72 100644 ---- a/src/util/debug.c -+++ b/src/util/debug.c -@@ -277,7 +277,7 @@ void sss_vdebug_fn(const char *file, - errno_t ret; - va_list ap_fallback; - -- if (!debug_file && !debug_to_stderr) { -+ if (sss_logger == JOURNALD_LOGGER) { - /* If we are not outputting logs to files, we should be sending them - * to journald. - * NOTE: on modern systems, this is where stdout/stderr will end up -@@ -470,7 +470,7 @@ int rotate_debug_files(void) - int ret; - errno_t error; - -- if (!debug_to_file) return EOK; -+ if (sss_logger != FILES_LOGGER) return EOK; - - do { - error = 0; -diff --git a/src/util/server.c b/src/util/server.c -index 0046c9737bc0d9aea7be59b4fed5e0f8930ff66e..26b8b27f0e5c8524520a2d4774e90fd6cb32bf7a 100644 ---- a/src/util/server.c -+++ b/src/util/server.c -@@ -455,7 +455,7 @@ int server_setup(const char *name, int flags, - char *conf_db; - int ret = EOK; - bool dt; -- bool dl; -+ bool dl = false; - bool dm; - struct tevent_signal *tes; - struct logrotate_ctx *lctx; -@@ -637,16 +637,18 @@ int server_setup(const char *name, int flags, - } - - /* same for debug to file */ -- dl = (debug_to_file != 0); - ret = confdb_get_bool(ctx->confdb_ctx, conf_entry, - CONFDB_SERVICE_DEBUG_TO_FILES, -- dl, &dl); -+ false, &dl); - if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, "Error reading from confdb (%d) [%s]\n", - ret, strerror(ret)); - return ret; - } -- if (dl) debug_to_file = 1; -+ if (dl) { -+ debug_to_file = 1; -+ sss_set_logger(sss_logger_str[FILES_LOGGER]); -+ } - - /* before opening the log file set up log rotation */ - lctx = talloc_zero(ctx, struct logrotate_ctx); -@@ -662,7 +664,7 @@ int server_setup(const char *name, int flags, - } - - /* open log file if told so */ -- if (debug_to_file) { -+ if (sss_logger == FILES_LOGGER) { - ret = open_debug_file(); - if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, "Error setting up logging (%d) " --- -2.13.5 - diff --git a/SOURCES/0017-TESTS-Allow-storing-e-mail-address-for-users.patch b/SOURCES/0017-TESTS-Allow-storing-e-mail-address-for-users.patch new file mode 100644 index 0000000..85bee19 --- /dev/null +++ b/SOURCES/0017-TESTS-Allow-storing-e-mail-address-for-users.patch @@ -0,0 +1,65 @@ +From 75710952e74ea6070a53baaf5ea4e80507cdc26c Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Thu, 21 Jun 2018 12:37:42 +0200 +Subject: [PATCH] TESTS: Allow storing e-mail address for users +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This would allow adding tests for by-e-mail lookups later + +Related: +https://pagure.io/SSSD/sssd/issue/3607 + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit d057eb2e20a19ce975dc2202f7c0e9f204eb9510) +--- + src/tests/intg/ldap_ent.py | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/src/tests/intg/ldap_ent.py b/src/tests/intg/ldap_ent.py +index a4c987969d3dcefba2af69e095b220180e0fa54c..1f23e3ab7a7ee62909babb8338379a5f2d4e37f2 100644 +--- a/src/tests/intg/ldap_ent.py ++++ b/src/tests/intg/ldap_ent.py +@@ -25,7 +25,8 @@ def user(base_dn, uid, uidNumber, gidNumber, + loginShell=None, + cn=None, + sn=None, +- sshPubKey=()): ++ sshPubKey=(), ++ mail=None): + """ + Generate an RFC2307(bis) user add-modlist for passing to ldap.add* + """ +@@ -56,6 +57,8 @@ def user(base_dn, uid, uidNumber, gidNumber, + if len(sshPubKey) > 0: + pubkeys = [key.encode('utf-8') for key in sshPubKey] + user[1].append(('sshPublicKey', pubkeys)) ++ if mail is not None: ++ user[1].append(('mail', [mail.encode('utf-8')])) + return user + + +@@ -124,7 +127,8 @@ class List(list): + loginShell=None, + cn=None, + sn=None, +- sshPubKey=()): ++ sshPubKey=(), ++ mail=None): + """Add an RFC2307(bis) user add-modlist.""" + self.append(user(base_dn or self.base_dn, + uid, uidNumber, gidNumber, +@@ -134,7 +138,8 @@ class List(list): + loginShell=loginShell, + cn=cn, + sn=sn, +- sshPubKey=sshPubKey)) ++ sshPubKey=sshPubKey, ++ mail=mail)) + + def add_group(self, cn, gidNumber, member_uids=[], + base_dn=None): +-- +2.17.1 + diff --git a/SOURCES/0018-SYSTEMD-Replace-parameter-debug-to-files-with-DEBUG_.patch b/SOURCES/0018-SYSTEMD-Replace-parameter-debug-to-files-with-DEBUG_.patch deleted file mode 100644 index a409fab..0000000 --- a/SOURCES/0018-SYSTEMD-Replace-parameter-debug-to-files-with-DEBUG_.patch +++ /dev/null @@ -1,259 +0,0 @@ -From 66cdb732268cc8dfd4f0800178d1cc186de83ef7 Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Mon, 23 Oct 2017 18:03:46 +0200 -Subject: [PATCH 18/21] SYSTEMD: Replace parameter --debug-to-files with - ${DEBUG_LOGGER} -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Users can set variable DEBUG_LOGGER in environment files -(/etc/sysconfig/sssd or /etc/default/sssd; depending on the distribution) -to override default logging to files. - -e.g. -DEBUG_LOGGER=--logger=stderr -DEBUG_LOGGER=--logger=journald - -Resolves: -https://pagure.io/SSSD/sssd/issue/3433 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit a7277fecf7a65ab6c83b36f009c558cdfbf997d2) ---- - Makefile.am | 12 +----------- - contrib/sssd.spec.in | 4 ---- - src/sysv/systemd/journal.conf.in | 7 ------- - src/sysv/systemd/sssd-autofs.service.in | 3 ++- - src/sysv/systemd/sssd-ifp.service.in | 3 ++- - src/sysv/systemd/sssd-kcm.service.in | 3 ++- - src/sysv/systemd/sssd-nss.service.in | 3 ++- - src/sysv/systemd/sssd-pac.service.in | 3 ++- - src/sysv/systemd/sssd-pam.service.in | 3 ++- - src/sysv/systemd/sssd-secrets.service.in | 3 ++- - src/sysv/systemd/sssd-ssh.service.in | 3 ++- - src/sysv/systemd/sssd-sudo.service.in | 3 ++- - src/sysv/systemd/sssd.service.in | 3 ++- - 13 files changed, 21 insertions(+), 32 deletions(-) - delete mode 100644 src/sysv/systemd/journal.conf.in - -diff --git a/Makefile.am b/Makefile.am -index 41a8f32f4e76fdcbd09ad833161f0bdada19e389..5483375167d99568e8313c9a0488900419be6ec3 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -91,7 +91,7 @@ sssdkcmdatadir = $(datadir)/sssd-kcm - deskprofilepath = $(sss_statedir)/deskprofile - - if HAVE_SYSTEMD_UNIT --ifp_exec_cmd = $(sssdlibexecdir)/sssd_ifp --uid 0 --gid 0 --debug-to-files --dbus-activated -+ifp_exec_cmd = $(sssdlibexecdir)/sssd_ifp --uid 0 --gid 0 --dbus-activated - ifp_systemdservice = SystemdService=sssd-ifp.service - ifp_restart = Restart=on-failure - else -@@ -4483,10 +4483,6 @@ if BUILD_KCM - src/sysv/systemd/sssd-kcm.service \ - $(NULL) - endif --if WITH_JOURNALD -- systemdconf_DATA += \ -- src/sysv/systemd/journal.conf --endif - else - if HAVE_SUSE - init_SCRIPTS += \ -@@ -4535,7 +4531,6 @@ replace_script = \ - - EXTRA_DIST += \ - src/sysv/systemd/sssd.service.in \ -- src/sysv/systemd/journal.conf.in \ - src/sysv/systemd/sssd-nss.socket.in \ - src/sysv/systemd/sssd-nss.service.in \ - src/sysv/systemd/sssd-pam.socket.in \ -@@ -4585,10 +4580,6 @@ src/sysv/systemd/sssd.service: src/sysv/systemd/sssd.service.in Makefile - @$(MKDIR_P) src/sysv/systemd/ - $(replace_script) - --src/sysv/systemd/journal.conf: src/sysv/systemd/journal.conf.in Makefile -- @$(MKDIR_P) src/sysv/systemd/ -- $(replace_script) -- - src/sysv/systemd/sssd-nss.socket: src/sysv/systemd/sssd-nss.socket.in Makefile - @$(MKDIR_P) src/sysv/systemd/ - $(replace_script) -@@ -4924,7 +4915,6 @@ endif - rm -f $(builddir)/src/sysv/systemd/sssd-secrets.service - rm -f $(builddir)/src/sysv/systemd/sssd-kcm.socket - rm -f $(builddir)/src/sysv/systemd/sssd-kcm.service -- rm -f $(builddir)/src/sysv/systemd/journal.conf - rm -f $(builddir)/src/tools/wrappers/sss_debuglevel - - CLEANFILES += *.X */*.X */*/*.X -diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in -index e76b51833d5dfa3207d28add4af1016c00f25e1f..1ee64d5a2a64635984260fceced779f4804e8b31 100644 ---- a/contrib/sssd.spec.in -+++ b/contrib/sssd.spec.in -@@ -971,10 +971,6 @@ done - %attr(711,sssd,sssd) %dir %{_sysconfdir}/sssd - %attr(711,sssd,sssd) %dir %{_sysconfdir}/sssd/conf.d - %ghost %attr(0600,sssd,sssd) %config(noreplace) %{_sysconfdir}/sssd/sssd.conf --%if (0%{?use_systemd} == 1) --%attr(755,root,root) %dir %{_sysconfdir}/systemd/system/sssd.service.d --%config(noreplace) %{_sysconfdir}/systemd/system/sssd.service.d/journal.conf --%endif - %dir %{_sysconfdir}/logrotate.d - %config(noreplace) %{_sysconfdir}/logrotate.d/sssd - %dir %{_sysconfdir}/rwtab.d -diff --git a/src/sysv/systemd/journal.conf.in b/src/sysv/systemd/journal.conf.in -deleted file mode 100644 -index 9ce170b4893629792516aab41573adea1fb741f0..0000000000000000000000000000000000000000 ---- a/src/sysv/systemd/journal.conf.in -+++ /dev/null -@@ -1,7 +0,0 @@ --[Service] --# Uncomment *both* of the following lines to enable debug logging --# to go to journald instead of /var/log/sssd. You will need to --# run 'systemctl daemon-reload' and then restart the SSSD service --# for this to take effect --#ExecStart= --#ExecStart=@sbindir@/sssd -i -diff --git a/src/sysv/systemd/sssd-autofs.service.in b/src/sysv/systemd/sssd-autofs.service.in -index 32ea6e19ca7f9aa65599c0cf296a8c5e73362271..c2dc254c8f3f56cb6ae4dc481781688aa702b102 100644 ---- a/src/sysv/systemd/sssd-autofs.service.in -+++ b/src/sysv/systemd/sssd-autofs.service.in -@@ -9,8 +9,9 @@ RefuseManualStart=true - Also=sssd-autofs.socket - - [Service] -+Environment=DEBUG_LOGGER=--logger=files - ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_autofs.log --ExecStart=@libexecdir@/sssd/sssd_autofs --debug-to-files --socket-activated -+ExecStart=@libexecdir@/sssd/sssd_autofs ${DEBUG_LOGGER} --socket-activated - Restart=on-failure - User=@SSSD_USER@ - Group=@SSSD_USER@ -diff --git a/src/sysv/systemd/sssd-ifp.service.in b/src/sysv/systemd/sssd-ifp.service.in -index 8e7abdb0e8c5ec83f9423c688daf845a16c57e7e..05a9a602b2d27c54a4faa79c58e0ecba90267100 100644 ---- a/src/sysv/systemd/sssd-ifp.service.in -+++ b/src/sysv/systemd/sssd-ifp.service.in -@@ -5,7 +5,8 @@ After=sssd.service - BindsTo=sssd.service - - [Service] -+Environment=DEBUG_LOGGER=--logger=files - Type=dbus - BusName=org.freedesktop.sssd.infopipe --ExecStart=@ifp_exec_cmd@ -+ExecStart=@ifp_exec_cmd@ ${DEBUG_LOGGER} - @ifp_restart@ -diff --git a/src/sysv/systemd/sssd-kcm.service.in b/src/sysv/systemd/sssd-kcm.service.in -index 1e2bee12dc3bedd17d41b86f91c9b2b52d985c40..92306f97ec73a775739bfdb4454df14956e5e133 100644 ---- a/src/sysv/systemd/sssd-kcm.service.in -+++ b/src/sysv/systemd/sssd-kcm.service.in -@@ -6,4 +6,5 @@ Documentation=man:sssd-kcm(5) - Also=sssd-kcm.socket - - [Service] --ExecStart=@libexecdir@/sssd/sssd_kcm --uid 0 --gid 0 --debug-to-files -+Environment=DEBUG_LOGGER=--logger=files -+ExecStart=@libexecdir@/sssd/sssd_kcm --uid 0 --gid 0 ${DEBUG_LOGGER} -diff --git a/src/sysv/systemd/sssd-nss.service.in b/src/sysv/systemd/sssd-nss.service.in -index 6a29078d5a36dff229e47bf7ce953e46443ce023..fe771ad0fa99968bb1d42037abf2f960271589b1 100644 ---- a/src/sysv/systemd/sssd-nss.service.in -+++ b/src/sysv/systemd/sssd-nss.service.in -@@ -9,5 +9,6 @@ RefuseManualStart=true - Also=sssd-nss.socket - - [Service] --ExecStart=@libexecdir@/sssd/sssd_nss --debug-to-files --socket-activated -+Environment=DEBUG_LOGGER=--logger=files -+ExecStart=@libexecdir@/sssd/sssd_nss ${DEBUG_LOGGER} --socket-activated - Restart=on-failure -diff --git a/src/sysv/systemd/sssd-pac.service.in b/src/sysv/systemd/sssd-pac.service.in -index ffbfdec030ba6d5cf75c989854c27bc46b6983a5..dbd25abc476f579c9d8cce171fdeafa06e567610 100644 ---- a/src/sysv/systemd/sssd-pac.service.in -+++ b/src/sysv/systemd/sssd-pac.service.in -@@ -9,8 +9,9 @@ RefuseManualStart=true - Also=sssd-pac.socket - - [Service] -+Environment=DEBUG_LOGGER=--logger=files - ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_pac.log --ExecStart=@libexecdir@/sssd/sssd_pac --debug-to-files --socket-activated -+ExecStart=@libexecdir@/sssd/sssd_pac ${DEBUG_LOGGER} --socket-activated - Restart=on-failure - User=@SSSD_USER@ - Group=@SSSD_USER@ -diff --git a/src/sysv/systemd/sssd-pam.service.in b/src/sysv/systemd/sssd-pam.service.in -index 6dec46f0c5d384c500268dafcd00af894088e0b6..df722d1f3014bf62cc60114c30331424d14f411b 100644 ---- a/src/sysv/systemd/sssd-pam.service.in -+++ b/src/sysv/systemd/sssd-pam.service.in -@@ -9,8 +9,9 @@ RefuseManualStart=true - Also=sssd-pam.socket sssd-pam-priv.socket - - [Service] -+Environment=DEBUG_LOGGER=--logger=files - ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_pam.log --ExecStart=@libexecdir@/sssd/sssd_pam --debug-to-files --socket-activated -+ExecStart=@libexecdir@/sssd/sssd_pam ${DEBUG_LOGGER} --socket-activated - Restart=on-failure - User=@SSSD_USER@ - Group=@SSSD_USER@ -diff --git a/src/sysv/systemd/sssd-secrets.service.in b/src/sysv/systemd/sssd-secrets.service.in -index f45d647677a62900c01c7eb103597f2b1387498c..a7b41e0b16a5fa882546b41047e616fd2140329f 100644 ---- a/src/sysv/systemd/sssd-secrets.service.in -+++ b/src/sysv/systemd/sssd-secrets.service.in -@@ -6,4 +6,5 @@ Documentation=man:sssd-secrets(5) - Also=sssd-secrets.socket - - [Service] --ExecStart=@libexecdir@/sssd/sssd_secrets --uid 0 --gid 0 --debug-to-files -+Environment=DEBUG_LOGGER=--logger=files -+ExecStart=@libexecdir@/sssd/sssd_secrets --uid 0 --gid 0 ${DEBUG_LOGGER} -diff --git a/src/sysv/systemd/sssd-ssh.service.in b/src/sysv/systemd/sssd-ssh.service.in -index 6f233b4854018d79cc0ad9d67d53ebd67a49f7b7..f41249ea0fe19e5044d5d06ba195ab604d8e6a29 100644 ---- a/src/sysv/systemd/sssd-ssh.service.in -+++ b/src/sysv/systemd/sssd-ssh.service.in -@@ -9,8 +9,9 @@ RefuseManualStart=true - Also=sssd-ssh.socket - - [Service] -+Environment=DEBUG_LOGGER=--logger=files - ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_ssh.log --ExecStart=@libexecdir@/sssd/sssd_ssh --debug-to-files --socket-activated -+ExecStart=@libexecdir@/sssd/sssd_ssh ${DEBUG_LOGGER} --socket-activated - Restart=on-failure - User=@SSSD_USER@ - Group=@SSSD_USER@ -diff --git a/src/sysv/systemd/sssd-sudo.service.in b/src/sysv/systemd/sssd-sudo.service.in -index b59bcbcd817c3986d7ee245b1083f90ff5a3775a..da022f768af91e360182fad0ff885fad43ecfdc0 100644 ---- a/src/sysv/systemd/sssd-sudo.service.in -+++ b/src/sysv/systemd/sssd-sudo.service.in -@@ -9,8 +9,9 @@ RefuseManualStart=true - Also=sssd-sudo.socket - - [Service] -+Environment=DEBUG_LOGGER=--logger=files - ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_sudo.log --ExecStart=@libexecdir@/sssd/sssd_sudo --debug-to-files --socket-activated -+ExecStart=@libexecdir@/sssd/sssd_sudo --socket-activated - Restart=on-failure - User=@SSSD_USER@ - Group=@SSSD_USER@ -diff --git a/src/sysv/systemd/sssd.service.in b/src/sysv/systemd/sssd.service.in -index 05cfd3705084dbff8b46fb07e736612612c58b70..cea848fac80303d6fae12dd84316a91dbc60072d 100644 ---- a/src/sysv/systemd/sssd.service.in -+++ b/src/sysv/systemd/sssd.service.in -@@ -5,8 +5,9 @@ Before=systemd-user-sessions.service nss-user-lookup.target - Wants=nss-user-lookup.target - - [Service] -+Environment=DEBUG_LOGGER=--logger=files - EnvironmentFile=-@environment_file@ --ExecStart=@sbindir@/sssd -i -f -+ExecStart=@sbindir@/sssd -i ${DEBUG_LOGGER} - Type=notify - NotifyAccess=main - --- -2.13.5 - diff --git a/SOURCES/0018-TESTS-Add-regression-test-for-looking-up-users-with-.patch b/SOURCES/0018-TESTS-Add-regression-test-for-looking-up-users-with-.patch new file mode 100644 index 0000000..109d6c0 --- /dev/null +++ b/SOURCES/0018-TESTS-Add-regression-test-for-looking-up-users-with-.patch @@ -0,0 +1,93 @@ +From 0cbf6070bccb6c1f904cea596f00af0cc6328bae Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Thu, 21 Jun 2018 12:37:57 +0200 +Subject: [PATCH] TESTS: Add regression test for looking up users with + conflicting e-mail addresses +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Related: +https://pagure.io/SSSD/sssd/issue/3607 + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit 76ce965fc3abfdcf3a4a9518e57545ea060033d6) +--- + src/tests/intg/test_ldap.py | 64 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +diff --git a/src/tests/intg/test_ldap.py b/src/tests/intg/test_ldap.py +index f71915a8086d395e9971a7c82e2744bdd7b931b6..d70ae39841f111fdf2d6c00c9acca8073725c5c5 100644 +--- a/src/tests/intg/test_ldap.py ++++ b/src/tests/intg/test_ldap.py +@@ -1736,3 +1736,67 @@ def test_local_negative_timeout_disabled(ldap_conn, + assert res == NssReturnCode.SUCCESS + + cleanup_ldap_entries(ldap_conn, ent_list) ++ ++ ++@pytest.fixture ++def users_with_email_setup(request, ldap_conn): ++ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) ++ ent_list.add_user("user1", 1001, 2001, mail="user1.email@LDAP") ++ ++ ent_list.add_user("emailuser", 1002, 2002) ++ ent_list.add_user("emailuser2", 1003, 2003, mail="emailuser@LDAP") ++ ++ ent_list.add_user("userx", 1004, 2004, mail="userxy@LDAP") ++ ent_list.add_user("usery", 1005, 2005, mail="userxy@LDAP") ++ ++ create_ldap_fixture(request, ldap_conn, ent_list) ++ ++ conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) ++ create_conf_fixture(request, conf) ++ create_sssd_fixture(request) ++ return None ++ ++ ++def test_lookup_by_email(ldap_conn, users_with_email_setup): ++ """ ++ Test the simple case of looking up a user by e-mail ++ """ ++ ent.assert_passwd_by_name("user1.email@LDAP", ++ dict(name="user1", uid=1001, gid=2001)) ++ ++ ++def test_conflicting_mail_addresses_and_fqdn(ldap_conn, ++ users_with_email_setup): ++ """ ++ Test that we handle the case where one user's mail address is the ++ same as another user's FQDN ++ ++ This is a regression test for https://pagure.io/SSSD/sssd/issue/3607 ++ """ ++ # With #3607 unfixed, these two lookups would prime the cache with ++ # nameAlias: emailuser@LDAP for both entries.. ++ ent.assert_passwd_by_name("emailuser@LDAP", ++ dict(name="emailuser", uid=1002, gid=2002)) ++ ent.assert_passwd_by_name("emailuser2@LDAP", ++ dict(name="emailuser2", uid=1003, gid=2003)) ++ ++ # ..and subsequently, emailuser would not be returned because the cache ++ # lookup would have had returned two entries which is an error ++ ent.assert_passwd_by_name("emailuser@LDAP", ++ dict(name="emailuser", uid=1002, gid=2002)) ++ ent.assert_passwd_by_name("emailuser2@LDAP", ++ dict(name="emailuser2", uid=1003, gid=2003)) ++ ++ ++def test_conflicting_mail_addresses(ldap_conn, ++ users_with_email_setup): ++ """ ++ Negative test: looking up a user by e-mail which belongs to more than ++ one account fails in the back end. ++ """ ++ with pytest.raises(KeyError): ++ pwd.getpwnam("userxy@LDAP") ++ ++ # However resolving the users on their own must work ++ ent.assert_passwd_by_name("userx", dict(name="userx", uid=1004, gid=2004)) ++ ent.assert_passwd_by_name("usery", dict(name="usery", uid=1005, gid=2005)) +-- +2.17.1 + diff --git a/SOURCES/0019-MAN-Remove-outdated-notes-from-the-re_expression-des.patch b/SOURCES/0019-MAN-Remove-outdated-notes-from-the-re_expression-des.patch new file mode 100644 index 0000000..4ce9fed --- /dev/null +++ b/SOURCES/0019-MAN-Remove-outdated-notes-from-the-re_expression-des.patch @@ -0,0 +1,47 @@ +From 8d5241404e8eb2388a9fc45115f5210e3ada1f1b Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Fri, 22 Jun 2018 10:40:29 +0200 +Subject: [PATCH] MAN: Remove outdated notes from the re_expression description +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +These notes are only valid for very old pcre releases which hopefully +nobody is using anymore. + +Reviewed-by: Fabiano Fidêncio +Reviewed-by: Sumit Bose +(cherry picked from commit 4c79db69cbad88ed56e87e8fe61f697f72d7408d) + +DOWNSTREAM: +Resolves: rhbz#1509691 - Document how to change the regular expression for SSSD so that group names with an @-sign can be parsed +--- + src/man/sssd.conf.5.xml | 12 ------------ + 1 file changed, 12 deletions(-) + +diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml +index beed677072c9bbfb9e7749f25c2a90d743f9328d..558c97e834d7aaf46adb31b1573eb59705569782 100644 +--- a/src/man/sssd.conf.5.xml ++++ b/src/man/sssd.conf.5.xml +@@ -2630,18 +2630,6 @@ pam_account_locked_message = Account locked, please contact help desk. + the @ sign, the domain everything + after that" + +- +- PLEASE NOTE: the support for non-unique named +- subpatterns is not available on all platforms +- (e.g. RHEL5 and SLES10). Only platforms with +- libpcre version 7 or higher can support non-unique +- named subpatterns. +- +- +- PLEASE NOTE ALSO: older version of libpcre only +- support the Python syntax (?P<name>) to label +- subpatterns. +- + + + +-- +2.17.1 + diff --git a/SOURCES/0019-SYSTEMD-Add-environment-file-to-responder-service-fi.patch b/SOURCES/0019-SYSTEMD-Add-environment-file-to-responder-service-fi.patch deleted file mode 100644 index 060c43e..0000000 --- a/SOURCES/0019-SYSTEMD-Add-environment-file-to-responder-service-fi.patch +++ /dev/null @@ -1,107 +0,0 @@ -From cc4f298024b2ef08cc0740ebbaf916bd494ef892 Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Tue, 24 Oct 2017 12:15:48 +0200 -Subject: [PATCH 19/21] SYSTEMD: Add environment file to responder service - files -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 115145f0fb7507c1b9c5489bc77398d422a66875) ---- - src/sysv/systemd/sssd-autofs.service.in | 1 + - src/sysv/systemd/sssd-ifp.service.in | 1 + - src/sysv/systemd/sssd-nss.service.in | 1 + - src/sysv/systemd/sssd-pac.service.in | 1 + - src/sysv/systemd/sssd-pam.service.in | 1 + - src/sysv/systemd/sssd-ssh.service.in | 1 + - src/sysv/systemd/sssd-sudo.service.in | 1 + - 7 files changed, 7 insertions(+) - -diff --git a/src/sysv/systemd/sssd-autofs.service.in b/src/sysv/systemd/sssd-autofs.service.in -index c2dc254c8f3f56cb6ae4dc481781688aa702b102..7f920ad66a46bb0785c3f947bc26c15d0e370259 100644 ---- a/src/sysv/systemd/sssd-autofs.service.in -+++ b/src/sysv/systemd/sssd-autofs.service.in -@@ -10,6 +10,7 @@ Also=sssd-autofs.socket - - [Service] - Environment=DEBUG_LOGGER=--logger=files -+EnvironmentFile=-@environment_file@ - ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_autofs.log - ExecStart=@libexecdir@/sssd/sssd_autofs ${DEBUG_LOGGER} --socket-activated - Restart=on-failure -diff --git a/src/sysv/systemd/sssd-ifp.service.in b/src/sysv/systemd/sssd-ifp.service.in -index 05a9a602b2d27c54a4faa79c58e0ecba90267100..f3bf92223ce8847858f57c2bb04b97c858be0ead 100644 ---- a/src/sysv/systemd/sssd-ifp.service.in -+++ b/src/sysv/systemd/sssd-ifp.service.in -@@ -6,6 +6,7 @@ BindsTo=sssd.service - - [Service] - Environment=DEBUG_LOGGER=--logger=files -+EnvironmentFile=-@environment_file@ - Type=dbus - BusName=org.freedesktop.sssd.infopipe - ExecStart=@ifp_exec_cmd@ ${DEBUG_LOGGER} -diff --git a/src/sysv/systemd/sssd-nss.service.in b/src/sysv/systemd/sssd-nss.service.in -index fe771ad0fa99968bb1d42037abf2f960271589b1..c671280f2c8a7f85fd09a72983a21db0c30df3b9 100644 ---- a/src/sysv/systemd/sssd-nss.service.in -+++ b/src/sysv/systemd/sssd-nss.service.in -@@ -10,5 +10,6 @@ Also=sssd-nss.socket - - [Service] - Environment=DEBUG_LOGGER=--logger=files -+EnvironmentFile=-@environment_file@ - ExecStart=@libexecdir@/sssd/sssd_nss ${DEBUG_LOGGER} --socket-activated - Restart=on-failure -diff --git a/src/sysv/systemd/sssd-pac.service.in b/src/sysv/systemd/sssd-pac.service.in -index dbd25abc476f579c9d8cce171fdeafa06e567610..590449b01223fe799eebb12b63229dfb8f2438f9 100644 ---- a/src/sysv/systemd/sssd-pac.service.in -+++ b/src/sysv/systemd/sssd-pac.service.in -@@ -10,6 +10,7 @@ Also=sssd-pac.socket - - [Service] - Environment=DEBUG_LOGGER=--logger=files -+EnvironmentFile=-@environment_file@ - ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_pac.log - ExecStart=@libexecdir@/sssd/sssd_pac ${DEBUG_LOGGER} --socket-activated - Restart=on-failure -diff --git a/src/sysv/systemd/sssd-pam.service.in b/src/sysv/systemd/sssd-pam.service.in -index df722d1f3014bf62cc60114c30331424d14f411b..f2e938579c7ef4254bb2e05231bfe83d7e20f395 100644 ---- a/src/sysv/systemd/sssd-pam.service.in -+++ b/src/sysv/systemd/sssd-pam.service.in -@@ -10,6 +10,7 @@ Also=sssd-pam.socket sssd-pam-priv.socket - - [Service] - Environment=DEBUG_LOGGER=--logger=files -+EnvironmentFile=-@environment_file@ - ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_pam.log - ExecStart=@libexecdir@/sssd/sssd_pam ${DEBUG_LOGGER} --socket-activated - Restart=on-failure -diff --git a/src/sysv/systemd/sssd-ssh.service.in b/src/sysv/systemd/sssd-ssh.service.in -index f41249ea0fe19e5044d5d06ba195ab604d8e6a29..1c185466dfa8c13804cc980bbbdbc997d4ebe955 100644 ---- a/src/sysv/systemd/sssd-ssh.service.in -+++ b/src/sysv/systemd/sssd-ssh.service.in -@@ -10,6 +10,7 @@ Also=sssd-ssh.socket - - [Service] - Environment=DEBUG_LOGGER=--logger=files -+EnvironmentFile=-@environment_file@ - ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_ssh.log - ExecStart=@libexecdir@/sssd/sssd_ssh ${DEBUG_LOGGER} --socket-activated - Restart=on-failure -diff --git a/src/sysv/systemd/sssd-sudo.service.in b/src/sysv/systemd/sssd-sudo.service.in -index da022f768af91e360182fad0ff885fad43ecfdc0..f13d88107eccd9e80447390c9c0f8940ae933106 100644 ---- a/src/sysv/systemd/sssd-sudo.service.in -+++ b/src/sysv/systemd/sssd-sudo.service.in -@@ -10,6 +10,7 @@ Also=sssd-sudo.socket - - [Service] - Environment=DEBUG_LOGGER=--logger=files -+EnvironmentFile=-@environment_file@ - ExecStartPre=-/bin/chown @SSSD_USER@:@SSSD_USER@ @logpath@/sssd_sudo.log - ExecStart=@libexecdir@/sssd/sssd_sudo --socket-activated - Restart=on-failure --- -2.13.5 - diff --git a/SOURCES/0020-SUDO-Create-the-socket-with-stricter-permissions.patch b/SOURCES/0020-SUDO-Create-the-socket-with-stricter-permissions.patch new file mode 100644 index 0000000..0b81675 --- /dev/null +++ b/SOURCES/0020-SUDO-Create-the-socket-with-stricter-permissions.patch @@ -0,0 +1,58 @@ +From e13d53326bc154c684ea1bef9efc5922b5228945 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Fri, 15 Jun 2018 22:29:34 +0200 +Subject: [PATCH] SUDO: Create the socket with stricter permissions +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch switches the sudo responder from being created as a public +responder where the permissions are open and not checked by the sssd +deaamon to a private socket. In this case, sssd creates the pipes with +strict permissions (see the umask in the call to create_pipe_fd() in +set_unix_socket()) and additionaly checks the permissions with every read +via the tevent integrations (see accept_fd_handler()). + +Resolves: +https://pagure.io/SSSD/sssd/issue/3766 (CVE-2018-10852) + +Reviewed-by: Sumit Bose +Reviewed-by: Pavel Březina +(cherry picked from commit ed90a20a0f0e936eb00d268080716c0384ffb01d) + +DOWNSTREAM: +Resolves: rhbz#1590603 - EMBARGOED CVE-2018-10852 sssd: information leak from the sssd-sudo responder [rhel-7] +--- + src/responder/sudo/sudosrv.c | 3 ++- + src/sysv/systemd/sssd-sudo.socket.in | 1 + + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c +index ac4258710d3a9b48285522abd23bdd59ba42ad4e..e87a24499c2d82fafaa8e1f9b386e44332394266 100644 +--- a/src/responder/sudo/sudosrv.c ++++ b/src/responder/sudo/sudosrv.c +@@ -79,7 +79,8 @@ int sudo_process_init(TALLOC_CTX *mem_ctx, + sudo_cmds = get_sudo_cmds(); + ret = sss_process_init(mem_ctx, ev, cdb, + sudo_cmds, +- SSS_SUDO_SOCKET_NAME, -1, NULL, -1, ++ NULL, -1, /* No public socket */ ++ SSS_SUDO_SOCKET_NAME, -1, /* Private socket only */ + CONFDB_SUDO_CONF_ENTRY, + SSS_SUDO_SBUS_SERVICE_NAME, + SSS_SUDO_SBUS_SERVICE_VERSION, +diff --git a/src/sysv/systemd/sssd-sudo.socket.in b/src/sysv/systemd/sssd-sudo.socket.in +index c9abb875f0accbaf58d78846020fef74c7473528..96a8b0327ddb4d331c9b2e97ece3453f8f76872d 100644 +--- a/src/sysv/systemd/sssd-sudo.socket.in ++++ b/src/sysv/systemd/sssd-sudo.socket.in +@@ -11,6 +11,7 @@ ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r sudo + ListenStream=@pipepath@/sudo + SocketUser=@SSSD_USER@ + SocketGroup=@SSSD_USER@ ++SocketMode=0600 + + [Install] + WantedBy=sssd.service +-- +2.17.1 + diff --git a/SOURCES/0020-UTIL-Hide-and-deprecate-parameter-debug-to-files.patch b/SOURCES/0020-UTIL-Hide-and-deprecate-parameter-debug-to-files.patch deleted file mode 100644 index 8ade838..0000000 --- a/SOURCES/0020-UTIL-Hide-and-deprecate-parameter-debug-to-files.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 65e47ac92a16c57058b955fe9ec2e17b838a37db Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Tue, 24 Oct 2017 12:07:46 +0200 -Subject: [PATCH 20/21] UTIL: Hide and deprecate parameter --debug-to-files -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Reviewed-by: Justin Stephenson -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 18a47bcc463c866de6b6b0327e6d85ceb1e0f7d6) ---- - src/man/sssd.8.xml | 4 ++++ - src/util/debug.h | 2 +- - 2 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/man/sssd.8.xml b/src/man/sssd.8.xml -index 0b725628ff93f48f832140dd5dc15b040a8b179f..f2cbe015b844579af98aebd864770bc651dcf4b1 100644 ---- a/src/man/sssd.8.xml -+++ b/src/man/sssd.8.xml -@@ -90,6 +90,10 @@ - log files are stored in /var/log/sssd and - there are separate log files for every SSSD service and domain. - -+ -+ This option is deprecated. It is replaced by -+ . -+ - - - -diff --git a/src/util/debug.h b/src/util/debug.h -index 4adafb7cfc03f7381c4d03071eb44edad04bee00..09f50cc9f3122f02d8ba2092dfb7ee633332de9b 100644 ---- a/src/util/debug.h -+++ b/src/util/debug.h -@@ -101,7 +101,7 @@ int get_fd_from_debug_file(void); - #define SSSD_DEBUG_OPTS \ - {"debug-level", 'd', POPT_ARG_INT, &debug_level, 0, \ - _("Debug level"), NULL}, \ -- {"debug-to-files", 'f', POPT_ARG_NONE, &debug_to_file, 0, \ -+ {"debug-to-files", 'f', POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_file, 0, \ - _("Send the debug output to files instead of stderr"), NULL }, \ - {"debug-to-stderr", 0, POPT_ARG_NONE | POPT_ARGFLAG_DOC_HIDDEN, &debug_to_stderr, 0, \ - _("Send the debug output to stderr directly."), NULL }, \ --- -2.13.5 - diff --git a/SOURCES/0021-LDAP-Bind-to-the-LDAP-server-also-in-the-auth.patch b/SOURCES/0021-LDAP-Bind-to-the-LDAP-server-also-in-the-auth.patch deleted file mode 100644 index 6f138f1..0000000 --- a/SOURCES/0021-LDAP-Bind-to-the-LDAP-server-also-in-the-auth.patch +++ /dev/null @@ -1,213 +0,0 @@ -From 7ebfab326f94e508ce2910c7242a8dd7652ec8a2 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= -Date: Wed, 25 Oct 2017 11:25:09 +0200 -Subject: [PATCH 21/21] LDAP: Bind to the LDAP server also in the auth -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When dealing with id_provider not being the same as auth_provider, SSSD -has to bind the DN of the user which wants to authenticate with the -ldap_default_bind_dn and the password provided by the user. - -In order to do so, the least intrusive way is just by replacing -sdap_connect*() functions by sdap_cli_connect*() functions in the LDAP's -auth module. - -The simple change also allowed us to remove some code that is already -executed as part of sdap_cli_connect*() and some functions had their -names adapted to reflect better their new purpose. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3451 - -Signed-off-by: Fabiano Fidêncio -Reviewed-by: Sumit Bose -(cherry picked from commit add72860c7a7a2c418f4d8b6790b5caeaf7dfb7b) ---- - src/providers/ldap/ldap_auth.c | 114 +++++++++-------------------------------- - 1 file changed, 25 insertions(+), 89 deletions(-) - -diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c -index 00ddd889b6294e457c13218491547b84f1468266..a3b1480aae4272d2e10f105a1eaf3a5816c3487c 100644 ---- a/src/providers/ldap/ldap_auth.c -+++ b/src/providers/ldap/ldap_auth.c -@@ -619,14 +619,11 @@ struct auth_state { - char *dn; - enum pwexpire pw_expire_type; - void *pw_expire_data; -- -- struct fo_server *srv; - }; - --static struct tevent_req *auth_get_server(struct tevent_req *req); -+static struct tevent_req *auth_connect_send(struct tevent_req *req); - static void auth_get_dn_done(struct tevent_req *subreq); - static void auth_do_bind(struct tevent_req *req); --static void auth_resolve_done(struct tevent_req *subreq); - static void auth_connect_done(struct tevent_req *subreq); - static void auth_bind_user_done(struct tevent_req *subreq); - -@@ -659,7 +656,6 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, - state->ctx = ctx; - state->username = username; - state->authtok = authtok; -- state->srv = NULL; - if (try_chpass_service && ctx->chpass_service != NULL && - ctx->chpass_service->name != NULL) { - state->sdap_service = ctx->chpass_service; -@@ -667,7 +663,7 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx, - state->sdap_service = ctx->service; - } - -- if (!auth_get_server(req)) goto fail; -+ if (!auth_connect_send(req)) goto fail; - - return req; - -@@ -676,75 +672,37 @@ fail: - return NULL; - } - --static struct tevent_req *auth_get_server(struct tevent_req *req) -+static struct tevent_req *auth_connect_send(struct tevent_req *req) - { -- struct tevent_req *next_req; -+ struct tevent_req *subreq; - struct auth_state *state = tevent_req_data(req, - struct auth_state); -- -- /* NOTE: this call may cause service->uri to be refreshed -- * with a new valid server. Do not use service->uri before */ -- next_req = be_resolve_server_send(state, -- state->ev, -- state->ctx->be, -- state->sdap_service->name, -- state->srv == NULL ? true : false); -- if (!next_req) { -- DEBUG(SSSDBG_CRIT_FAILURE, "be_resolve_server_send failed.\n"); -- return NULL; -- } -- -- tevent_req_set_callback(next_req, auth_resolve_done, req); -- return next_req; --} -- --static void auth_resolve_done(struct tevent_req *subreq) --{ -- struct tevent_req *req = tevent_req_callback_data(subreq, -- struct tevent_req); -- struct auth_state *state = tevent_req_data(req, -- struct auth_state); -- int ret; - bool use_tls; - -- ret = be_resolve_server_recv(subreq, state, &state->srv); -- talloc_zfree(subreq); -- if (ret) { -- /* all servers have been tried and none -- * was found good, go offline */ -- tevent_req_error(req, ETIMEDOUT); -- return; -+ /* Check for undocumented debugging feature to disable TLS -+ * for authentication. This should never be used in production -+ * for obvious reasons. -+ */ -+ use_tls = !dp_opt_get_bool(state->ctx->opts->basic, SDAP_DISABLE_AUTH_TLS); -+ if (!use_tls) { -+ sss_log(SSS_LOG_ALERT, "LDAP authentication being performed over " -+ "insecure connection. This should be done " -+ "for debugging purposes only."); - } - -- /* Determine whether we need to use TLS */ -- if (sdap_is_secure_uri(state->ctx->service->uri)) { -- DEBUG(SSSDBG_TRACE_INTERNAL, -- "[%s] is a secure channel. No need to run START_TLS\n", -- state->ctx->service->uri); -- use_tls = false; -- } else { -+ subreq = sdap_cli_connect_send(state, state->ev, state->ctx->opts, -+ state->ctx->be, -+ state->sdap_service, false, -+ use_tls ? CON_TLS_ON : CON_TLS_OFF, false); - -- /* Check for undocumented debugging feature to disable TLS -- * for authentication. This should never be used in production -- * for obvious reasons. -- */ -- use_tls = !dp_opt_get_bool(state->ctx->opts->basic, SDAP_DISABLE_AUTH_TLS); -- if (!use_tls) { -- sss_log(SSS_LOG_ALERT, "LDAP authentication being performed over " -- "insecure connection. This should be done " -- "for debugging purposes only."); -- } -- } -- -- subreq = sdap_connect_send(state, state->ev, state->ctx->opts, -- state->sdap_service->uri, -- state->sdap_service->sockaddr, use_tls); -- if (!subreq) { -+ if (subreq == NULL) { - tevent_req_error(req, ENOMEM); -- return; -+ return NULL; - } - - tevent_req_set_callback(subreq, auth_connect_done, req); -+ -+ return subreq; - } - - static void auth_connect_done(struct tevent_req *subreq) -@@ -755,35 +713,13 @@ static void auth_connect_done(struct tevent_req *subreq) - struct auth_state); - int ret; - -- ret = sdap_connect_recv(subreq, state, &state->sh); -+ ret = sdap_cli_connect_recv(subreq, state, NULL, &state->sh, NULL); - talloc_zfree(subreq); -- if (ret) { -- if (state->srv) { -- /* mark this server as bad if connection failed */ -- be_fo_set_port_status(state->ctx->be, -- state->sdap_service->name, -- state->srv, PORT_NOT_WORKING); -- } -- -- if (auth_get_server(req) == NULL) { -+ if (ret != EOK) { -+ if (auth_connect_send(req) == NULL) { - tevent_req_error(req, ENOMEM); - } - return; -- } else if (state->srv) { -- be_fo_set_port_status(state->ctx->be, state->sdap_service->name, -- state->srv, PORT_WORKING); -- } -- -- /* In case the ID provider is set to proxy, this might be the first -- * LDAP operation at all, so we need to set the connection status -- */ -- if (state->sh->connected == false) { -- ret = sdap_set_connected(state->sh, state->ev); -- if (ret) { -- DEBUG(SSSDBG_OP_FAILURE, "Cannot set connected status\n"); -- tevent_req_error(req, ret); -- return; -- } - } - - ret = get_user_dn(state, state->ctx->be->domain, -@@ -870,7 +806,7 @@ static void auth_bind_user_done(struct tevent_req *subreq) - break; - case ETIMEDOUT: - case ERR_NETWORK_IO: -- if (auth_get_server(req) == NULL) { -+ if (auth_connect_send(req) == NULL) { - tevent_req_error(req, ENOMEM); - } - return; --- -2.13.5 - diff --git a/SOURCES/0021-MAN-Give-information-regarding-priority-of-ldap-look.patch b/SOURCES/0021-MAN-Give-information-regarding-priority-of-ldap-look.patch new file mode 100644 index 0000000..56e7687 --- /dev/null +++ b/SOURCES/0021-MAN-Give-information-regarding-priority-of-ldap-look.patch @@ -0,0 +1,49 @@ +From 7689f3c8b4661c16a019c4410b1557f6ae4229aa Mon Sep 17 00:00:00 2001 +From: amitkumar50 +Date: Fri, 15 Jun 2018 10:45:38 +0530 +Subject: [PATCH] MAN: Give information regarding priority of ldap lookup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This PR provides information about priority of lookup +similar to as provided by function select_principal_from_keytab(). + +Resolves: https://pagure.io/SSSD/sssd/issue/3475 + +Reviewed-by: Pavel Březina +(cherry picked from commit c5ef56b4f9ffb361742edae36b261a4ffd0e75ae) + +DOWNSTREAM: +Resolves: rhbz#1450778 - Full information regarding priority of lookup of principal in keytab not in man page +--- + src/man/sssd-ldap.5.xml | 13 ++++++++++++- + 1 file changed, 12 insertions(+), 1 deletion(-) + +diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml +index f7617670c8b0fe1a5922c1a811b94e25bacecbfe..3145f0730341bf40159277ef2ae23be601154a89 100644 +--- a/src/man/sssd-ldap.5.xml ++++ b/src/man/sssd-ldap.5.xml +@@ -1778,7 +1778,18 @@ + principal used for authentication to the directory. + This option can either contain the full principal (for + example host/myhost@EXAMPLE.COM) or just the principal name +- (for example host/myhost). ++ (for example host/myhost). By default, the value is not set ++ and the following principals are used: ++ ++hostname@REALM ++netbiosname$@REALM ++host/hostname@REALM ++*$@REALM ++host/*@REALM ++host/* ++ ++ If none of them are found, the first principal in keytab is ++ returned. + + + Default: host/hostname@REALM +-- +2.17.1 + diff --git a/SOURCES/0022-AD-LDAP-Do-not-misuse-the-ignore_mark_offline-to-che.patch b/SOURCES/0022-AD-LDAP-Do-not-misuse-the-ignore_mark_offline-to-che.patch new file mode 100644 index 0000000..2806c55 --- /dev/null +++ b/SOURCES/0022-AD-LDAP-Do-not-misuse-the-ignore_mark_offline-to-che.patch @@ -0,0 +1,82 @@ +From 7b8ed13c2bac164fdc49227d1b51364bdf907a98 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 19 Jun 2018 16:09:30 +0200 +Subject: [PATCH] AD/LDAP: Do not misuse the ignore_mark_offline to check if a + connection needs to be checked for POSIX attribute presence +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The logic behind deciding whether to check if a server contains any +POSIX attributes used the ignore_mark_offline flag. This was OK for some +time, because this flag was only set for to true for Global Catalog +connections, which are those that we need to check. + +However, in recent releases, the flag was also set for any connection +towards a trusted domain. This had the unintended effect that any +lookup, LDAP or GC against a trusted domain ran the wide POSIX presence +check. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3754 + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit 5e1641b104f159f9fa47c3008d84119dfd5ab226) + +DOWNSTREAM: +Resolves: rhbz#1583725 - SSSD AD uses LDAP filter to detect POSIX attributes stored in AD GC also for regular AD DC queries +--- + src/providers/ad/ad_common.c | 2 ++ + src/providers/ldap/ldap_common.c | 2 +- + src/providers/ldap/ldap_common.h | 2 ++ + 3 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c +index 8caaba6c0d06cfe83d9741536192d662fc936273..feeb5d09643a02b99be1a387b41842a034a323b8 100644 +--- a/src/providers/ad/ad_common.c ++++ b/src/providers/ad/ad_common.c +@@ -1408,6 +1408,7 @@ ad_gc_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx, + clist[cindex] = ad_ctx->gc_ctx; + clist[cindex]->ignore_mark_offline = true; + clist[cindex]->no_mpg_user_fallback = true; ++ clist[cindex]->check_posix_attrs = true; + cindex++; + } + +@@ -1454,6 +1455,7 @@ ad_user_conn_list(TALLOC_CTX *mem_ctx, + && IS_SUBDOMAIN(dom)) { + clist[cindex] = ad_ctx->gc_ctx; + clist[cindex]->ignore_mark_offline = true; ++ clist[cindex]->check_posix_attrs = true; + cindex++; + } + +diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c +index 15377ee1f062c0167aabee30ef0757ebe7271682..a0a9b8523310b2551ee992f8d0c2e369dafaa56d 100644 +--- a/src/providers/ldap/ldap_common.c ++++ b/src/providers/ldap/ldap_common.c +@@ -893,7 +893,7 @@ bool should_run_posix_check(struct sdap_id_ctx *ctx, + if (use_id_mapping == false && + posix_request == true && + ctx->opts->schema_type == SDAP_SCHEMA_AD && +- conn->ignore_mark_offline == true && ++ conn->check_posix_attrs == true && + ctx->srv_opts && + ctx->srv_opts->posix_checked == false) { + return true; +diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h +index 3cefdd0bfb0e96b5a7f904fe753dfc457b2a45c2..3de3568cb28c258c00f9b522c0b9120adca81d81 100644 +--- a/src/providers/ldap/ldap_common.h ++++ b/src/providers/ldap/ldap_common.h +@@ -59,6 +59,8 @@ struct sdap_id_conn_ctx { + bool ignore_mark_offline; + /* do not fall back to user lookups for mpg domains on this connection */ + bool no_mpg_user_fallback; ++ /* check if this connection contains POSIX attributes */ ++ bool check_posix_attrs; + }; + + struct sdap_id_ctx { +-- +2.17.1 + diff --git a/SOURCES/0022-sss_client-create-nss_common.h.patch b/SOURCES/0022-sss_client-create-nss_common.h.patch deleted file mode 100644 index f695b2b..0000000 --- a/SOURCES/0022-sss_client-create-nss_common.h.patch +++ /dev/null @@ -1,143 +0,0 @@ -From 22c5575eb442f20230081cc06528d685397c8914 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 29 Sep 2017 21:38:54 +0200 -Subject: [PATCH 22/31] sss_client: create nss_common.h - -This patch makes sss_nss_getpw_readrep() and sss_nss_getgr_readrep() -calls which parse SSSD's replies for user and group requests available -to other components. - -Related to https://pagure.io/SSSD/sssd/issue/2478 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 7449b236523409cc8766fb957d6cba051fdfb483) ---- - Makefile.am | 1 + - src/sss_client/nss_common.h | 43 +++++++++++++++++++++++++++++++++++++++++++ - src/sss_client/nss_group.c | 10 +++------- - src/sss_client/nss_passwd.c | 11 +++-------- - 4 files changed, 50 insertions(+), 15 deletions(-) - create mode 100644 src/sss_client/nss_common.h - -diff --git a/Makefile.am b/Makefile.am -index 5483375167d99568e8313c9a0488900419be6ec3..dc2f4b1857ce5bd376544488348731be29b6b293 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -3623,6 +3623,7 @@ libnss_sss_la_SOURCES = \ - src/sss_client/nss_services.c \ - src/sss_client/sss_cli.h \ - src/sss_client/nss_compat.h \ -+ src/sss_client/nss_common.h \ - src/sss_client/nss_mc_common.c \ - src/util/io.c \ - src/util/murmurhash3.c \ -diff --git a/src/sss_client/nss_common.h b/src/sss_client/nss_common.h -new file mode 100644 -index 0000000000000000000000000000000000000000..e83b4f95a3136b5aa711194a4d37389eebfb607a ---- /dev/null -+++ b/src/sss_client/nss_common.h -@@ -0,0 +1,43 @@ -+/* -+ SSSD -+ -+ Common routines for classical and enhanced NSS interface -+ -+ Authors: -+ Sumit Bose -+ -+ Copyright (C) Red Hat, Inc 2007 -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU Lesser General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public License -+ along with this program. If not, see . -+*/ -+ -+ -+ -+struct sss_nss_pw_rep { -+ struct passwd *result; -+ char *buffer; -+ size_t buflen; -+}; -+ -+int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr, -+ uint8_t *buf, size_t *len); -+ -+struct sss_nss_gr_rep { -+ struct group *result; -+ char *buffer; -+ size_t buflen; -+}; -+ -+int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr, -+ uint8_t *buf, size_t *len); -diff --git a/src/sss_client/nss_group.c b/src/sss_client/nss_group.c -index 0e686af43aeb84a5938315e3922e9fcf2fef4e83..42fba6242d23fc1d52cfd7be10cf10383010f091 100644 ---- a/src/sss_client/nss_group.c -+++ b/src/sss_client/nss_group.c -@@ -29,6 +29,7 @@ - #include - #include "sss_cli.h" - #include "nss_mc.h" -+#include "nss_common.h" - - static struct sss_nss_getgrent_data { - size_t len; -@@ -190,14 +191,9 @@ done: - * - * FIXME: do we need to pad so that each result is 32 bit aligned ? - */ --struct sss_nss_gr_rep { -- struct group *result; -- char *buffer; -- size_t buflen; --}; - --static int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr, -- uint8_t *buf, size_t *len) -+int sss_nss_getgr_readrep(struct sss_nss_gr_rep *pr, -+ uint8_t *buf, size_t *len) - { - errno_t ret; - size_t i, l, slen, ptmem, pad, dlen, glen; -diff --git a/src/sss_client/nss_passwd.c b/src/sss_client/nss_passwd.c -index c43f9bc50f43599b541e97f5a5aa60de036a5cdf..61e2a567e684fbc7664b5d425e81cfa28a98e845 100644 ---- a/src/sss_client/nss_passwd.c -+++ b/src/sss_client/nss_passwd.c -@@ -28,6 +28,7 @@ - #include - #include "sss_cli.h" - #include "nss_mc.h" -+#include "nss_common.h" - - static struct sss_nss_getpwent_data { - size_t len; -@@ -63,14 +64,8 @@ static void sss_nss_getpwent_data_clean(void) { - * 8-X: sequence of 5, 0 terminated, strings (name, passwd, gecos, dir, shell) - */ - --struct sss_nss_pw_rep { -- struct passwd *result; -- char *buffer; -- size_t buflen; --}; -- --static int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr, -- uint8_t *buf, size_t *len) -+int sss_nss_getpw_readrep(struct sss_nss_pw_rep *pr, -+ uint8_t *buf, size_t *len) - { - errno_t ret; - size_t i, slen, dlen; --- -2.13.6 - diff --git a/SOURCES/0023-AD-expose-the-helper-function-to-format-the-site-DNS.patch b/SOURCES/0023-AD-expose-the-helper-function-to-format-the-site-DNS.patch new file mode 100644 index 0000000..4208977 --- /dev/null +++ b/SOURCES/0023-AD-expose-the-helper-function-to-format-the-site-DNS.patch @@ -0,0 +1,91 @@ +From 09fd8246f25dbfb80db638a0dd8f2fe4c1fba957 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 25 Jun 2018 13:03:38 +0200 +Subject: [PATCH] AD: expose the helper function to format the site DNS query + +This function will be used later in the patchset. Instead of exposing +the format constant, expose the function that builds the DNS query for +site discovery. + +Related: +https://pagure.io/SSSD/sssd/issue/3291 + +Reviewed-by: Sumit Bose +(cherry picked from commit 29bbc8e017f2d9b98667890a9b7056128a93e572) + +DOWNSTREAM: +Resolves: rhbz#1416528 - sssd in cross realm trust configuration should be able to use AD KDCs from a client site defined in sssd.conf or a snippet +--- + src/providers/ad/ad_srv.c | 21 +++++++++++++++------ + src/providers/ad/ad_srv.h | 4 ++++ + 2 files changed, 19 insertions(+), 6 deletions(-) + +diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c +index 4fa1668605e131b2e31802b1401f49fc6e00a23b..5fd25f60e8bf38c3952823601593515b6c703284 100644 +--- a/src/providers/ad/ad_srv.c ++++ b/src/providers/ad/ad_srv.c +@@ -38,6 +38,13 @@ + + #define AD_SITE_DOMAIN_FMT "%s._sites.%s" + ++char *ad_site_dns_discovery_domain(TALLOC_CTX *mem_ctx, ++ const char *site, ++ const char *domain) ++{ ++ return talloc_asprintf(mem_ctx, AD_SITE_DOMAIN_FMT, site, domain); ++} ++ + static errno_t ad_sort_servers_by_dns(TALLOC_CTX *mem_ctx, + const char *domain, + struct fo_server_info **_srv, +@@ -154,8 +161,8 @@ static struct tevent_req *ad_get_dc_servers_send(TALLOC_CTX *mem_ctx, + DEBUG(SSSDBG_TRACE_FUNC, "Looking up domain controllers in domain " + "%s and site %s\n", discovery_domain, site); + +- domains[0] = talloc_asprintf(state, AD_SITE_DOMAIN_FMT, +- site, discovery_domain); ++ domains[0] = ad_site_dns_discovery_domain(domains, ++ site, discovery_domain); + if (domains[0] == NULL) { + ret = ENOMEM; + goto immediately; +@@ -775,9 +782,10 @@ static void ad_srv_plugin_site_done(struct tevent_req *subreq) + if (strcmp(state->service, "gc") == 0) { + if (state->forest != NULL) { + if (state->site != NULL) { +- primary_domain = talloc_asprintf(state, AD_SITE_DOMAIN_FMT, +- state->site, +- state->forest); ++ primary_domain = ad_site_dns_discovery_domain( ++ state, ++ state->site, ++ state->forest); + if (primary_domain == NULL) { + ret = ENOMEM; + goto done; +@@ -791,7 +799,8 @@ static void ad_srv_plugin_site_done(struct tevent_req *subreq) + } + } else { + if (state->site != NULL) { +- primary_domain = talloc_asprintf(state, AD_SITE_DOMAIN_FMT, ++ primary_domain = ad_site_dns_discovery_domain( ++ state, + state->site, + state->discovery_domain); + if (primary_domain == NULL) { +diff --git a/src/providers/ad/ad_srv.h b/src/providers/ad/ad_srv.h +index fddef686762e57bb95d648247131d39a797aa516..e553d594d77ad99f806af9634c2817754a80d4f5 100644 +--- a/src/providers/ad/ad_srv.h ++++ b/src/providers/ad/ad_srv.h +@@ -49,4 +49,8 @@ errno_t ad_srv_plugin_recv(TALLOC_CTX *mem_ctx, + struct fo_server_info **_backup_servers, + size_t *_num_backup_servers); + ++char *ad_site_dns_discovery_domain(TALLOC_CTX *mem_ctx, ++ const char *site, ++ const char *domain); ++ + #endif /* __AD_SRV_H__ */ +-- +2.17.1 + diff --git a/SOURCES/0023-nss-idmap-add-nss-like-calls-with-timeout-and-flags.patch b/SOURCES/0023-nss-idmap-add-nss-like-calls-with-timeout-and-flags.patch deleted file mode 100644 index d6f9b89..0000000 --- a/SOURCES/0023-nss-idmap-add-nss-like-calls-with-timeout-and-flags.patch +++ /dev/null @@ -1,901 +0,0 @@ -From 15d7f1aeb541615314b914b6be1149f6e289d3e2 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 29 Sep 2017 16:16:01 +0200 -Subject: [PATCH 23/31] nss-idmap: add nss like calls with timeout and flags - -This patch adds new calls to libsss_nss_idmap to get NSS like user and -group information directly from SSSD without using the system's NSS -interfaces. - -Additionally a timeout and a flags options are added which are not -available for system's NSS. - -Related to https://pagure.io/SSSD/sssd/issue/2478 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 5e6622722e84d594298a8324f3685a1bda2b5868) ---- - Makefile.am | 22 +- - configure.ac | 13 + - src/sss_client/common.c | 9 +- - src/sss_client/common_private.h | 41 +++ - src/sss_client/idmap/common_ex.c | 105 +++++++ - src/sss_client/idmap/sss_nss_ex.c | 402 +++++++++++++++++++++++++++ - src/sss_client/idmap/sss_nss_idmap.exports | 10 + - src/sss_client/idmap/sss_nss_idmap.h | 135 +++++++++ - src/sss_client/idmap/sss_nss_idmap_private.h | 30 ++ - 9 files changed, 757 insertions(+), 10 deletions(-) - create mode 100644 src/sss_client/common_private.h - create mode 100644 src/sss_client/idmap/common_ex.c - create mode 100644 src/sss_client/idmap/sss_nss_ex.c - create mode 100644 src/sss_client/idmap/sss_nss_idmap_private.h - -diff --git a/Makefile.am b/Makefile.am -index dc2f4b1857ce5bd376544488348731be29b6b293..dd25d1f7ea1be66388aa1b393bac290c4d7501a2 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1159,13 +1159,28 @@ pkgconfig_DATA += src/sss_client/idmap/sss_nss_idmap.pc - libsss_nss_idmap_la_DEPENDENCIES = src/sss_client/idmap/sss_nss_idmap.exports - libsss_nss_idmap_la_SOURCES = \ - src/sss_client/idmap/sss_nss_idmap.c \ -+ src/sss_client/idmap/sss_nss_ex.c \ -+ src/sss_client/idmap/sss_nss_idmap_private.h \ - src/sss_client/common.c \ -- src/util/strtonum.c -+ src/sss_client/idmap/common_ex.c \ -+ src/sss_client/nss_mc_passwd.c \ -+ src/sss_client/nss_passwd.c \ -+ src/sss_client/nss_mc_group.c \ -+ src/sss_client/nss_group.c \ -+ src/sss_client/nss_mc_initgr.c \ -+ src/sss_client/nss_mc_common.c \ -+ src/util/strtonum.c \ -+ src/util/murmurhash3.c \ -+ src/util/io.c \ -+ $(NULL) - libsss_nss_idmap_la_LIBADD = \ -- $(CLIENT_LIBS) -+ $(LIBCLOCK_GETTIME) \ -+ $(CLIENT_LIBS) \ -+ -lpthread \ -+ $(NULL) - libsss_nss_idmap_la_LDFLAGS = \ - -Wl,--version-script,$(srcdir)/src/sss_client/idmap/sss_nss_idmap.exports \ -- -version-info 3:0:3 -+ -version-info 4:0:4 - - dist_noinst_DATA += src/sss_client/idmap/sss_nss_idmap.exports - -@@ -3624,6 +3639,7 @@ libnss_sss_la_SOURCES = \ - src/sss_client/sss_cli.h \ - src/sss_client/nss_compat.h \ - src/sss_client/nss_common.h \ -+ src/sss_client/common_private.h \ - src/sss_client/nss_mc_common.c \ - src/util/io.c \ - src/util/murmurhash3.c \ -diff --git a/configure.ac b/configure.ac -index 7037927b5f7045b29d3774c85758e00e35e6def6..7e699d33e342c70d210d3f320c8a29a99e0c78a6 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -75,6 +75,19 @@ AC_SEARCH_LIBS([timer_create], [rt posix4], - AC_SUBST([LIBADD_TIMER]) - LIBS=$SAVE_LIBS - -+# Check library for the clock_gettime function -+SAVE_LIBS=$LIBS -+LIBS= -+LIBCLOCK_GETTIME= -+AC_SEARCH_LIBS([clock_gettime], [rt posix4], -+ [AC_DEFINE([HAVE_LIBRT], [1], -+ [Define if you have the librt library or equivalent.]) -+ LIBCLOCK_GETTIME="$LIBS"], -+ [AC_MSG_ERROR([unable to find library for the clock_gettime() function])]) -+ -+AC_SUBST([LIBCLOCK_GETTIME]) -+LIBS=$SAVE_LIBS -+ - # Check for presence of modern functions for setting file timestamps - AC_CHECK_FUNCS([ utimensat \ - futimens ]) -diff --git a/src/sss_client/common.c b/src/sss_client/common.c -index e5e0cbf854e4c977c03f9b1ca1ac90bfd8cbdb77..40252a35281dc4e94c712c3e7f8253af8b19b35a 100644 ---- a/src/sss_client/common.c -+++ b/src/sss_client/common.c -@@ -43,6 +43,7 @@ - #include - #define _(STRING) dgettext (PACKAGE, STRING) - #include "sss_cli.h" -+#include "common_private.h" - - #if HAVE_PTHREAD - #include -@@ -1113,13 +1114,7 @@ errno_t sss_strnlen(const char *str, size_t maxlen, size_t *len) - #if HAVE_PTHREAD - typedef void (*sss_mutex_init)(void); - --struct sss_mutex { -- pthread_mutex_t mtx; -- -- int old_cancel_state; --}; -- --static struct sss_mutex sss_nss_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER }; -+struct sss_mutex sss_nss_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER }; - - static struct sss_mutex sss_pam_mtx = { .mtx = PTHREAD_MUTEX_INITIALIZER }; - -diff --git a/src/sss_client/common_private.h b/src/sss_client/common_private.h -new file mode 100644 -index 0000000000000000000000000000000000000000..a98d2c062caeecdbab02ecdaa6ae44d688a791bb ---- /dev/null -+++ b/src/sss_client/common_private.h -@@ -0,0 +1,41 @@ -+/* -+ SSSD -+ -+ SSS client - private calls -+ -+ Authors: -+ Sumit Bose -+ -+ Copyright (C) 2017 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 . -+*/ -+ -+#ifndef COMMON_PRIVATE_H_ -+#define COMMON_PRIVATE_H_ -+ -+#include "config.h" -+ -+#if HAVE_PTHREAD -+#include -+ -+struct sss_mutex { -+ pthread_mutex_t mtx; -+ -+ int old_cancel_state; -+}; -+ -+#endif /* HAVE_PTHREAD */ -+ -+#endif /* COMMON_PRIVATE_H_ */ -diff --git a/src/sss_client/idmap/common_ex.c b/src/sss_client/idmap/common_ex.c -new file mode 100644 -index 0000000000000000000000000000000000000000..5efe9fabed7896ce674615472dbb256c4eae2144 ---- /dev/null -+++ b/src/sss_client/idmap/common_ex.c -@@ -0,0 +1,105 @@ -+/* -+ Authors: -+ Sumit Bose -+ -+ Copyright (C) 2017 Red Hat -+ -+ SSSD's enhanced NSS API -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+ -+#include -+#include -+ -+#include "sss_cli.h" -+#include "common_private.h" -+ -+extern struct sss_mutex sss_nss_mtx; -+ -+#define SEC_FROM_MSEC(ms) ((ms) / 1000) -+#define NSEC_FROM_MSEC(ms) (((ms) % 1000) * 1000 * 1000) -+ -+/* adopted from timersub() defined in /usr/include/sys/time.h */ -+#define TIMESPECSUB(a, b, result) \ -+ do { \ -+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ -+ (result)->tv_nsec = (a)->tv_nsec - (b)->tv_nsec; \ -+ if ((result)->tv_nsec < 0) { \ -+ --(result)->tv_sec; \ -+ (result)->tv_nsec += 1000000000; \ -+ } \ -+ } while (0) -+ -+#define TIMESPEC_TO_MS(ts) ( ((ts)->tv_sec * 1000) \ -+ + ((ts)->tv_nsec) / (1000 * 1000) ) -+ -+static int sss_mt_timedlock(struct sss_mutex *m, struct timespec *endtime) -+{ -+ int ret; -+ -+ ret = pthread_mutex_timedlock(&m->mtx, endtime); -+ if (ret != 0) { -+ return ret; -+ } -+ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &m->old_cancel_state); -+ -+ return 0; -+} -+ -+int sss_nss_timedlock(unsigned int timeout_ms, int *time_left_ms) -+{ -+ int ret; -+ int left; -+ struct timespec starttime; -+ struct timespec endtime; -+ struct timespec diff; -+ -+ /* make sure there is no overrun when calculating the time left */ -+ if (timeout_ms > INT_MAX) { -+ timeout_ms = INT_MAX; -+ } -+ -+ ret = clock_gettime(CLOCK_REALTIME, &starttime); -+ if (ret != 0) { -+ return ret; -+ } -+ endtime.tv_sec = starttime.tv_sec + SEC_FROM_MSEC(timeout_ms); -+ endtime.tv_nsec = starttime.tv_nsec + NSEC_FROM_MSEC(timeout_ms); -+ -+ ret = sss_mt_timedlock(&sss_nss_mtx, &endtime); -+ -+ if (ret == 0) { -+ ret = clock_gettime(CLOCK_REALTIME, &endtime); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if (timeout_ms == 0) { -+ *time_left_ms = 0; -+ } else { -+ TIMESPECSUB(&endtime, &starttime, &diff); -+ left = timeout_ms - TIMESPEC_TO_MS(&diff); -+ if (left <= 0) { -+ return EIO; -+ } else if (left > SSS_CLI_SOCKET_TIMEOUT) { -+ *time_left_ms = SSS_CLI_SOCKET_TIMEOUT; -+ } else { -+ *time_left_ms = left; -+ } -+ } -+ } -+ -+ return ret; -+} -diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c -new file mode 100644 -index 0000000000000000000000000000000000000000..582d1373ec35305cf128e04fd3d705457d304789 ---- /dev/null -+++ b/src/sss_client/idmap/sss_nss_ex.c -@@ -0,0 +1,402 @@ -+/* -+ SSSD -+ -+ Extended NSS Responder Interface -+ -+ Authors: -+ Sumit Bose -+ -+ Copyright (C) 2017 Red Hat -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see . -+*/ -+#include -+#include -+ -+#include /* for MIN() */ -+ -+#include "sss_client/sss_cli.h" -+#include "sss_client/nss_mc.h" -+#include "sss_client/nss_common.h" -+#include "sss_client/idmap/sss_nss_idmap.h" -+#include "sss_client/idmap/sss_nss_idmap_private.h" -+ -+#ifndef discard_const -+#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) -+#endif -+ -+struct sss_nss_initgr_rep { -+ gid_t *groups; -+ long int *ngroups; -+ long int *start; -+}; -+ -+struct nss_input { -+ union { -+ const char *name; -+ uid_t uid; -+ gid_t gid; -+ } input; -+ struct sss_cli_req_data rd; -+ enum sss_cli_command cmd; -+ union { -+ struct sss_nss_pw_rep pwrep; -+ struct sss_nss_gr_rep grrep; -+ struct sss_nss_initgr_rep initgrrep; -+ } result; -+}; -+ -+errno_t sss_nss_mc_get(struct nss_input *inp) -+{ -+ switch(inp->cmd) { -+ case SSS_NSS_GETPWNAM: -+ return sss_nss_mc_getpwnam(inp->input.name, (inp->rd.len - 1), -+ inp->result.pwrep.result, -+ inp->result.pwrep.buffer, -+ inp->result.pwrep.buflen); -+ break; -+ case SSS_NSS_GETPWUID: -+ return sss_nss_mc_getpwuid(inp->input.uid, -+ inp->result.pwrep.result, -+ inp->result.pwrep.buffer, -+ inp->result.pwrep.buflen); -+ break; -+ case SSS_NSS_GETGRNAM: -+ return sss_nss_mc_getgrnam(inp->input.name, (inp->rd.len - 1), -+ inp->result.grrep.result, -+ inp->result.grrep.buffer, -+ inp->result.grrep.buflen); -+ break; -+ case SSS_NSS_GETGRGID: -+ return sss_nss_mc_getgrgid(inp->input.gid, -+ inp->result.grrep.result, -+ inp->result.grrep.buffer, -+ inp->result.grrep.buflen); -+ break; -+ case SSS_NSS_INITGR: -+ return sss_nss_mc_initgroups_dyn(inp->input.name, (inp->rd.len - 1), -+ -1 /* currently ignored */, -+ inp->result.initgrrep.start, -+ inp->result.initgrrep.ngroups, -+ &(inp->result.initgrrep.groups), -+ *(inp->result.initgrrep.ngroups)); -+ break; -+ default: -+ return EINVAL; -+ } -+} -+ -+int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout) -+{ -+ uint8_t *repbuf = NULL; -+ size_t replen; -+ size_t len; -+ uint32_t num_results; -+ int ret; -+ int time_left; -+ int errnop; -+ size_t c; -+ gid_t *new_groups; -+ size_t idx; -+ -+ ret = sss_nss_mc_get(inp); -+ switch (ret) { -+ case 0: -+ return 0; -+ case ERANGE: -+ return ERANGE; -+ case ENOENT: -+ /* fall through, we need to actively ask the parent -+ * if no entry is found */ -+ break; -+ default: -+ /* if using the mmaped cache failed, -+ * fall back to socket based comms */ -+ break; -+ } -+ -+ sss_nss_timedlock(timeout, &time_left); -+ -+ /* previous thread might already initialize entry in mmap cache */ -+ ret = sss_nss_mc_get(inp); -+ switch (ret) { -+ case 0: -+ ret = 0; -+ goto out; -+ case ERANGE: -+ ret = ERANGE; -+ goto out; -+ case ENOENT: -+ /* fall through, we need to actively ask the parent -+ * if no entry is found */ -+ break; -+ default: -+ /* if using the mmaped cache failed, -+ * fall back to socket based comms */ -+ break; -+ } -+ -+ ret = sss_nss_make_request_timeout(inp->cmd, &inp->rd, time_left, -+ &repbuf, &replen, &errnop); -+ if (ret != NSS_STATUS_SUCCESS) { -+ ret = errnop != 0 ? errnop : EIO; -+ goto out; -+ } -+ -+ /* Get number of results from repbuf. */ -+ SAFEALIGN_COPY_UINT32(&num_results, repbuf, NULL); -+ -+ /* no results if not found */ -+ if (num_results == 0) { -+ ret = ENOENT; -+ goto out; -+ } -+ -+ if (inp->cmd == SSS_NSS_INITGR) { -+ if ((*(inp->result.initgrrep.ngroups) - *(inp->result.initgrrep.start)) -+ < num_results) { -+ new_groups = realloc(inp->result.initgrrep.groups, -+ (num_results + *(inp->result.initgrrep.start)) -+ * sizeof(gid_t)); -+ if (new_groups == NULL) { -+ ret = ENOMEM; -+ goto out; -+ } -+ -+ inp->result.initgrrep.groups = new_groups; -+ } -+ *(inp->result.initgrrep.ngroups) = num_results -+ + *(inp->result.initgrrep.start); -+ -+ idx = 2 * sizeof(uint32_t); -+ for (c = 0; c < num_results; c++) { -+ SAFEALIGN_COPY_UINT32( -+ &(inp->result.initgrrep.groups[*(inp->result.initgrrep.start)]), -+ repbuf + idx, &idx); -+ *(inp->result.initgrrep.start) += 1; -+ } -+ -+ ret = 0; -+ goto out; -+ } -+ -+ /* only 1 result is accepted for this function */ -+ if (num_results != 1) { -+ ret = EBADMSG; -+ goto out; -+ } -+ -+ len = replen - 8; -+ if (inp->cmd == SSS_NSS_GETPWNAM || inp->cmd == SSS_NSS_GETPWUID) { -+ ret = sss_nss_getpw_readrep(&(inp->result.pwrep), repbuf+8, &len); -+ } else if (inp->cmd == SSS_NSS_GETGRNAM || inp->cmd == SSS_NSS_GETGRGID) { -+ ret = sss_nss_getgr_readrep(&(inp->result.grrep), repbuf+8, &len); -+ } else { -+ ret = EINVAL; -+ goto out; -+ } -+ if (ret) { -+ goto out; -+ } -+ -+ if (len == 0) { -+ /* no extra data */ -+ ret = 0; -+ goto out; -+ } -+ -+out: -+ free(repbuf); -+ -+ sss_nss_unlock(); -+ return ret; -+} -+ -+int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd, -+ char *buffer, size_t buflen, -+ struct passwd **result, -+ uint32_t flags, unsigned int timeout) -+{ -+ int ret; -+ struct nss_input inp = { -+ .input.name = name, -+ .cmd = SSS_NSS_GETPWNAM, -+ .rd.data = name, -+ .result.pwrep.result = pwd, -+ .result.pwrep.buffer = buffer, -+ .result.pwrep.buflen = buflen}; -+ -+ if (buffer == NULL || buflen == 0) { -+ return ERANGE; -+ } -+ -+ ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len); -+ if (ret != 0) { -+ return EINVAL; -+ } -+ inp.rd.len++; -+ -+ *result = NULL; -+ -+ ret = sss_get_ex(&inp, flags, timeout); -+ if (ret == 0) { -+ *result = inp.result.pwrep.result; -+ } -+ return ret; -+} -+ -+int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd, -+ char *buffer, size_t buflen, -+ struct passwd **result, -+ uint32_t flags, unsigned int timeout) -+{ -+ int ret; -+ uint32_t user_uid = uid; -+ struct nss_input inp = { -+ .input.uid = uid, -+ .cmd = SSS_NSS_GETPWUID, -+ .rd.len = sizeof(uint32_t), -+ .rd.data = &user_uid, -+ .result.pwrep.result = pwd, -+ .result.pwrep.buffer = buffer, -+ .result.pwrep.buflen = buflen}; -+ -+ if (buffer == NULL || buflen == 0) { -+ return ERANGE; -+ } -+ -+ *result = NULL; -+ -+ ret = sss_get_ex(&inp, flags, timeout); -+ if (ret == 0) { -+ *result = inp.result.pwrep.result; -+ } -+ return ret; -+} -+ -+int sss_nss_getgrnam_timeout(const char *name, struct group *grp, -+ char *buffer, size_t buflen, struct group **result, -+ uint32_t flags, unsigned int timeout) -+{ -+ int ret; -+ struct nss_input inp = { -+ .input.name = name, -+ .cmd = SSS_NSS_GETGRNAM, -+ .rd.data = name, -+ .result.grrep.result = grp, -+ .result.grrep.buffer = buffer, -+ .result.grrep.buflen = buflen}; -+ -+ if (buffer == NULL || buflen == 0) { -+ return ERANGE; -+ } -+ -+ ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len); -+ if (ret != 0) { -+ return EINVAL; -+ } -+ inp.rd.len++; -+ -+ *result = NULL; -+ -+ ret = sss_get_ex(&inp, flags, timeout); -+ if (ret == 0) { -+ *result = inp.result.grrep.result; -+ } -+ return ret; -+} -+ -+int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp, -+ char *buffer, size_t buflen, struct group **result, -+ uint32_t flags, unsigned int timeout) -+{ -+ int ret; -+ uint32_t group_gid = gid; -+ struct nss_input inp = { -+ .input.gid = gid, -+ .cmd = SSS_NSS_GETGRGID, -+ .rd.len = sizeof(uint32_t), -+ .rd.data = &group_gid, -+ .result.grrep.result = grp, -+ .result.grrep.buffer = buffer, -+ .result.grrep.buflen = buflen}; -+ -+ if (buffer == NULL || buflen == 0) { -+ return ERANGE; -+ } -+ -+ *result = NULL; -+ -+ ret = sss_get_ex(&inp, flags, timeout); -+ if (ret == 0) { -+ *result = inp.result.grrep.result; -+ } -+ return ret; -+} -+ -+int sss_nss_getgrouplist_timeout(const char *name, gid_t group, -+ gid_t *groups, int *ngroups, -+ uint32_t flags, unsigned int timeout) -+{ -+ int ret; -+ gid_t *new_groups; -+ long int new_ngroups; -+ long int start = 1; -+ struct nss_input inp = { -+ .input.name = name, -+ .cmd = SSS_NSS_INITGR, -+ .rd.data = name}; -+ -+ if (groups == NULL || ngroups == NULL || *ngroups == 0) { -+ return EINVAL; -+ } -+ -+ ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len); -+ if (ret != 0) { -+ return ret; -+ } -+ inp.rd.len++; -+ -+ new_ngroups = MAX(1, *ngroups); -+ new_groups = malloc(new_ngroups * sizeof(gid_t)); -+ if (new_groups == NULL) { -+ free(discard_const(inp.rd.data)); -+ return ENOMEM; -+ } -+ new_groups[0] = group; -+ -+ inp.result.initgrrep.groups = new_groups, -+ inp.result.initgrrep.ngroups = &new_ngroups; -+ inp.result.initgrrep.start = &start; -+ -+ -+ ret = sss_get_ex(&inp, flags, timeout); -+ free(discard_const(inp.rd.data)); -+ if (ret != 0) { -+ free(new_groups); -+ return ret; -+ } -+ -+ memcpy(groups, new_groups, MIN(*ngroups, start) * sizeof(gid_t)); -+ free(new_groups); -+ -+ if (start > *ngroups) { -+ ret = ERANGE; -+ } else { -+ ret = 0; -+ } -+ *ngroups = start; -+ -+ return ret; -+} -diff --git a/src/sss_client/idmap/sss_nss_idmap.exports b/src/sss_client/idmap/sss_nss_idmap.exports -index 49dac6fc9351b0ca98cd46e83b85ec8ef0075a0d..788d05ecc3bd56fa88e68a98b9c8096cf7140a09 100644 ---- a/src/sss_client/idmap/sss_nss_idmap.exports -+++ b/src/sss_client/idmap/sss_nss_idmap.exports -@@ -31,3 +31,13 @@ SSS_NSS_IDMAP_0.3.0 { - global: - sss_nss_getlistbycert; - } SSS_NSS_IDMAP_0.2.0; -+ -+SSS_NSS_IDMAP_0.4.0 { -+ # public functions -+ global: -+ sss_nss_getpwnam_timeout; -+ sss_nss_getpwuid_timeout; -+ sss_nss_getgrnam_timeout; -+ sss_nss_getgrgid_timeout; -+ sss_nss_getgrouplist_timeout; -+} SSS_NSS_IDMAP_0.3.0; -diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h -index cbf19479ff9ec6e0d6e07e1f7e48a1571e147740..2334b6cb3fb8ef62e4ce3a7187c7affaeaa034e7 100644 ---- a/src/sss_client/idmap/sss_nss_idmap.h -+++ b/src/sss_client/idmap/sss_nss_idmap.h -@@ -26,6 +26,9 @@ - #define SSS_NSS_IDMAP_H_ - - #include -+#include -+#include -+#include - - /** - * Object types -@@ -159,4 +162,136 @@ int sss_nss_getlistbycert(const char *cert, char ***fq_name, - * @param[in] kv_list Key-value list returned by sss_nss_getorigbyname(). - */ - void sss_nss_free_kv(struct sss_nss_kv *kv_list); -+ -+/** -+ * Flags to control the behavior and the results for sss_*_ex() calls -+ */ -+ -+#define SSS_NSS_EX_FLAG_NO_FLAGS 0 -+ -+#ifdef IPA_389DS_PLUGIN_HELPER_CALLS -+ -+/** -+ * @brief Return user information based on the user name -+ * -+ * @param[in] name same as for getpwnam_r(3) -+ * @param[in] pwd same as for getpwnam_r(3) -+ * @param[in] buffer same as for getpwnam_r(3) -+ * @param[in] buflen same as for getpwnam_r(3) -+ * @param[out] result same as for getpwnam_r(3) -+ * @param[in] flags flags to control the behavior and the results of the -+ * call -+ * @param[in] timeout timeout in milliseconds -+ * -+ * @return -+ * - 0: -+ * - ENOENT: no user with the given name found -+ * - ERANGE: Insufficient buffer space supplied -+ * - ETIME: request timed out but was send to SSSD -+ * - ETIMEDOUT: request timed out but was not send to SSSD -+ */ -+int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd, -+ char *buffer, size_t buflen, -+ struct passwd **result, -+ uint32_t flags, unsigned int timeout); -+ -+/** -+ * @brief Return user information based on the user uid -+ * -+ * @param[in] uid same as for getpwuid_r(3) -+ * @param[in] pwd same as for getpwuid_r(3) -+ * @param[in] buffer same as for getpwuid_r(3) -+ * @param[in] buflen same as for getpwuid_r(3) -+ * @param[out] result same as for getpwuid_r(3) -+ * @param[in] flags flags to control the behavior and the results of the -+ * call -+ * @param[in] timeout timeout in milliseconds -+ * -+ * @return -+ * - 0: -+ * - ENOENT: no user with the given uid found -+ * - ERANGE: Insufficient buffer space supplied -+ * - ETIME: request timed out but was send to SSSD -+ * - ETIMEDOUT: request timed out but was not send to SSSD -+ */ -+int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd, -+ char *buffer, size_t buflen, -+ struct passwd **result, -+ uint32_t flags, unsigned int timeout); -+ -+/** -+ * @brief Return group information based on the group name -+ * -+ * @param[in] name same as for getgrnam_r(3) -+ * @param[in] pwd same as for getgrnam_r(3) -+ * @param[in] buffer same as for getgrnam_r(3) -+ * @param[in] buflen same as for getgrnam_r(3) -+ * @param[out] result same as for getgrnam_r(3) -+ * @param[in] flags flags to control the behavior and the results of the -+ * call -+ * @param[in] timeout timeout in milliseconds -+ * -+ * @return -+ * - 0: -+ * - ENOENT: no group with the given name found -+ * - ERANGE: Insufficient buffer space supplied -+ * - ETIME: request timed out but was send to SSSD -+ * - ETIMEDOUT: request timed out but was not send to SSSD -+ */ -+int sss_nss_getgrnam_timeout(const char *name, struct group *grp, -+ char *buffer, size_t buflen, struct group **result, -+ uint32_t flags, unsigned int timeout); -+ -+/** -+ * @brief Return group information based on the group gid -+ * -+ * @param[in] gid same as for getgrgid_r(3) -+ * @param[in] pwd same as for getgrgid_r(3) -+ * @param[in] buffer same as for getgrgid_r(3) -+ * @param[in] buflen same as for getgrgid_r(3) -+ * @param[out] result same as for getgrgid_r(3) -+ * @param[in] flags flags to control the behavior and the results of the -+ * call -+ * @param[in] timeout timeout in milliseconds -+ * -+ * @return -+ * - 0: -+ * - ENOENT: no group with the given gid found -+ * - ERANGE: Insufficient buffer space supplied -+ * - ETIME: request timed out but was send to SSSD -+ * - ETIMEDOUT: request timed out but was not send to SSSD -+ */ -+int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp, -+ char *buffer, size_t buflen, struct group **result, -+ uint32_t flags, unsigned int timeout); -+ -+/** -+ * @brief Return a list of groups to which a user belongs -+ * -+ * @param[in] name name of the user -+ * @param[in] group same as second argument of getgrouplist(3) -+ * @param[in] groups array of gid_t of size ngroups, will be filled -+ * with GIDs of groups the user belongs to -+ * @param[in,out] ngroups size of the groups array on input. On output it -+ * will contain the actual number of groups the -+ * user belongs to. With a return value of 0 the -+ * groups array was large enough to hold all group. -+ * With a return valu of ERANGE the array was not -+ * large enough and ngroups will have the needed -+ * size. -+ * @param[in] flags flags to control the behavior and the results of -+ * the call -+ * @param[in] timeout timeout in milliseconds -+ * -+ * @return -+ * - 0: success -+ * - ENOENT: no user with the given name found -+ * - ERANGE: Insufficient buffer space supplied -+ * - ETIME: request timed out but was send to SSSD -+ * - ETIMEDOUT: request timed out but was not send to SSSD -+ */ -+int sss_nss_getgrouplist_timeout(const char *name, gid_t group, -+ gid_t *groups, int *ngroups, -+ uint32_t flags, unsigned int timeout); -+#endif /* IPA_389DS_PLUGIN_HELPER_CALLS */ - #endif /* SSS_NSS_IDMAP_H_ */ -diff --git a/src/sss_client/idmap/sss_nss_idmap_private.h b/src/sss_client/idmap/sss_nss_idmap_private.h -new file mode 100644 -index 0000000000000000000000000000000000000000..afcd8e355981b9a2dc29a62bab143756b39ed654 ---- /dev/null -+++ b/src/sss_client/idmap/sss_nss_idmap_private.h -@@ -0,0 +1,30 @@ -+/* -+ SSSD -+ -+ NSS Responder ID-mapping interface - private calls -+ -+ Authors: -+ Sumit Bose -+ -+ Copyright (C) 2017 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 . -+*/ -+ -+#ifndef SSS_NSS_IDMAP_PRIVATE_H_ -+#define SSS_NSS_IDMAP_PRIVATE_H_ -+ -+int sss_nss_timedlock(unsigned int timeout_ms, int *time_left_ms); -+ -+#endif /* SSS_NSS_IDMAP_PRIVATE_H_ */ --- -2.13.6 - diff --git a/SOURCES/0024-NSS-add-_EX-version-of-some-requests.patch b/SOURCES/0024-NSS-add-_EX-version-of-some-requests.patch deleted file mode 100644 index e97d92d..0000000 --- a/SOURCES/0024-NSS-add-_EX-version-of-some-requests.patch +++ /dev/null @@ -1,606 +0,0 @@ -From 8c6cb61cc65af7d3f243476dca66fb8f4750df80 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 11 Oct 2017 14:54:54 +0200 -Subject: [PATCH 24/31] NSS: add *_EX version of some requests - -To be able to send the flags to the SSSD responder new request types -with an _EX postfix are added which expect and additional 32bit flag -field after the name or the id of the requested object. - -Related to https://pagure.io/SSSD/sssd/issue/2478 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit cf93f7c2f2031078bbbff095dae01eb4f8deff85) ---- - src/responder/nss/nss_cmd.c | 76 +++++++++++++++++++++----- - src/responder/nss/nss_protocol.c | 81 ++++++++++++++++++++++++++++ - src/responder/nss/nss_protocol.h | 8 +++ - src/sss_client/idmap/sss_nss_ex.c | 110 +++++++++++++++++++++++++++----------- - src/sss_client/sss_cli.h | 7 +++ - 5 files changed, 237 insertions(+), 45 deletions(-) - -diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c -index ebf66dfe0444b83aed20d58d36ddf70d2f4fa1f9..974eaccc93cea3a330007735676da69eb9b84141 100644 ---- a/src/responder/nss/nss_cmd.c -+++ b/src/responder/nss/nss_cmd.c -@@ -54,6 +54,7 @@ static void nss_getby_done(struct tevent_req *subreq); - static void nss_getlistby_done(struct tevent_req *subreq); - - static errno_t nss_getby_name(struct cli_ctx *cli_ctx, -+ bool ex_version, - enum cache_req_type type, - const char **attrs, - enum sss_mc_type memcache, -@@ -64,6 +65,7 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx, - struct tevent_req *subreq; - const char *rawname; - errno_t ret; -+ uint32_t flags = 0; - - cmd_ctx = nss_cmd_ctx_create(cli_ctx, cli_ctx, type, fill_fn); - if (cmd_ctx == NULL) { -@@ -71,7 +73,11 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx, - goto done; - } - -- ret = nss_protocol_parse_name(cli_ctx, &rawname); -+ if (ex_version) { -+ ret = nss_protocol_parse_name_ex(cli_ctx, &rawname, &flags); -+ } else { -+ ret = nss_protocol_parse_name(cli_ctx, &rawname); -+ } - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request message!\n"); - goto done; -@@ -108,6 +114,7 @@ done: - } - - static errno_t nss_getby_id(struct cli_ctx *cli_ctx, -+ bool ex_version, - enum cache_req_type type, - const char **attrs, - enum sss_mc_type memcache, -@@ -118,6 +125,7 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx, - struct tevent_req *subreq; - uint32_t id; - errno_t ret; -+ uint32_t flags = 0; - - cmd_ctx = nss_cmd_ctx_create(cli_ctx, cli_ctx, type, fill_fn); - if (cmd_ctx == NULL) { -@@ -125,7 +133,11 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx, - goto done; - } - -- ret = nss_protocol_parse_id(cli_ctx, &id); -+ if (ex_version) { -+ ret = nss_protocol_parse_id_ex(cli_ctx, &id, &flags); -+ } else { -+ ret = nss_protocol_parse_id(cli_ctx, &id); -+ } - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request message!\n"); - goto done; -@@ -766,14 +778,26 @@ static errno_t nss_endent(struct cli_ctx *cli_ctx, - - static errno_t nss_cmd_getpwnam(struct cli_ctx *cli_ctx) - { -- return nss_getby_name(cli_ctx, CACHE_REQ_USER_BY_NAME, NULL, SSS_MC_PASSWD, -- nss_protocol_fill_pwent); -+ return nss_getby_name(cli_ctx, false, CACHE_REQ_USER_BY_NAME, NULL, -+ SSS_MC_PASSWD, nss_protocol_fill_pwent); - } - - static errno_t nss_cmd_getpwuid(struct cli_ctx *cli_ctx) - { -- return nss_getby_id(cli_ctx, CACHE_REQ_USER_BY_ID, NULL, SSS_MC_PASSWD, -- nss_protocol_fill_pwent); -+ return nss_getby_id(cli_ctx, false, CACHE_REQ_USER_BY_ID, NULL, -+ SSS_MC_PASSWD, nss_protocol_fill_pwent); -+} -+ -+static errno_t nss_cmd_getpwnam_ex(struct cli_ctx *cli_ctx) -+{ -+ return nss_getby_name(cli_ctx, true, CACHE_REQ_USER_BY_NAME, NULL, -+ SSS_MC_PASSWD, nss_protocol_fill_pwent); -+} -+ -+static errno_t nss_cmd_getpwuid_ex(struct cli_ctx *cli_ctx) -+{ -+ return nss_getby_id(cli_ctx, true, CACHE_REQ_USER_BY_ID, NULL, -+ SSS_MC_PASSWD, nss_protocol_fill_pwent); - } - - static errno_t nss_cmd_setpwent(struct cli_ctx *cli_ctx) -@@ -809,16 +833,29 @@ static errno_t nss_cmd_endpwent(struct cli_ctx *cli_ctx) - - static errno_t nss_cmd_getgrnam(struct cli_ctx *cli_ctx) - { -- return nss_getby_name(cli_ctx, CACHE_REQ_GROUP_BY_NAME, NULL, SSS_MC_GROUP, -- nss_protocol_fill_grent); -+ return nss_getby_name(cli_ctx, false, CACHE_REQ_GROUP_BY_NAME, NULL, -+ SSS_MC_GROUP, nss_protocol_fill_grent); - } - - static errno_t nss_cmd_getgrgid(struct cli_ctx *cli_ctx) - { -- return nss_getby_id(cli_ctx, CACHE_REQ_GROUP_BY_ID, NULL, SSS_MC_GROUP, -- nss_protocol_fill_grent); -+ return nss_getby_id(cli_ctx, false, CACHE_REQ_GROUP_BY_ID, NULL, -+ SSS_MC_GROUP, nss_protocol_fill_grent); - } - -+static errno_t nss_cmd_getgrnam_ex(struct cli_ctx *cli_ctx) -+{ -+ return nss_getby_name(cli_ctx, true, CACHE_REQ_GROUP_BY_NAME, NULL, -+ SSS_MC_GROUP, nss_protocol_fill_grent); -+} -+ -+static errno_t nss_cmd_getgrgid_ex(struct cli_ctx *cli_ctx) -+{ -+ return nss_getby_id(cli_ctx, true, CACHE_REQ_GROUP_BY_ID, NULL, -+ SSS_MC_GROUP, nss_protocol_fill_grent); -+} -+ -+ - static errno_t nss_cmd_setgrent(struct cli_ctx *cli_ctx) - { - struct nss_ctx *nss_ctx; -@@ -852,7 +889,13 @@ static errno_t nss_cmd_endgrent(struct cli_ctx *cli_ctx) - - static errno_t nss_cmd_initgroups(struct cli_ctx *cli_ctx) - { -- return nss_getby_name(cli_ctx, CACHE_REQ_INITGROUPS, NULL, -+ return nss_getby_name(cli_ctx, false, CACHE_REQ_INITGROUPS, NULL, -+ SSS_MC_INITGROUPS, nss_protocol_fill_initgr); -+} -+ -+static errno_t nss_cmd_initgroups_ex(struct cli_ctx *cli_ctx) -+{ -+ return nss_getby_name(cli_ctx, true, CACHE_REQ_INITGROUPS, NULL, - SSS_MC_INITGROUPS, nss_protocol_fill_initgr); - } - -@@ -943,7 +986,7 @@ static errno_t nss_cmd_getsidbyname(struct cli_ctx *cli_ctx) - { - const char *attrs[] = { SYSDB_SID_STR, NULL }; - -- return nss_getby_name(cli_ctx, CACHE_REQ_OBJECT_BY_NAME, attrs, -+ return nss_getby_name(cli_ctx, false, CACHE_REQ_OBJECT_BY_NAME, attrs, - SSS_MC_NONE, nss_protocol_fill_sid); - } - -@@ -951,7 +994,7 @@ static errno_t nss_cmd_getsidbyid(struct cli_ctx *cli_ctx) - { - const char *attrs[] = { SYSDB_SID_STR, NULL }; - -- return nss_getby_id(cli_ctx, CACHE_REQ_OBJECT_BY_ID, attrs, -+ return nss_getby_id(cli_ctx, false, CACHE_REQ_OBJECT_BY_ID, attrs, - SSS_MC_NONE, nss_protocol_fill_sid); - } - -@@ -1006,7 +1049,7 @@ static errno_t nss_cmd_getorigbyname(struct cli_ctx *cli_ctx) - attrs = defattrs; - } - -- return nss_getby_name(cli_ctx, CACHE_REQ_OBJECT_BY_NAME, attrs, -+ return nss_getby_name(cli_ctx, false, CACHE_REQ_OBJECT_BY_NAME, attrs, - SSS_MC_NONE, nss_protocol_fill_orig); - } - -@@ -1051,6 +1094,11 @@ struct sss_cmd_table *get_nss_cmds(void) - { SSS_NSS_GETORIGBYNAME, nss_cmd_getorigbyname }, - { SSS_NSS_GETNAMEBYCERT, nss_cmd_getnamebycert }, - { SSS_NSS_GETLISTBYCERT, nss_cmd_getlistbycert }, -+ { SSS_NSS_GETPWNAM_EX, nss_cmd_getpwnam_ex }, -+ { SSS_NSS_GETPWUID_EX, nss_cmd_getpwuid_ex }, -+ { SSS_NSS_GETGRNAM_EX, nss_cmd_getgrnam_ex }, -+ { SSS_NSS_GETGRGID_EX, nss_cmd_getgrgid_ex }, -+ { SSS_NSS_INITGR_EX, nss_cmd_initgroups_ex }, - { SSS_CLI_NULL, NULL } - }; - -diff --git a/src/responder/nss/nss_protocol.c b/src/responder/nss/nss_protocol.c -index 06fc4d00a7877a7990402f4f2633ddc0bd640b41..17bfc4f4e71960a72e9e04622eac95b94a865ec7 100644 ---- a/src/responder/nss/nss_protocol.c -+++ b/src/responder/nss/nss_protocol.c -@@ -134,6 +134,61 @@ nss_protocol_parse_name(struct cli_ctx *cli_ctx, const char **_rawname) - } - - errno_t -+nss_protocol_parse_name_ex(struct cli_ctx *cli_ctx, const char **_rawname, -+ uint32_t *_flags) -+{ -+ struct cli_protocol *pctx; -+ const char *rawname; -+ uint8_t *body; -+ size_t blen; -+ uint8_t *p; -+ uint32_t flags; -+ -+ pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol); -+ -+ sss_packet_get_body(pctx->creq->in, &body, &blen); -+ -+ if (blen < 1 + sizeof(uint32_t)) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Body too short!\n"); -+ return EINVAL; -+ } -+ -+ /* If first argument not terminated fail. */ -+ if (body[blen - 1 - sizeof(uint32_t)] != '\0') { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Body is not null terminated!\n"); -+ return EINVAL; -+ } -+ -+ p = memchr(body, '\0', blen); -+ -+ /* If the body isn't valid UTF-8, fail */ -+ if (!sss_utf8_check(body, (p - body))) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "First argument is not UTF-8 string!\n"); -+ return EINVAL; -+ } -+ -+ rawname = (const char *)body; -+ if (rawname[0] == '\0') { -+ DEBUG(SSSDBG_CRIT_FAILURE, "An empty name was provided!\n"); -+ return EINVAL; -+ } -+ -+ p++; -+ if ((p - body) + sizeof(uint32_t) != blen) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Body has unexpected size!\n"); -+ return EINVAL; -+ } -+ -+ SAFEALIGN_COPY_UINT32(&flags, p, NULL); -+ p += sizeof(uint32_t); -+ -+ *_rawname = rawname; -+ *_flags = flags; -+ -+ return EOK; -+} -+ -+errno_t - nss_protocol_parse_id(struct cli_ctx *cli_ctx, uint32_t *_id) - { - struct cli_protocol *pctx; -@@ -157,6 +212,32 @@ nss_protocol_parse_id(struct cli_ctx *cli_ctx, uint32_t *_id) - } - - errno_t -+nss_protocol_parse_id_ex(struct cli_ctx *cli_ctx, uint32_t *_id, -+ uint32_t *_flags) -+{ -+ struct cli_protocol *pctx; -+ uint8_t *body; -+ size_t blen; -+ uint32_t id; -+ uint32_t flags; -+ -+ pctx = talloc_get_type(cli_ctx->protocol_ctx, struct cli_protocol); -+ -+ sss_packet_get_body(pctx->creq->in, &body, &blen); -+ -+ if (blen != 2 * sizeof(uint32_t)) { -+ return EINVAL; -+ } -+ -+ SAFEALIGN_COPY_UINT32(&id, body, NULL); -+ SAFEALIGN_COPY_UINT32(&flags, body + sizeof(uint32_t), NULL); -+ -+ *_id = id; -+ -+ return EOK; -+} -+ -+errno_t - nss_protocol_parse_limit(struct cli_ctx *cli_ctx, uint32_t *_limit) - { - return nss_protocol_parse_id(cli_ctx, _limit); -diff --git a/src/responder/nss/nss_protocol.h b/src/responder/nss/nss_protocol.h -index 417b0891615dcb8771d49f7b2f4d276342ca3150..ca5b040237dc18acdca9a7a3a7a7dbb64265aa95 100644 ---- a/src/responder/nss/nss_protocol.h -+++ b/src/responder/nss/nss_protocol.h -@@ -89,9 +89,17 @@ errno_t - nss_protocol_parse_name(struct cli_ctx *cli_ctx, const char **_rawname); - - errno_t -+nss_protocol_parse_name_ex(struct cli_ctx *cli_ctx, const char **_rawname, -+ uint32_t *_flags); -+ -+errno_t - nss_protocol_parse_id(struct cli_ctx *cli_ctx, uint32_t *_id); - - errno_t -+nss_protocol_parse_id_ex(struct cli_ctx *cli_ctx, uint32_t *_id, -+ uint32_t *_flags); -+ -+errno_t - nss_protocol_parse_limit(struct cli_ctx *cli_ctx, uint32_t *_limit); - - errno_t -diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c -index 582d1373ec35305cf128e04fd3d705457d304789..dc7610a4e528b5126f0d25d84cd3c1a22f683b75 100644 ---- a/src/sss_client/idmap/sss_nss_ex.c -+++ b/src/sss_client/idmap/sss_nss_ex.c -@@ -61,31 +61,37 @@ errno_t sss_nss_mc_get(struct nss_input *inp) - { - switch(inp->cmd) { - case SSS_NSS_GETPWNAM: -- return sss_nss_mc_getpwnam(inp->input.name, (inp->rd.len - 1), -+ case SSS_NSS_GETPWNAM_EX: -+ return sss_nss_mc_getpwnam(inp->input.name, strlen(inp->input.name), - inp->result.pwrep.result, - inp->result.pwrep.buffer, - inp->result.pwrep.buflen); - break; - case SSS_NSS_GETPWUID: -+ case SSS_NSS_GETPWUID_EX: - return sss_nss_mc_getpwuid(inp->input.uid, - inp->result.pwrep.result, - inp->result.pwrep.buffer, - inp->result.pwrep.buflen); - break; - case SSS_NSS_GETGRNAM: -- return sss_nss_mc_getgrnam(inp->input.name, (inp->rd.len - 1), -+ case SSS_NSS_GETGRNAM_EX: -+ return sss_nss_mc_getgrnam(inp->input.name, strlen(inp->input.name), - inp->result.grrep.result, - inp->result.grrep.buffer, - inp->result.grrep.buflen); - break; - case SSS_NSS_GETGRGID: -+ case SSS_NSS_GETGRGID_EX: - return sss_nss_mc_getgrgid(inp->input.gid, - inp->result.grrep.result, - inp->result.grrep.buffer, - inp->result.grrep.buflen); - break; - case SSS_NSS_INITGR: -- return sss_nss_mc_initgroups_dyn(inp->input.name, (inp->rd.len - 1), -+ case SSS_NSS_INITGR_EX: -+ return sss_nss_mc_initgroups_dyn(inp->input.name, -+ strlen(inp->input.name), - -1 /* currently ignored */, - inp->result.initgrrep.start, - inp->result.initgrrep.ngroups, -@@ -163,7 +169,7 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout) - goto out; - } - -- if (inp->cmd == SSS_NSS_INITGR) { -+ if (inp->cmd == SSS_NSS_INITGR || inp->cmd == SSS_NSS_INITGR_EX) { - if ((*(inp->result.initgrrep.ngroups) - *(inp->result.initgrrep.start)) - < num_results) { - new_groups = realloc(inp->result.initgrrep.groups, -@@ -198,15 +204,24 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout) - } - - len = replen - 8; -- if (inp->cmd == SSS_NSS_GETPWNAM || inp->cmd == SSS_NSS_GETPWUID) { -+ -+ switch(inp->cmd) { -+ case SSS_NSS_GETPWNAM: -+ case SSS_NSS_GETPWUID: -+ case SSS_NSS_GETPWNAM_EX: -+ case SSS_NSS_GETPWUID_EX: - ret = sss_nss_getpw_readrep(&(inp->result.pwrep), repbuf+8, &len); -- } else if (inp->cmd == SSS_NSS_GETGRNAM || inp->cmd == SSS_NSS_GETGRGID) { -+ break; -+ case SSS_NSS_GETGRNAM: -+ case SSS_NSS_GETGRGID: -+ case SSS_NSS_GETGRNAM_EX: -+ case SSS_NSS_GETGRGID_EX: - ret = sss_nss_getgr_readrep(&(inp->result.grrep), repbuf+8, &len); -- } else { -+ break; -+ default: - ret = EINVAL; -- goto out; - } -- if (ret) { -+ if (ret != 0) { - goto out; - } - -@@ -223,6 +238,39 @@ out: - return ret; - } - -+static int make_name_flag_req_data(const char *name, uint32_t flags, -+ struct sss_cli_req_data *rd) -+{ -+ size_t len; -+ size_t name_len; -+ uint8_t *data; -+ int ret; -+ -+ if (name == NULL) { -+ return EINVAL; -+ } -+ -+ ret = sss_strnlen(name, SSS_NAME_MAX, &name_len); -+ if (ret != 0) { -+ return ret; -+ } -+ name_len++; -+ -+ len = name_len + sizeof(uint32_t); -+ data = malloc(len); -+ if (data == NULL) { -+ return ENOMEM; -+ } -+ -+ memcpy(data, name, name_len); -+ SAFEALIGN_COPY_UINT32(data + name_len, &flags, NULL); -+ -+ rd->len = len; -+ rd->data = data; -+ -+ return 0; -+} -+ - int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd, - char *buffer, size_t buflen, - struct passwd **result, -@@ -231,8 +279,7 @@ int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd, - int ret; - struct nss_input inp = { - .input.name = name, -- .cmd = SSS_NSS_GETPWNAM, -- .rd.data = name, -+ .cmd = SSS_NSS_GETPWNAM_EX, - .result.pwrep.result = pwd, - .result.pwrep.buffer = buffer, - .result.pwrep.buflen = buflen}; -@@ -241,15 +288,15 @@ int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd, - return ERANGE; - } - -- ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len); -+ ret = make_name_flag_req_data(name, flags, &inp.rd); - if (ret != 0) { -- return EINVAL; -+ return ret; - } -- inp.rd.len++; - - *result = NULL; - - ret = sss_get_ex(&inp, flags, timeout); -+ free(discard_const(inp.rd.data)); - if (ret == 0) { - *result = inp.result.pwrep.result; - } -@@ -262,12 +309,12 @@ int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd, - uint32_t flags, unsigned int timeout) - { - int ret; -- uint32_t user_uid = uid; -+ uint32_t req_data[2]; - struct nss_input inp = { - .input.uid = uid, -- .cmd = SSS_NSS_GETPWUID, -- .rd.len = sizeof(uint32_t), -- .rd.data = &user_uid, -+ .cmd = SSS_NSS_GETPWUID_EX, -+ .rd.len = 2 * sizeof(uint32_t), -+ .rd.data = &req_data, - .result.pwrep.result = pwd, - .result.pwrep.buffer = buffer, - .result.pwrep.buflen = buflen}; -@@ -276,6 +323,8 @@ int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd, - return ERANGE; - } - -+ SAFEALIGN_COPY_UINT32(&req_data[0], &uid, NULL); -+ SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL); - *result = NULL; - - ret = sss_get_ex(&inp, flags, timeout); -@@ -292,8 +341,7 @@ int sss_nss_getgrnam_timeout(const char *name, struct group *grp, - int ret; - struct nss_input inp = { - .input.name = name, -- .cmd = SSS_NSS_GETGRNAM, -- .rd.data = name, -+ .cmd = SSS_NSS_GETGRNAM_EX, - .result.grrep.result = grp, - .result.grrep.buffer = buffer, - .result.grrep.buflen = buflen}; -@@ -302,15 +350,15 @@ int sss_nss_getgrnam_timeout(const char *name, struct group *grp, - return ERANGE; - } - -- ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len); -+ ret = make_name_flag_req_data(name, flags, &inp.rd); - if (ret != 0) { -- return EINVAL; -+ return ret; - } -- inp.rd.len++; - - *result = NULL; - - ret = sss_get_ex(&inp, flags, timeout); -+ free(discard_const(inp.rd.data)); - if (ret == 0) { - *result = inp.result.grrep.result; - } -@@ -322,12 +370,12 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp, - uint32_t flags, unsigned int timeout) - { - int ret; -- uint32_t group_gid = gid; -+ uint32_t req_data[2]; - struct nss_input inp = { - .input.gid = gid, -- .cmd = SSS_NSS_GETGRGID, -- .rd.len = sizeof(uint32_t), -- .rd.data = &group_gid, -+ .cmd = SSS_NSS_GETGRGID_EX, -+ .rd.len = 2 * sizeof(uint32_t), -+ .rd.data = &req_data, - .result.grrep.result = grp, - .result.grrep.buffer = buffer, - .result.grrep.buflen = buflen}; -@@ -336,6 +384,8 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp, - return ERANGE; - } - -+ SAFEALIGN_COPY_UINT32(&req_data[0], &gid, NULL); -+ SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL); - *result = NULL; - - ret = sss_get_ex(&inp, flags, timeout); -@@ -355,18 +405,16 @@ int sss_nss_getgrouplist_timeout(const char *name, gid_t group, - long int start = 1; - struct nss_input inp = { - .input.name = name, -- .cmd = SSS_NSS_INITGR, -- .rd.data = name}; -+ .cmd = SSS_NSS_INITGR_EX}; - - if (groups == NULL || ngroups == NULL || *ngroups == 0) { - return EINVAL; - } - -- ret = sss_strnlen(name, SSS_NAME_MAX, &inp.rd.len); -+ ret = make_name_flag_req_data(name, flags, &inp.rd); - if (ret != 0) { - return ret; - } -- inp.rd.len++; - - new_ngroups = MAX(1, *ngroups); - new_groups = malloc(new_ngroups * sizeof(gid_t)); -diff --git a/src/sss_client/sss_cli.h b/src/sss_client/sss_cli.h -index 5329651a9385d138b8ea7237cb5cf4e2b8e5f371..9d2cc00c9957f5680548461129e3e6b777da5091 100644 ---- a/src/sss_client/sss_cli.h -+++ b/src/sss_client/sss_cli.h -@@ -79,6 +79,9 @@ enum sss_cli_command { - SSS_NSS_GETPWENT = 0x0014, - SSS_NSS_ENDPWENT = 0x0015, - -+ SSS_NSS_GETPWNAM_EX = 0x0019, -+ SSS_NSS_GETPWUID_EX = 0x001A, -+ - /* group */ - - SSS_NSS_GETGRNAM = 0x0021, -@@ -88,6 +91,10 @@ enum sss_cli_command { - SSS_NSS_ENDGRENT = 0x0025, - SSS_NSS_INITGR = 0x0026, - -+ SSS_NSS_GETGRNAM_EX = 0x0029, -+ SSS_NSS_GETGRGID_EX = 0x002A, -+ SSS_NSS_INITGR_EX = 0x002E, -+ - #if 0 - /* aliases */ - --- -2.13.6 - diff --git a/SOURCES/0024-RESOLV-Add-a-resolv_hostport_list-request.patch b/SOURCES/0024-RESOLV-Add-a-resolv_hostport_list-request.patch new file mode 100644 index 0000000..e19eb54 --- /dev/null +++ b/SOURCES/0024-RESOLV-Add-a-resolv_hostport_list-request.patch @@ -0,0 +1,265 @@ +From e73e35f2a1ef037d89f73b4ce5609e2567dc8714 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 25 Jun 2018 12:46:51 +0200 +Subject: [PATCH] RESOLV: Add a resolv_hostport_list request + +Adds a request that resolves a list of (host,port) tuples and returns a +list of structures that contain the resolv_hostent structure as other +resolver requests do, but also a pointer to the original request tuple. + +This is done because the request skips any unresolvable inputs, so it +might be handy to know which input an output maps to. + +It is expected that the request will be used in the future also for cases +where we want to e.g. try the connectivity to a serve using a mechanism +such as an LDAP ping. + +Related: +https://pagure.io/SSSD/sssd/issue/3291 + +Reviewed-by: Sumit Bose +(cherry picked from commit 6f80bccc6f8203381c387080bd0563ba10994487) +--- + src/resolv/async_resolv.c | 187 ++++++++++++++++++++++++++++++++++++++ + src/resolv/async_resolv.h | 30 ++++++ + 2 files changed, 217 insertions(+) + +diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c +index ba6fabf285533153ea440394ce1cc224aa42cbd3..bb27011548b73c0cc62f6638401847ab9e0b175c 100644 +--- a/src/resolv/async_resolv.c ++++ b/src/resolv/async_resolv.c +@@ -2322,3 +2322,190 @@ resolv_sort_srv_reply(struct ares_srv_reply **reply) + + return EOK; + } ++ ++struct resolv_hostport_list_state { ++ struct tevent_context *ev; ++ struct resolv_ctx *ctx; ++ struct resolv_hostport *hostport_list; ++ size_t list_size; ++ size_t limit; ++ enum restrict_family family_order; ++ enum host_database *db; ++ ++ size_t hpindex; ++ ++ struct resolv_hostport_addr **rhp_addrs; ++ size_t addrindex; ++}; ++ ++static errno_t resolv_hostport_list_step(struct tevent_req *req); ++static void resolv_hostport_list_resolv_hostname_done(struct tevent_req *subreq); ++ ++struct tevent_req *resolv_hostport_list_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct resolv_ctx *ctx, ++ struct resolv_hostport *hostport_list, ++ size_t list_size, ++ size_t limit, ++ enum restrict_family family_order, ++ enum host_database *db) ++{ ++ struct resolv_hostport_list_state *state; ++ struct tevent_req *req; ++ errno_t ret; ++ ++ req = tevent_req_create(mem_ctx, &state, ++ struct resolv_hostport_list_state); ++ if (req == NULL) { ++ return NULL; ++ } ++ state->ev = ev; ++ state->ctx = ctx; ++ state->hostport_list = hostport_list; ++ state->family_order = family_order; ++ state->db = db; ++ state->list_size = list_size; ++ state->limit = limit; ++ ++ state->rhp_addrs = talloc_array(state, ++ struct resolv_hostport_addr *, ++ state->list_size); ++ if (state->rhp_addrs == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } ++ ++ ret = resolv_hostport_list_step(req); ++ if (ret != EAGAIN) { ++ goto immediately; ++ } ++ ++ return req; ++ ++immediately: ++ if (ret != EOK) { ++ tevent_req_error(req, ret); ++ } else { ++ tevent_req_done(req); ++ } ++ tevent_req_post(req, ev); ++ return req; ++} ++ ++static errno_t resolv_hostport_list_step(struct tevent_req *req) ++{ ++ struct tevent_req *subreq = NULL; ++ struct resolv_hostport_list_state *state = tevent_req_data(req, ++ struct resolv_hostport_list_state); ++ ++ if (state->hpindex >= state->list_size) { ++ DEBUG(SSSDBG_TRACE_INTERNAL, "Done\n"); ++ return EOK; ++ } ++ ++ subreq = resolv_gethostbyname_send(state, ++ state->ev, ++ state->ctx, ++ state->hostport_list[state->hpindex].host, ++ state->family_order, ++ state->db); ++ if (subreq == NULL) { ++ return ENOMEM; ++ } ++ tevent_req_set_callback(subreq, ++ resolv_hostport_list_resolv_hostname_done, req); ++ return EAGAIN; ++} ++ ++static struct resolv_hostport_addr* ++resolv_hostport_addr_new(TALLOC_CTX *mem_ctx, ++ const char *host, ++ int port, ++ struct resolv_hostent *reply) ++{ ++ struct resolv_hostport_addr *rhp_addr; ++ ++ rhp_addr = talloc_zero(mem_ctx, struct resolv_hostport_addr); ++ if (rhp_addr == NULL) { ++ return NULL; ++ } ++ ++ rhp_addr->origin.host = talloc_strdup(rhp_addr, host); ++ if (rhp_addr->origin.host == NULL) { ++ return NULL; ++ } ++ ++ rhp_addr->origin.port = port; ++ rhp_addr->reply = talloc_steal(rhp_addr, reply); ++ return rhp_addr; ++} ++ ++static void resolv_hostport_list_resolv_hostname_done(struct tevent_req *subreq) ++{ ++ errno_t ret; ++ struct tevent_req *req = ++ tevent_req_callback_data(subreq, struct tevent_req); ++ struct resolv_hostport_list_state *state = tevent_req_data(req, ++ struct resolv_hostport_list_state); ++ struct resolv_hostent *rhostent; ++ int resolv_status; ++ ++ ret = resolv_gethostbyname_recv(subreq, state, &resolv_status, NULL, ++ &rhostent); ++ talloc_zfree(subreq); ++ ++ if (ret != EOK) { ++ /* Don't abort the request, just go to the next one */ ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Could not resolve address for this machine, error [%d]: %s, " ++ "resolver returned: [%d]: %s\n", ret, sss_strerror(ret), ++ resolv_status, resolv_strerror(resolv_status)); ++ } else { ++ state->rhp_addrs[state->addrindex] = \ ++ resolv_hostport_addr_new(state->rhp_addrs, ++ state->hostport_list[state->hpindex].host, ++ state->hostport_list[state->hpindex].port, ++ rhostent); ++ state->addrindex++; ++ ++ if (state->limit > 0 && state->addrindex >= state->limit) { ++ DEBUG(SSSDBG_TRACE_INTERNAL, ++ "Reached the limit or addresses to resolve\n"); ++ tevent_req_done(req); ++ return; ++ } ++ } ++ ++ state->hpindex++; ++ ++ ret = resolv_hostport_list_step(req); ++ if (ret == EOK) { ++ tevent_req_done(req); ++ return; ++ } else if (ret != EAGAIN) { ++ tevent_req_error(req, ret); ++ return; ++ } ++ /* Next iteration .. */ ++} ++ ++int resolv_hostport_list_recv(struct tevent_req *req, ++ TALLOC_CTX *mem_ctx, ++ size_t *_rhp_len, ++ struct resolv_hostport_addr ***_rhp_addrs) ++{ ++ struct resolv_hostport_list_state *state = tevent_req_data(req, ++ struct resolv_hostport_list_state); ++ ++ TEVENT_REQ_RETURN_ON_ERROR(req); ++ ++ if (_rhp_len) { ++ *_rhp_len = state->addrindex; ++ } ++ ++ if (_rhp_addrs) { ++ *_rhp_addrs = talloc_steal(mem_ctx, state->rhp_addrs); ++ } ++ ++ return EOK; ++} +diff --git a/src/resolv/async_resolv.h b/src/resolv/async_resolv.h +index b602a425c21b5f3bfd0098ce3208f6750d4ed1ad..90ed037075c7becb0f8bcd580b218092f2d8579e 100644 +--- a/src/resolv/async_resolv.h ++++ b/src/resolv/async_resolv.h +@@ -112,6 +112,36 @@ int resolv_gethostbyname_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + int *status, int *timeouts, + struct resolv_hostent **rhostent); + ++struct resolv_hostport { ++ const char *host; ++ int port; ++}; ++ ++struct resolv_hostport_addr { ++ struct resolv_hostport origin; ++ struct resolv_hostent *reply; ++}; ++ ++/* Resolves a list of resolv_hostport tuples into a list of ++ * resolv_hostport_addr. Any unresolvable addresses are skipped. ++ * ++ * Optionally takes a limit argument and stops after the request ++ * had resolved addresses up to the limit. ++ */ ++struct tevent_req *resolv_hostport_list_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct resolv_ctx *ctx, ++ struct resolv_hostport *hostport_list, ++ size_t list_size, ++ size_t limit, ++ enum restrict_family family_order, ++ enum host_database *db); ++ ++int resolv_hostport_list_recv(struct tevent_req *req, ++ TALLOC_CTX *mem_ctx, ++ size_t *_rhp_len, ++ struct resolv_hostport_addr ***_rhp_addrs); ++ + char * + resolv_get_string_address_index(TALLOC_CTX *mem_ctx, + struct resolv_hostent *hostent, +-- +2.17.1 + diff --git a/SOURCES/0025-KRB5-IPA-AD-Add-a-utility-function-to-create-a-krb5_.patch b/SOURCES/0025-KRB5-IPA-AD-Add-a-utility-function-to-create-a-krb5_.patch new file mode 100644 index 0000000..53d87db --- /dev/null +++ b/SOURCES/0025-KRB5-IPA-AD-Add-a-utility-function-to-create-a-krb5_.patch @@ -0,0 +1,246 @@ +From 95cb7de6221dad54b37f7dd05dbfc3b717168488 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 25 Jun 2018 13:08:25 +0200 +Subject: [PATCH] KRB5/IPA/AD: Add a utility function to create a krb5_service + instance + +Each Kerberized provider used hand-crafted copy-paste code to set up its +copy of the krb5_service structure. Instead of adding yet another copy in +this patchset in the IPA subdomains code, create a utility function instead. + +Due to IPA provider first creating the krb5_service in the common setup +function, but only later reading the auth options in the auth provider +constructor, the code first uses the default true value for the use_kdcinfo +flag and then overrides it with the configured value in the auth constructor +-- it would be preferable to create the structure with the right value at +creation time, but this would require bigger refactoring. Also, the code +before this change was even less correct as the flag was initially set the +"false" due to the structure being allocated with talloc_zero(). At least +now it uses the default value. + +Related: +https://pagure.io/SSSD/sssd/issue/3291 + +Reviewed-by: Sumit Bose +(cherry picked from commit a9a9f39342ebd26425cb1b3baedfea2429d88b04) +--- + src/providers/ad/ad_common.c | 26 ++-------------- + src/providers/ipa/ipa_common.c | 35 +++++++++------------- + src/providers/krb5/krb5_common.c | 51 ++++++++++++++++++++++---------- + src/providers/krb5/krb5_common.h | 6 ++++ + 4 files changed, 58 insertions(+), 60 deletions(-) + +diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c +index feeb5d09643a02b99be1a387b41842a034a323b8..b103410e5915a380d0404e18da869517e4d4e355 100644 +--- a/src/providers/ad/ad_common.c ++++ b/src/providers/ad/ad_common.c +@@ -757,20 +757,14 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, + goto done; + } + +- service->krb5_service = talloc_zero(service, struct krb5_service); ++ service->krb5_service = krb5_service_new(service, bectx, ++ ad_service, krb5_realm, ++ use_kdcinfo); + if (!service->krb5_service) { + ret = ENOMEM; + goto done; + } + +- /* Set flag that controls whether we want to write the +- * kdcinfo files at all +- */ +- service->krb5_service->write_kdcinfo = use_kdcinfo; +- DEBUG(SSSDBG_CONF_SETTINGS, "write_kdcinfo for realm %s set to %s\n", +- krb5_realm, +- service->krb5_service->write_kdcinfo ? "true" : "false"); +- + ret = be_fo_add_service(bectx, ad_service, ad_user_data_cmp); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create failover service!\n"); +@@ -783,12 +777,6 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, + goto done; + } + +- service->krb5_service->name = talloc_strdup(service->krb5_service, +- ad_service); +- if (!service->krb5_service->name) { +- ret = ENOMEM; +- goto done; +- } + service->sdap->kinit_service_name = service->krb5_service->name; + service->gc->kinit_service_name = service->krb5_service->name; + +@@ -797,14 +785,6 @@ ad_failover_init(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, + ret = EINVAL; + goto done; + } +- service->krb5_service->realm = +- talloc_strdup(service->krb5_service, krb5_realm); +- if (!service->krb5_service->realm) { +- ret = ENOMEM; +- goto done; +- } +- +- service->krb5_service->be_ctx = bectx; + + if (!primary_servers) { + DEBUG(SSSDBG_CONF_SETTINGS, +diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c +index dcbb54a744358718e444972b9827ee64887e5e33..5808513bfd570c43bc1712114aabba5749ba0fec 100644 +--- a/src/providers/ipa/ipa_common.c ++++ b/src/providers/ipa/ipa_common.c +@@ -965,6 +965,13 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, + return ENOMEM; + } + ++ realm = dp_opt_get_string(options->basic, IPA_KRB5_REALM); ++ if (!realm) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm set\n"); ++ ret = EINVAL; ++ goto done; ++ } ++ + service = talloc_zero(tmp_ctx, struct ipa_service); + if (!service) { + ret = ENOMEM; +@@ -975,7 +982,13 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, + ret = ENOMEM; + goto done; + } +- service->krb5_service = talloc_zero(service, struct krb5_service); ++ ++ service->krb5_service = krb5_service_new(service, ctx, ++ "IPA", realm, ++ true); /* The configured value ++ * will be set later when ++ * the auth provider is set up ++ */ + if (!service->krb5_service) { + ret = ENOMEM; + goto done; +@@ -993,28 +1006,8 @@ int ipa_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, + goto done; + } + +- service->krb5_service->name = talloc_strdup(service, "IPA"); +- if (!service->krb5_service->name) { +- ret = ENOMEM; +- goto done; +- } + service->sdap->kinit_service_name = service->krb5_service->name; + +- realm = dp_opt_get_string(options->basic, IPA_KRB5_REALM); +- if (!realm) { +- DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm set\n"); +- ret = EINVAL; +- goto done; +- } +- service->krb5_service->realm = +- talloc_strdup(service->krb5_service, realm); +- if (!service->krb5_service->realm) { +- ret = ENOMEM; +- goto done; +- } +- +- service->krb5_service->be_ctx = ctx; +- + if (!primary_servers) { + DEBUG(SSSDBG_CONF_SETTINGS, + "No primary servers defined, using service discovery\n"); +diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c +index d064a09ac3726c4185c2fa1eeac76ef6c261d33b..2a50dfec55c29b8d7f8b8751c904977c22aa906a 100644 +--- a/src/providers/krb5/krb5_common.c ++++ b/src/providers/krb5/krb5_common.c +@@ -807,6 +807,40 @@ static int krb5_user_data_cmp(void *ud1, void *ud2) + return strcasecmp((char*) ud1, (char*) ud2); + } + ++struct krb5_service *krb5_service_new(TALLOC_CTX *mem_ctx, ++ struct be_ctx *be_ctx, ++ const char *service_name, ++ const char *realm, ++ bool use_kdcinfo) ++{ ++ struct krb5_service *service; ++ ++ service = talloc_zero(mem_ctx, struct krb5_service); ++ if (service == NULL) { ++ return NULL; ++ } ++ ++ service->name = talloc_strdup(service, service_name); ++ if (service->name == NULL) { ++ talloc_free(service); ++ return NULL; ++ } ++ ++ service->realm = talloc_strdup(service, realm); ++ if (service->realm == NULL) { ++ talloc_free(service); ++ return NULL; ++ } ++ ++ DEBUG(SSSDBG_CONF_SETTINGS, ++ "write_kdcinfo for realm %s set to %s\n", ++ realm, ++ use_kdcinfo ? "true" : "false"); ++ service->write_kdcinfo = use_kdcinfo; ++ service->be_ctx = be_ctx; ++ return service; ++} ++ + int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, + const char *service_name, + const char *primary_servers, +@@ -824,7 +858,7 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, + return ENOMEM; + } + +- service = talloc_zero(tmp_ctx, struct krb5_service); ++ service = krb5_service_new(tmp_ctx, ctx, service_name, realm, use_kdcinfo); + if (!service) { + ret = ENOMEM; + goto done; +@@ -836,21 +870,6 @@ int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, + goto done; + } + +- service->name = talloc_strdup(service, service_name); +- if (!service->name) { +- ret = ENOMEM; +- goto done; +- } +- +- service->realm = talloc_strdup(service, realm); +- if (!service->realm) { +- ret = ENOMEM; +- goto done; +- } +- +- service->write_kdcinfo = use_kdcinfo; +- service->be_ctx = ctx; +- + if (!primary_servers) { + DEBUG(SSSDBG_CONF_SETTINGS, + "No primary servers defined, using service discovery\n"); +diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h +index 3529d740b89fee91281f936fdafd1bdb99e95bd7..1c12d5652ccef7e1738177eedad1c9de543916b7 100644 +--- a/src/providers/krb5/krb5_common.h ++++ b/src/providers/krb5/krb5_common.h +@@ -164,6 +164,12 @@ errno_t write_krb5info_file(struct krb5_service *krb5_service, + const char *server, + const char *service); + ++struct krb5_service *krb5_service_new(TALLOC_CTX *mem_ctx, ++ struct be_ctx *be_ctx, ++ const char *service_name, ++ const char *realm, ++ bool use_kdcinfo); ++ + int krb5_service_init(TALLOC_CTX *memctx, struct be_ctx *ctx, + const char *service_name, + const char *primary_servers, +-- +2.17.1 + diff --git a/SOURCES/0025-NSS-add-support-for-SSS_NSS_EX_FLAG_NO_CACHE.patch b/SOURCES/0025-NSS-add-support-for-SSS_NSS_EX_FLAG_NO_CACHE.patch deleted file mode 100644 index 637d39b..0000000 --- a/SOURCES/0025-NSS-add-support-for-SSS_NSS_EX_FLAG_NO_CACHE.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 21633dc4ad13c0ebae0f2b4e4f4188556202113e Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 12 Oct 2017 10:42:41 +0200 -Subject: [PATCH 25/31] NSS: add support for SSS_NSS_EX_FLAG_NO_CACHE - -If SSS_NSS_EX_FLAG_NO_CACHE is set the object is refresh by directly -looking it up in the backend. - -Related to https://pagure.io/SSSD/sssd/issue/2478 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit ac6b267ff3df6d0417062a128ec16b184ea2c1b7) ---- - src/responder/nss/nss_cmd.c | 8 ++++ - src/sss_client/idmap/sss_nss_ex.c | 71 ++++++++++++++++++++---------------- - src/sss_client/idmap/sss_nss_idmap.h | 4 ++ - 3 files changed, 52 insertions(+), 31 deletions(-) - -diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c -index 974eaccc93cea3a330007735676da69eb9b84141..c5ddd2f2cc2122cd169ea991b94a14eb5bad095f 100644 ---- a/src/responder/nss/nss_cmd.c -+++ b/src/responder/nss/nss_cmd.c -@@ -92,6 +92,10 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx, - goto done; - } - -+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) { -+ cache_req_data_set_bypass_cache(data, true); -+ } -+ - subreq = nss_get_object_send(cmd_ctx, cli_ctx->ev, cli_ctx, - data, memcache, rawname, 0); - if (subreq == NULL) { -@@ -152,6 +156,10 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx, - goto done; - } - -+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) { -+ cache_req_data_set_bypass_cache(data, true); -+ } -+ - subreq = nss_get_object_send(cmd_ctx, cli_ctx->ev, cli_ctx, - data, memcache, NULL, id); - if (subreq == NULL) { -diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c -index dc7610a4e528b5126f0d25d84cd3c1a22f683b75..edb3ea652ef7032b76c8f815b9f83fe185a669ea 100644 ---- a/src/sss_client/idmap/sss_nss_ex.c -+++ b/src/sss_client/idmap/sss_nss_ex.c -@@ -115,42 +115,51 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout) - size_t c; - gid_t *new_groups; - size_t idx; -+ bool skip_mc = false; - -- ret = sss_nss_mc_get(inp); -- switch (ret) { -- case 0: -- return 0; -- case ERANGE: -- return ERANGE; -- case ENOENT: -- /* fall through, we need to actively ask the parent -- * if no entry is found */ -- break; -- default: -- /* if using the mmaped cache failed, -- * fall back to socket based comms */ -- break; -+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) { -+ skip_mc = true; -+ } -+ -+ if (!skip_mc) { -+ ret = sss_nss_mc_get(inp); -+ switch (ret) { -+ case 0: -+ return 0; -+ case ERANGE: -+ return ERANGE; -+ case ENOENT: -+ /* fall through, we need to actively ask the parent -+ * if no entry is found */ -+ break; -+ default: -+ /* if using the mmaped cache failed, -+ * fall back to socket based comms */ -+ break; -+ } - } - - sss_nss_timedlock(timeout, &time_left); - -- /* previous thread might already initialize entry in mmap cache */ -- ret = sss_nss_mc_get(inp); -- switch (ret) { -- case 0: -- ret = 0; -- goto out; -- case ERANGE: -- ret = ERANGE; -- goto out; -- case ENOENT: -- /* fall through, we need to actively ask the parent -- * if no entry is found */ -- break; -- default: -- /* if using the mmaped cache failed, -- * fall back to socket based comms */ -- break; -+ if (!skip_mc) { -+ /* previous thread might already initialize entry in mmap cache */ -+ ret = sss_nss_mc_get(inp); -+ switch (ret) { -+ case 0: -+ ret = 0; -+ goto out; -+ case ERANGE: -+ ret = ERANGE; -+ goto out; -+ case ENOENT: -+ /* fall through, we need to actively ask the parent -+ * if no entry is found */ -+ break; -+ default: -+ /* if using the mmaped cache failed, -+ * fall back to socket based comms */ -+ break; -+ } - } - - ret = sss_nss_make_request_timeout(inp->cmd, &inp->rd, time_left, -diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h -index 2334b6cb3fb8ef62e4ce3a7187c7affaeaa034e7..1649830afbb80c617fd339f054aef8bc8e585fb9 100644 ---- a/src/sss_client/idmap/sss_nss_idmap.h -+++ b/src/sss_client/idmap/sss_nss_idmap.h -@@ -169,6 +169,10 @@ void sss_nss_free_kv(struct sss_nss_kv *kv_list); - - #define SSS_NSS_EX_FLAG_NO_FLAGS 0 - -+/** Always request data from the server side, client must be privileged to do -+ * so, see nss_trusted_users option in man sssd.conf for details */ -+#define SSS_NSS_EX_FLAG_NO_CACHE (1 << 0) -+ - #ifdef IPA_389DS_PLUGIN_HELPER_CALLS - - /** --- -2.13.6 - diff --git a/SOURCES/0026-CACHE_REQ-Add-cache_req_data_set_bypass_dp.patch b/SOURCES/0026-CACHE_REQ-Add-cache_req_data_set_bypass_dp.patch deleted file mode 100644 index e0dd792..0000000 --- a/SOURCES/0026-CACHE_REQ-Add-cache_req_data_set_bypass_dp.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 102ea8cf91207d3dc05537d5c558d98e4756027a Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 23 Oct 2017 18:26:55 +0200 -Subject: [PATCH 26/31] CACHE_REQ: Add cache_req_data_set_bypass_dp() - -Similar to cache_req_data_set_bypass_cache() -cache_req_data_set_bypass_dp() can be used to control how the cache_req -framework performs the lookup. If cache_req_data_set_bypass_dp() is used -with 'true' only a cache lookup is performed and no request is send to -the backend even if no entry was found. - -Related to https://pagure.io/SSSD/sssd/issue/2478 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 52e675ec4b160720515c81ae8c0e5a95feb50c57) ---- - src/responder/common/cache_req/cache_req.c | 15 +++++++++++++++ - src/responder/common/cache_req/cache_req.h | 3 +++ - src/responder/common/cache_req/cache_req_data.c | 12 ++++++++++++ - src/responder/common/cache_req/cache_req_private.h | 2 ++ - 4 files changed, 32 insertions(+) - -diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c -index 5fed7a2ab8beded2fee91f679a12f9a0ff6013ec..110df561101be538e3f0496addfa2e14e42ea918 100644 ---- a/src/responder/common/cache_req/cache_req.c -+++ b/src/responder/common/cache_req/cache_req.c -@@ -142,6 +142,13 @@ cache_req_create(TALLOC_CTX *mem_ctx, - - cr->cache_first = rctx->cache_first; - cr->bypass_cache = cr->plugin->bypass_cache || cr->data->bypass_cache; -+ cr->bypass_dp = cr->data->bypass_dp; -+ if (cr->bypass_cache && cr->bypass_dp) { -+ CACHE_REQ_DEBUG(SSSDBG_CRIT_FAILURE, cr, -+ "Cannot bypass cache and dp at the same time!"); -+ talloc_free(cr); -+ return NULL; -+ } - - return cr; - } -@@ -661,6 +668,14 @@ static bool cache_req_search_schema(struct cache_req *cr, - if (!first_iteration) { - return false; - } -+ } else if (cr->bypass_dp) { -+ /* The caller wants to lookup only in the cache */ -+ bypass_cache = false; -+ bypass_dp = true; -+ -+ if (!first_iteration) { -+ return false; -+ } - } else if (input_domain != NULL) { - /* We will search only one domain. */ - bypass_cache = false; -diff --git a/src/responder/common/cache_req/cache_req.h b/src/responder/common/cache_req/cache_req.h -index c04b2fba6f0445dcfcc9cfe1b5963ac975c39118..2c88853887fc816bba2182d9d9beaa32fa384158 100644 ---- a/src/responder/common/cache_req/cache_req.h -+++ b/src/responder/common/cache_req/cache_req.h -@@ -127,6 +127,9 @@ void - cache_req_data_set_bypass_cache(struct cache_req_data *data, - bool bypass_cache); - -+void -+cache_req_data_set_bypass_dp(struct cache_req_data *data, -+ bool bypass_dp); - /* Output data. */ - - struct cache_req_result { -diff --git a/src/responder/common/cache_req/cache_req_data.c b/src/responder/common/cache_req/cache_req_data.c -index 48264a321dc603f9708ba71c44542363b11a71ba..ed378274a9a0a68ede8ac99805f3ea4a041382e6 100644 ---- a/src/responder/common/cache_req/cache_req_data.c -+++ b/src/responder/common/cache_req/cache_req_data.c -@@ -365,3 +365,15 @@ cache_req_data_set_bypass_cache(struct cache_req_data *data, - - data->bypass_cache = bypass_cache; - } -+ -+void -+cache_req_data_set_bypass_dp(struct cache_req_data *data, -+ bool bypass_dp) -+{ -+ if (data == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "cache_req_data should never be NULL\n"); -+ return; -+ } -+ -+ data->bypass_dp = bypass_dp; -+} -diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h -index 9b706ff7d678f543effb77089857a7e8a42a9c51..0f630542d38a277d1819063fa4134bd7d2525c90 100644 ---- a/src/responder/common/cache_req/cache_req_private.h -+++ b/src/responder/common/cache_req/cache_req_private.h -@@ -42,6 +42,7 @@ struct cache_req { - struct sss_domain_info *domain; - bool cache_first; - bool bypass_cache; -+ bool bypass_dp; - /* Only contact domains with this type */ - enum cache_req_dom_type req_dom_type; - -@@ -90,6 +91,7 @@ struct cache_req_data { - } svc; - - bool bypass_cache; -+ bool bypass_dp; - }; - - struct tevent_req * --- -2.13.6 - diff --git a/SOURCES/0026-KRB5-Allow-writing-multiple-addresses-to-the-kdcinfo.patch b/SOURCES/0026-KRB5-Allow-writing-multiple-addresses-to-the-kdcinfo.patch new file mode 100644 index 0000000..87a0435 --- /dev/null +++ b/SOURCES/0026-KRB5-Allow-writing-multiple-addresses-to-the-kdcinfo.patch @@ -0,0 +1,246 @@ +From 73f452058c8ac83117cb86c12d4d266c8caccc57 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Tue, 26 Jun 2018 10:35:15 +0200 +Subject: [PATCH] KRB5: Allow writing multiple addresses to the kdcinfo plugin + +Turns the previous write_krb5info_file() function into a static function +that writes whatever input it recevies. Adds a wrapper around it that +accepts a list of strings, turns that into a newline-separated string +which is then passed to the original function. + +Related: +https://pagure.io/SSSD/sssd/issue/3291 + +Reviewed-by: Sumit Bose +(cherry picked from commit 8971399c872c21769d5c62cf753c5f9df4caf8cb) +--- + src/providers/ad/ad_common.c | 12 ++--- + src/providers/ipa/ipa_common.c | 8 ++-- + src/providers/krb5/krb5_common.c | 75 +++++++++++++++++++++++++------- + src/providers/krb5/krb5_common.h | 2 +- + 4 files changed, 70 insertions(+), 27 deletions(-) + +diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c +index b103410e5915a380d0404e18da869517e4d4e355..eaf0814f1aaf51a5085e992efa633240f32c498e 100644 +--- a/src/providers/ad/ad_common.c ++++ b/src/providers/ad/ad_common.c +@@ -848,7 +848,7 @@ ad_resolve_callback(void *private_data, struct fo_server *server) + struct resolv_hostent *srvaddr; + struct sockaddr_storage *sockaddr; + char *address; +- const char *safe_address; ++ char *safe_addr_list[2] = { NULL, NULL }; + char *new_uri; + int new_port; + const char *srv_name; +@@ -957,17 +957,17 @@ ad_resolve_callback(void *private_data, struct fo_server *server) + if ((sdata == NULL || sdata->gc == false) && + service->krb5_service->write_kdcinfo) { + /* Write krb5 info files */ +- safe_address = sss_escape_ip_address(tmp_ctx, +- srvaddr->family, +- address); +- if (safe_address == NULL) { ++ safe_addr_list[0] = sss_escape_ip_address(tmp_ctx, ++ srvaddr->family, ++ address); ++ if (safe_addr_list[0] == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "sss_escape_ip_address failed.\n"); + ret = ENOMEM; + goto done; + } + + ret = write_krb5info_file(service->krb5_service, +- safe_address, ++ safe_addr_list, + SSS_KRB5KDC_FO_SRV); + if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, +diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c +index 5808513bfd570c43bc1712114aabba5749ba0fec..0614019764287e5114aa8b8b5c670b717732068b 100644 +--- a/src/providers/ipa/ipa_common.c ++++ b/src/providers/ipa/ipa_common.c +@@ -766,7 +766,7 @@ static void ipa_resolve_callback(void *private_data, struct fo_server *server) + struct resolv_hostent *srvaddr; + struct sockaddr_storage *sockaddr; + char *address; +- const char *safe_address; ++ char *safe_addr_list[2] = { NULL, NULL }; + char *new_uri; + const char *srv_name; + int ret; +@@ -829,17 +829,17 @@ static void ipa_resolve_callback(void *private_data, struct fo_server *server) + service->sdap->sockaddr = talloc_steal(service, sockaddr); + + if (service->krb5_service->write_kdcinfo) { +- safe_address = sss_escape_ip_address(tmp_ctx, ++ safe_addr_list[0] = sss_escape_ip_address(tmp_ctx, + srvaddr->family, + address); +- if (safe_address == NULL) { ++ if (safe_addr_list[0] == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "sss_escape_ip_address failed.\n"); + talloc_free(tmp_ctx); + return; + } + + ret = write_krb5info_file(service->krb5_service, +- safe_address, ++ safe_addr_list, + SSS_KRB5KDC_FO_SRV); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +diff --git a/src/providers/krb5/krb5_common.c b/src/providers/krb5/krb5_common.c +index 2a50dfec55c29b8d7f8b8751c904977c22aa906a..2b003e1642b449e8db20ba4259ba13273e21212f 100644 +--- a/src/providers/krb5/krb5_common.c ++++ b/src/providers/krb5/krb5_common.c +@@ -466,10 +466,9 @@ done: + return ret; + } + +- +-errno_t write_krb5info_file(struct krb5_service *krb5_service, +- const char *server, +- const char *service) ++static errno_t write_krb5info_file_contents(struct krb5_service *krb5_service, ++ const char *contents, ++ const char *service) + { + int ret; + int fd = -1; +@@ -482,7 +481,7 @@ errno_t write_krb5info_file(struct krb5_service *krb5_service, + + if (krb5_service == NULL || krb5_service->realm == NULL + || *krb5_service->realm == '\0' +- || server == NULL || *server == '\0' ++ || contents == NULL || *contents == '\0' + || service == NULL || *service == '\0') { + DEBUG(SSSDBG_CRIT_FAILURE, + "Missing or empty realm, server or service.\n"); +@@ -505,7 +504,7 @@ errno_t write_krb5info_file(struct krb5_service *krb5_service, + return EINVAL; + } + +- server_len = strlen(server); ++ server_len = strlen(contents); + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { +@@ -535,7 +534,7 @@ errno_t write_krb5info_file(struct krb5_service *krb5_service, + } + + errno = 0; +- written = sss_atomic_write_s(fd, discard_const(server), server_len); ++ written = sss_atomic_write_s(fd, discard_const(contents), server_len); + if (written == -1) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, +@@ -592,12 +591,56 @@ done: + return ret; + } + ++errno_t write_krb5info_file(struct krb5_service *krb5_service, ++ char **server_list, ++ const char *service) ++{ ++ int i; ++ errno_t ret; ++ TALLOC_CTX *tmp_ctx = NULL; ++ char *contents = NULL; ++ ++ if (krb5_service == NULL || server_list == NULL || service == NULL) { ++ return EINVAL; ++ } ++ ++ if (server_list[0] == NULL) { ++ return EOK; ++ } ++ ++ tmp_ctx = talloc_new(NULL); ++ if (tmp_ctx == NULL) { ++ return ENOMEM; ++ } ++ ++ contents = talloc_strdup(tmp_ctx, ""); ++ if (contents == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ i = 0; ++ do { ++ contents = talloc_asprintf_append(contents, "%s\n", server_list[i]); ++ if (contents == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ i++; ++ } while (server_list[i] != NULL); ++ ++ ret = write_krb5info_file_contents(krb5_service, contents, service); ++done: ++ talloc_free(tmp_ctx); ++ return ret; ++} ++ + static void krb5_resolve_callback(void *private_data, struct fo_server *server) + { + struct krb5_service *krb5_service; + struct resolv_hostent *srvaddr; + char *address; +- char *safe_address; ++ char *safe_addr_list[2] = { NULL, NULL }; + int ret; + TALLOC_CTX *tmp_ctx = NULL; + +@@ -630,26 +673,26 @@ static void krb5_resolve_callback(void *private_data, struct fo_server *server) + return; + } + +- safe_address = sss_escape_ip_address(tmp_ctx, +- srvaddr->family, +- address); +- if (safe_address == NULL) { ++ safe_addr_list[0] = sss_escape_ip_address(tmp_ctx, ++ srvaddr->family, ++ address); ++ if (safe_addr_list[0] == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "sss_escape_ip_address failed.\n"); + talloc_free(tmp_ctx); + return; + } + + if (krb5_service->write_kdcinfo) { +- safe_address = talloc_asprintf_append(safe_address, ":%d", +- fo_get_server_port(server)); +- if (safe_address == NULL) { ++ safe_addr_list[0] = talloc_asprintf_append(safe_addr_list[0], ":%d", ++ fo_get_server_port(server)); ++ if (safe_addr_list[0] == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n"); + talloc_free(tmp_ctx); + return; + } + + ret = write_krb5info_file(krb5_service, +- safe_address, ++ safe_addr_list, + krb5_service->name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, +diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h +index 1c12d5652ccef7e1738177eedad1c9de543916b7..bf36a551a92877ec838d8d3a041903144f22bc8f 100644 +--- a/src/providers/krb5/krb5_common.h ++++ b/src/providers/krb5/krb5_common.h +@@ -161,7 +161,7 @@ errno_t sss_krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, + const char *conf_path, struct dp_option **_opts); + + errno_t write_krb5info_file(struct krb5_service *krb5_service, +- const char *server, ++ char **server_list, + const char *service); + + struct krb5_service *krb5_service_new(TALLOC_CTX *mem_ctx, +-- +2.17.1 + diff --git a/SOURCES/0027-IPA-Add-the-options-that-the-IPA-subdomains-code-wil.patch b/SOURCES/0027-IPA-Add-the-options-that-the-IPA-subdomains-code-wil.patch new file mode 100644 index 0000000..b000355 --- /dev/null +++ b/SOURCES/0027-IPA-Add-the-options-that-the-IPA-subdomains-code-wil.patch @@ -0,0 +1,67 @@ +From 51354c3e23aa59d88e0340fb7cdbb9b7d4990743 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 25 Jun 2018 13:10:34 +0200 +Subject: [PATCH] IPA: Add the options that the IPA subdomains code will read + for trusted domains on the client + +With this patchset, IPA clients will read and evaluate the ad_server and +ad_site options. This patch just adds the required structures for later +usage. + +Related: +https://pagure.io/SSSD/sssd/issue/3291 + +Reviewed-by: Sumit Bose +(cherry picked from commit 1cce549e0f88f4873c320577d6213dcaeb08766f) +--- + src/providers/ipa/ipa_common.h | 7 +++++++ + src/providers/ipa/ipa_opts.c | 6 ++++++ + src/providers/ipa/ipa_opts.h | 2 ++ + 3 files changed, 15 insertions(+) + +diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h +index 725e0e93728f7643bdf2220a4cb7ecfbbb8b958a..31e671eb50393f77225281226558d9848b3d3d78 100644 +--- a/src/providers/ipa/ipa_common.h ++++ b/src/providers/ipa/ipa_common.h +@@ -175,6 +175,13 @@ enum ipa_sudocmd_attrs { + IPA_OPTS_SUDOCMD + }; + ++enum ipa_cli_ad_subdom_attrs { ++ IPA_CLI_AD_SERVER, ++ IPA_CLI_AD_SITE, ++ ++ IPA_OPTS_CLI_AD_SUBDOM ++}; ++ + struct ipa_auth_ctx { + struct krb5_ctx *krb5_auth_ctx; + struct sdap_id_ctx *sdap_id_ctx; +diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c +index 9419cdcc3913c58e2bcefe238b56fb75e8aa52ec..485ad4fe3ff9808343a94b1792f8c632a3d4b481 100644 +--- a/src/providers/ipa/ipa_opts.c ++++ b/src/providers/ipa/ipa_opts.c +@@ -389,3 +389,9 @@ struct sdap_attr_map ipa_sudocmd_map[] = { + { "ipa_sudocmd_memberof", "memberOf", SYSDB_MEMBEROF, NULL }, + SDAP_ATTR_MAP_TERMINATOR + }; ++ ++struct dp_option ipa_cli_ad_subdom_opts [] = { ++ { "ad_server", DP_OPT_STRING, NULL_STRING, NULL_STRING }, ++ { "ad_site", DP_OPT_STRING, NULL_STRING, NULL_STRING }, ++ DP_OPTION_TERMINATOR ++}; +diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h +index 68326b8649a268232394a8fe970d932feb01d46e..378a9922c7b58fc4374262250efbd61b4b6a932f 100644 +--- a/src/providers/ipa/ipa_opts.h ++++ b/src/providers/ipa/ipa_opts.h +@@ -64,4 +64,6 @@ extern struct sdap_attr_map ipa_sudocmdgroup_map[]; + + extern struct sdap_attr_map ipa_sudocmd_map[]; + ++extern struct dp_option ipa_cli_ad_subdom_opts[]; ++ + #endif /* IPA_OPTS_H_ */ +-- +2.17.1 + diff --git a/SOURCES/0027-nss-make-memcache_delete_entry-public.patch b/SOURCES/0027-nss-make-memcache_delete_entry-public.patch deleted file mode 100644 index 6d0c026..0000000 --- a/SOURCES/0027-nss-make-memcache_delete_entry-public.patch +++ /dev/null @@ -1,49 +0,0 @@ -From fd798bd98d932bc847afc60817f5fdb744eee2a4 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 24 Oct 2017 12:50:43 +0200 -Subject: [PATCH 27/31] nss: make memcache_delete_entry() public - -Related to https://pagure.io/SSSD/sssd/issue/2478 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit a7d6ca275d6b2e5d396cbefb18d0ee880011e271) ---- - src/responder/nss/nss_get_object.c | 2 +- - src/responder/nss/nss_private.h | 8 ++++++++ - 2 files changed, 9 insertions(+), 1 deletion(-) - -diff --git a/src/responder/nss/nss_get_object.c b/src/responder/nss/nss_get_object.c -index e56480af5e3369963d2e8bb17d74d1603af8e014..15faced006f754134415e766284377f0c86af0ac 100644 ---- a/src/responder/nss/nss_get_object.c -+++ b/src/responder/nss/nss_get_object.c -@@ -86,7 +86,7 @@ memcache_delete_entry_by_id(struct nss_ctx *nss_ctx, - return ret; - } - --static errno_t -+errno_t - memcache_delete_entry(struct nss_ctx *nss_ctx, - struct resp_ctx *rctx, - struct sss_domain_info *domain, -diff --git a/src/responder/nss/nss_private.h b/src/responder/nss/nss_private.h -index a0b573d6ecba2d8ba6f55db0adcd7ee29cbec991..5fc19d26be9adda4d967086e7b239e49a78866ee 100644 ---- a/src/responder/nss/nss_private.h -+++ b/src/responder/nss/nss_private.h -@@ -92,6 +92,14 @@ struct sss_cmd_table *get_nss_cmds(void); - - int nss_connection_setup(struct cli_ctx *cli_ctx); - -+errno_t -+memcache_delete_entry(struct nss_ctx *nss_ctx, -+ struct resp_ctx *rctx, -+ struct sss_domain_info *domain, -+ const char *name, -+ uint32_t id, -+ enum sss_mc_type type); -+ - struct tevent_req * - nss_get_object_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, --- -2.13.6 - diff --git a/SOURCES/0028-IPA-Populate-kdcinfo-files-on-trust-clients-with-con.patch b/SOURCES/0028-IPA-Populate-kdcinfo-files-on-trust-clients-with-con.patch new file mode 100644 index 0000000..abbcae1 --- /dev/null +++ b/SOURCES/0028-IPA-Populate-kdcinfo-files-on-trust-clients-with-con.patch @@ -0,0 +1,800 @@ +From f1780cea77deb98789cc9c53cb6d7c83e2931e70 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Mon, 25 Jun 2018 13:10:39 +0200 +Subject: [PATCH] IPA: Populate kdcinfo files on trust clients with configured + AD servers + +Resolves: +https://pagure.io/SSSD/sssd/issue/3291 + +Adds a new request into the IPA subdomains provider. This request runs on +IPA clients only. + +The request looks into the configuration for either the ad_site or ad_server +options for each subdomain. If none are found, the subdomain is skipped. + +If either is found, the request resolves the server names, or first the +site and then the server names from the site and writes their addresses +to the kdcinfo files for each subdomain. This allows programs such as +kinit but also SSSD's krb5_child to use the configured servers. + +Reviewed-by: Sumit Bose +(cherry picked from commit 18b7f0a30b4745b7d61b3e599e5fb8cd399c23f3) +--- + src/providers/ipa/ipa_subdomains.c | 718 ++++++++++++++++++++++++++++- + 1 file changed, 716 insertions(+), 2 deletions(-) + +diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c +index a8a18ad8a3ec08c137994a84d51851e996aad6dc..1b443559eada3b8feeb9c91fbebd4e2dcca87a23 100644 +--- a/src/providers/ipa/ipa_subdomains.c ++++ b/src/providers/ipa/ipa_subdomains.c +@@ -76,6 +76,18 @@ + "("IPA_ENABLED_FLAG"="IPA_TRUE_VALUE"))" \ + "("OBJECTCLASS"="IPA_OC_CERTMAP_CONFIG_OBJECT"))" + ++/* It doesn't make sense to resolve more servers than this from the SRV ++ * lookup because kinit would time out before we are able to cycle ++ * through the whole list ++ */ ++#define MAX_SERVERS_FROM_SRV 5 ++ ++struct ipa_sd_k5_svc_list { ++ struct krb5_service *k5svc; ++ ++ struct ipa_sd_k5_svc_list *next; ++ struct ipa_sd_k5_svc_list *prev; ++}; + + struct ipa_subdomains_ctx { + struct be_ctx *be_ctx; +@@ -88,6 +100,11 @@ struct ipa_subdomains_ctx { + + time_t last_refreshed; + bool view_read_at_init; ++ /* List of krb5_service structures for each subdomain ++ * in order to write the kdcinfo files. For use on ++ * the client only ++ */ ++ struct ipa_sd_k5_svc_list *k5svc_list; + }; + + static errno_t +@@ -635,6 +652,69 @@ done: + return ret; + } + ++static struct krb5_service * ++ipa_subdom_get_k5_svc(struct ipa_subdomains_ctx *ctx, ++ struct sss_domain_info *dom, ++ bool use_kdcinfo) ++{ ++ struct ipa_sd_k5_svc_list *k5svc_ent; ++ ++ /* get the service by realm */ ++ DLIST_FOR_EACH(k5svc_ent, ctx->k5svc_list) { ++ if (strcasecmp(dom->realm, k5svc_ent->k5svc->realm) == 0) { ++ break; ++ } ++ } ++ ++ if (k5svc_ent != NULL) { ++ /* Already exists */ ++ return k5svc_ent->k5svc; ++ } ++ ++ /* Create a new service */ ++ k5svc_ent = talloc_zero(ctx, struct ipa_sd_k5_svc_list); ++ if (k5svc_ent == NULL) { ++ return NULL; ++ } ++ ++ k5svc_ent->k5svc = krb5_service_new(k5svc_ent, ++ ctx->be_ctx, ++ "IPA", ++ dom->realm, ++ use_kdcinfo); ++ if (k5svc_ent->k5svc == NULL) { ++ talloc_free(k5svc_ent); ++ return NULL; ++ } ++ DLIST_ADD(ctx->k5svc_list, k5svc_ent); ++ ++ return k5svc_ent->k5svc; ++} ++ ++static void ipa_subdom_remove_k5_svc(struct ipa_subdomains_ctx *ctx) ++{ ++ /* Domain going away is such a rare operation that it makes ++ * more sense to just throw away the whole k5svc_list and let ++ * the write_kdcinfo request recreate them all again instead ++ * of coding up complex logic.. ++ */ ++ talloc_zfree(ctx->k5svc_list); ++} ++ ++static void ipa_subdom_remove_step(struct ipa_subdomains_ctx *ctx, ++ struct sss_domain_info *dom) ++{ ++ if (dp_opt_get_bool(ctx->ipa_id_ctx->ipa_options->basic, ++ IPA_SERVER_MODE) == false) { ++ /* IPA clients keep track of krb5_service wrappers */ ++ return ipa_subdom_remove_k5_svc(ctx); ++ } else { ++ /* IPA servers keeps track of AD contexts */ ++ return ipa_ad_subdom_remove(ctx->be_ctx, ctx->ipa_id_ctx, dom); ++ } ++ ++} ++ + static void ipa_subdom_store_step(struct sss_domain_info *parent, + struct ipa_id_ctx *id_ctx, + struct sdap_idmap_ctx *sdap_idmap_ctx, +@@ -697,8 +777,7 @@ static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx, + goto done; + } + +- /* Remove the AD ID ctx from the list of LDAP domains */ +- ipa_ad_subdom_remove(ctx->be_ctx, ctx->ipa_id_ctx, dom); ++ ipa_subdom_remove_step(ctx, dom); + } else { + /* ok let's try to update it */ + ipa_subdom_store_step(parent, ctx->ipa_id_ctx, +@@ -1917,6 +1996,611 @@ static errno_t ipa_domain_resolution_order_recv(struct tevent_req *req) + return EOK; + } + ++struct kdcinfo_from_server_list_state { ++ struct resolv_hostport *hostport_list; ++ enum host_database db[2]; ++ ++ struct resolv_hostport_addr **rhp_addrs; ++ size_t rhp_len; ++}; ++ ++static void kdcinfo_from_server_list_done(struct tevent_req *subreq); ++ ++static struct tevent_req * ++kdcinfo_from_server_list_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_resolv_ctx *be_res, ++ const char *servers) ++{ ++ struct kdcinfo_from_server_list_state *state; ++ struct tevent_req *req; ++ struct tevent_req *subreq; ++ errno_t ret; ++ int server_list_len; ++ char **server_list; ++ ++ req = tevent_req_create(mem_ctx, &state, ++ struct kdcinfo_from_server_list_state); ++ if (req == NULL) { ++ return NULL; ++ } ++ state->db[0] = DB_DNS; ++ state->db[1] = DB_SENTINEL; ++ ++ if (servers == NULL) { ++ ret = EOK; ++ goto immediately; ++ } ++ ++ ret = split_on_separator(state, servers, ',', true, true, ++ &server_list, ++ &server_list_len); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, "Failed to parse server list!\n"); ++ goto immediately; ++ } ++ ++ state->hostport_list = talloc_array(state, ++ struct resolv_hostport, ++ server_list_len); ++ if (state->hostport_list == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } ++ ++ for (int i = 0; i < server_list_len; i++) { ++ state->hostport_list[i].host = server_list[i]; ++ state->hostport_list[i].port = 0; ++ } ++ ++ subreq = resolv_hostport_list_send(state, ++ ev, ++ be_res->resolv, ++ state->hostport_list, ++ server_list_len, ++ 0, ++ be_res->family_order, ++ state->db); ++ if (subreq == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } ++ tevent_req_set_callback(subreq, kdcinfo_from_server_list_done, req); ++ return req; ++ ++immediately: ++ if (ret != EOK) { ++ tevent_req_error(req, ret); ++ } else { ++ tevent_req_done(req); ++ } ++ tevent_req_post(req, ev); ++ return req; ++} ++ ++static void kdcinfo_from_server_list_done(struct tevent_req *subreq) ++{ ++ errno_t ret; ++ struct tevent_req *req = ++ tevent_req_callback_data(subreq, struct tevent_req); ++ struct kdcinfo_from_server_list_state *state = tevent_req_data(req, ++ struct kdcinfo_from_server_list_state); ++ ++ ret = resolv_hostport_list_recv(subreq, ++ state, ++ &state->rhp_len, ++ &state->rhp_addrs); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Failed to resolve address list [%d]: %s\n", ret, sss_strerror(ret)); ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ tevent_req_done(req); ++} ++ ++static errno_t kdcinfo_from_server_list_recv(TALLOC_CTX *mem_ctx, ++ struct tevent_req *req, ++ struct resolv_hostport_addr ***_rhp_addrs, ++ size_t *_rhp_len) ++{ ++ struct kdcinfo_from_server_list_state *state = tevent_req_data(req, ++ struct kdcinfo_from_server_list_state); ++ ++ TEVENT_REQ_RETURN_ON_ERROR(req); ++ ++ if (_rhp_addrs != NULL) { ++ *_rhp_addrs = talloc_steal(mem_ctx, state->rhp_addrs); ++ } ++ ++ if (_rhp_len != NULL) { ++ *_rhp_len = state->rhp_len; ++ } ++ ++ return EOK; ++} ++ ++struct kdcinfo_from_site_state { ++ struct tevent_context *ev; ++ struct be_resolv_ctx *be_res; ++ ++ const char *discovery_domains[2]; ++ struct resolv_hostport *hostport_list; ++ enum host_database db[2]; ++ ++ struct resolv_hostport_addr **rhp_addrs; ++ size_t rhp_len; ++}; ++ ++static void kdcinfo_from_site_srv_done(struct tevent_req *subreq); ++static void kdcinfo_from_site_server_list_done(struct tevent_req *subreq); ++ ++static struct tevent_req * ++kdcinfo_from_site_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct be_resolv_ctx *be_res, ++ const char *site, ++ const char *domain) ++{ ++ struct kdcinfo_from_site_state *state; ++ struct tevent_req *req; ++ struct tevent_req *subreq; ++ errno_t ret; ++ ++ req = tevent_req_create(mem_ctx, &state, ++ struct kdcinfo_from_site_state); ++ if (req == NULL) { ++ return NULL; ++ } ++ state->ev = ev; ++ state->be_res = be_res; ++ state->db[0] = DB_DNS; ++ state->db[1] = DB_SENTINEL; ++ ++ state->discovery_domains[0] = ad_site_dns_discovery_domain(state, ++ site, ++ domain); ++ if (state->discovery_domains[0] == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } ++ state->discovery_domains[1] = NULL; ++ ++ subreq = fo_discover_srv_send(state, ++ state->ev, ++ state->be_res->resolv, ++ "kerberos", "tcp", ++ state->discovery_domains); ++ if (subreq == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } ++ tevent_req_set_callback(subreq, kdcinfo_from_site_srv_done, req); ++ return req; ++ ++immediately: ++ if (ret != EOK) { ++ tevent_req_error(req, ret); ++ } else { ++ tevent_req_done(req); ++ } ++ tevent_req_post(req, ev); ++ return req; ++} ++ ++static void kdcinfo_from_site_srv_done(struct tevent_req *subreq) ++{ ++ errno_t ret; ++ struct tevent_req *req = ++ tevent_req_callback_data(subreq, struct tevent_req); ++ struct kdcinfo_from_site_state *state = tevent_req_data(req, ++ struct kdcinfo_from_site_state); ++ struct fo_server_info *servers; ++ size_t num_servers; ++ ++ ret = fo_discover_srv_recv(state, subreq, ++ NULL, NULL, /* not interested in TTL etc */ ++ &servers, &num_servers); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Could not resolve the site [%d]: %s\n", ret, sss_strerror(ret)); ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ state->hostport_list = talloc_array(state, ++ struct resolv_hostport, ++ num_servers); ++ if (state->hostport_list == NULL) { ++ tevent_req_error(req, ENOMEM); ++ return; ++ } ++ ++ for (size_t i = 0; i < num_servers; i++) { ++ state->hostport_list[i].host = servers[i].host; ++ state->hostport_list[i].port = servers[i].port; ++ } ++ ++ subreq = resolv_hostport_list_send(state, ++ state->ev, ++ state->be_res->resolv, ++ state->hostport_list, ++ num_servers, ++ MAX_SERVERS_FROM_SRV, ++ state->be_res->family_order, ++ state->db); ++ if (subreq == NULL) { ++ tevent_req_error(req, ENOMEM); ++ return; ++ } ++ tevent_req_set_callback(subreq, kdcinfo_from_site_server_list_done, req); ++} ++ ++static void kdcinfo_from_site_server_list_done(struct tevent_req *subreq) ++{ ++ errno_t ret; ++ struct tevent_req *req = ++ tevent_req_callback_data(subreq, struct tevent_req); ++ struct kdcinfo_from_site_state *state = tevent_req_data(req, ++ struct kdcinfo_from_site_state); ++ ++ ret = resolv_hostport_list_recv(subreq, ++ state, ++ &state->rhp_len, ++ &state->rhp_addrs); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "Failed to resolve address list [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ tevent_req_done(req); ++} ++ ++ ++static errno_t kdcinfo_from_site_recv(TALLOC_CTX *mem_ctx, ++ struct tevent_req *req, ++ struct resolv_hostport_addr ***_rhp_addrs, ++ size_t *_rhp_len) ++{ ++ struct kdcinfo_from_site_state *state = tevent_req_data(req, ++ struct kdcinfo_from_site_state); ++ ++ TEVENT_REQ_RETURN_ON_ERROR(req); ++ ++ if (_rhp_addrs != NULL) { ++ *_rhp_addrs = talloc_steal(mem_ctx, state->rhp_addrs); ++ } ++ ++ if (_rhp_len != NULL) { ++ *_rhp_len = state->rhp_len; ++ } ++ ++ return EOK; ++} ++ ++/* Anything per-domain in this request goes here so that we ++ * can just free the whole struct without mixing data from ++ * different domains or the overhead of another request ++ */ ++struct ipa_sd_per_dom_kdcinfo_ctx { ++ struct sss_domain_info *dom; ++ ++ const char *servers; ++ const char *site; ++ ++ const char *discovery_domains[2]; ++ struct krb5_service *krb5_service; ++}; ++ ++struct ipa_subdomains_write_kdcinfo_state { ++ struct tevent_context *ev; ++ struct ipa_subdomains_ctx *ipa_sd_ctx; ++ struct be_ctx *be_ctx; ++ ++ bool use_kdcinfo; ++ struct ipa_sd_per_dom_kdcinfo_ctx *pdctx; ++}; ++ ++static errno_t ipa_subdomains_write_kdcinfo_domain_step(struct sss_domain_info *start_dom, ++ struct tevent_req *req); ++static void ipa_subdomains_write_kdcinfo_domain_done(struct tevent_req *subreq); ++static errno_t ipa_subdomains_write_kdcinfo_write_step(struct sss_domain_info *dom, ++ struct krb5_service *krb5_service, ++ struct resolv_hostport_addr **rhp_addrs, ++ size_t rhp_len); ++ ++static struct tevent_req * ++ipa_subdomains_write_kdcinfo_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct ipa_subdomains_ctx *ipa_sd_ctx, ++ struct be_ctx *be_ctx) ++{ ++ struct ipa_subdomains_write_kdcinfo_state *state; ++ struct tevent_req *req; ++ errno_t ret; ++ ++ req = tevent_req_create(mem_ctx, &state, ++ struct ipa_subdomains_write_kdcinfo_state); ++ if (req == NULL) { ++ return NULL; ++ } ++ state->ev = ev; ++ state->ipa_sd_ctx = ipa_sd_ctx; ++ state->be_ctx = be_ctx; ++ ++ if (ipa_sd_ctx->ipa_id_ctx->server_mode != NULL) { ++ /* This request is valid for clients only */ ++ ret = EOK; ++ goto immediately; ++ } ++ ++ state->use_kdcinfo = dp_opt_get_bool(ipa_sd_ctx->ipa_id_ctx->ipa_options->auth, ++ KRB5_USE_KDCINFO); ++ if (state->use_kdcinfo == false) { ++ DEBUG(SSSDBG_CONF_SETTINGS, "kdcinfo creation disabled\n"); ++ ret = EOK; ++ goto immediately; ++ } ++ ++ if (be_ctx->domain->subdomains == NULL) { ++ DEBUG(SSSDBG_CONF_SETTINGS, "No subdomains, done\n"); ++ ret = EOK; ++ goto immediately; ++ } ++ ++ ret = ipa_subdomains_write_kdcinfo_domain_step(be_ctx->domain->subdomains, ++ req); ++ if (ret != EAGAIN) { ++ goto immediately; ++ } ++ return req; ++ ++immediately: ++ if (ret == EOK) { ++ tevent_req_done(req); ++ } else { ++ tevent_req_error(req, ret); ++ } ++ tevent_req_post(req, ev); ++ return req; ++} ++ ++static errno_t ipa_subdomains_write_kdcinfo_domain_step(struct sss_domain_info *start_dom, ++ struct tevent_req *req) ++{ ++ struct ipa_subdomains_write_kdcinfo_state *state = \ ++ tevent_req_data(req, ++ struct ipa_subdomains_write_kdcinfo_state); ++ struct dp_option *ipa_ad_subdom_opts; ++ struct tevent_req *subreq = NULL; ++ char *subdom_conf_path; ++ errno_t ret; ++ const char *servers; ++ const char *site; ++ ++ for (struct sss_domain_info *dom = start_dom; ++ dom != NULL; ++ dom = get_next_domain(dom, 0)) { ++ ++ talloc_zfree(state->pdctx); ++ ++ subdom_conf_path = subdomain_create_conf_path(state, dom); ++ if (subdom_conf_path == NULL) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "subdom_conf_path failed for %s\n", dom->name); ++ /* Not fatal */ ++ continue; ++ } ++ ++ ret = dp_get_options(state, state->be_ctx->cdb, ++ subdom_conf_path, ++ ipa_cli_ad_subdom_opts, ++ IPA_OPTS_CLI_AD_SUBDOM, ++ &ipa_ad_subdom_opts); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Cannot get options for %s: [%d]: %s\n", ++ dom->name, ret, sss_strerror(ret)); ++ /* Not fatal */ ++ continue; ++ } ++ ++ servers = dp_opt_get_string(ipa_ad_subdom_opts, IPA_CLI_AD_SERVER); ++ site = dp_opt_get_string(ipa_ad_subdom_opts, IPA_CLI_AD_SITE); ++ ++ if (servers == NULL && site == NULL) { ++ /* If neither is set, just go to the next domain */ ++ DEBUG(SSSDBG_TRACE_INTERNAL, ++ "No site or server defined for %s, skipping\n", ++ dom->name); ++ continue; ++ } ++ ++ /* We will resolve this domain, create a per-domain context */ ++ state->pdctx = talloc_zero(state, struct ipa_sd_per_dom_kdcinfo_ctx); ++ if (state->pdctx == NULL) { ++ return ENOMEM; ++ } ++ state->pdctx->dom = dom; ++ state->pdctx->servers = servers; ++ state->pdctx->site = site; ++ state->pdctx->krb5_service = ipa_subdom_get_k5_svc(state->ipa_sd_ctx, ++ dom, ++ state->use_kdcinfo); ++ if (state->pdctx->krb5_service == NULL) { ++ continue; ++ } ++ ++ if (state->pdctx->servers != NULL) { ++ DEBUG(SSSDBG_CONF_SETTINGS, ++ "Resolving servers [%s] for domain %s\n", ++ state->pdctx->servers, dom->name); ++ ++ subreq = kdcinfo_from_server_list_send(state, ++ state->ev, ++ state->be_ctx->be_res, ++ state->pdctx->servers); ++ } else if (state->pdctx->site != NULL) { ++ DEBUG(SSSDBG_CONF_SETTINGS, ++ "Resolving site %s for domain %s\n", ++ state->pdctx->site, dom->name); ++ ++ subreq = kdcinfo_from_site_send(state, ++ state->ev, ++ state->be_ctx->be_res, ++ state->pdctx->site, ++ state->pdctx->dom->name); ++ } else { ++ /* We should never get here */ ++ return EINVAL; ++ } ++ ++ if (subreq == NULL) { ++ return ENOMEM; ++ } ++ tevent_req_set_callback(subreq, ipa_subdomains_write_kdcinfo_domain_done, req); ++ return EAGAIN; ++ } ++ ++ return EOK; ++} ++ ++static void ipa_subdomains_write_kdcinfo_domain_done(struct tevent_req *subreq) ++{ ++ errno_t ret; ++ struct tevent_req *req = ++ tevent_req_callback_data(subreq, struct tevent_req); ++ struct ipa_subdomains_write_kdcinfo_state *state = \ ++ tevent_req_data(req, ++ struct ipa_subdomains_write_kdcinfo_state); ++ struct sss_domain_info *next_domain; ++ struct resolv_hostport_addr **rhp_addrs; ++ size_t rhp_len; ++ ++ if (state->pdctx->servers != NULL) { ++ ret = kdcinfo_from_server_list_recv(state->pdctx, subreq, ++ &rhp_addrs, &rhp_len); ++ } else if (state->pdctx->site != NULL) { ++ ret = kdcinfo_from_site_recv(state->pdctx, subreq, ++ &rhp_addrs, &rhp_len); ++ } else { ++ DEBUG(SSSDBG_CRIT_FAILURE, "Neither site nor servers set\n"); ++ ret = EINVAL; ++ } ++ ++ if (ret == EOK) { ++ ret = ipa_subdomains_write_kdcinfo_write_step(state->pdctx->dom, ++ state->pdctx->krb5_service, ++ rhp_addrs, rhp_len); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Could not write kdcinfo file for %s\n", state->pdctx->dom->name); ++ /* Not fatal, loop to the next domain below */ ++ } ++ } else { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Could not get address list for %s\n", state->pdctx->dom->name); ++ /* Not fatal, loop to the next domain below */ ++ } ++ ++ next_domain = get_next_domain(state->pdctx->dom, 0); ++ ret = ipa_subdomains_write_kdcinfo_domain_step(next_domain, req); ++ if (ret == EOK) { ++ tevent_req_done(req); ++ return; ++ } else if (ret != EAGAIN) { ++ /* the loop in ipa_subdomains_write_kdcinfo_domain_step already ++ * tries to be quite permissive, so any error is fatal ++ */ ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ /* Continue to the next domain */ ++} ++ ++static errno_t ipa_subdomains_write_kdcinfo_write_step(struct sss_domain_info *dom, ++ struct krb5_service *krb5_service, ++ struct resolv_hostport_addr **rhp_addrs, ++ size_t rhp_len) ++{ ++ errno_t ret; ++ char *address = NULL; ++ char *safe_address = NULL; ++ char **safe_addr_list; ++ int addr_index = 0; ++ TALLOC_CTX *tmp_ctx = NULL; ++ ++ tmp_ctx = talloc_new(NULL); ++ if (tmp_ctx == NULL) { ++ return ENOMEM; ++ } ++ ++ safe_addr_list = talloc_zero_array(tmp_ctx, char *, rhp_len+1); ++ if (safe_addr_list == NULL) { ++ ret = ENOMEM; ++ goto done; ++ } ++ ++ for (size_t i = 0; i < rhp_len; i++) { ++ address = resolv_get_string_address(tmp_ctx, rhp_addrs[i]->reply); ++ if (address == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "resolv_get_string_address failed.\n"); ++ continue; ++ } ++ ++ if (rhp_addrs[i]->origin.port != 0) { ++ address = talloc_asprintf_append(address, ++ ":%d", ++ rhp_addrs[i]->origin.port); ++ } ++ ++ safe_address = sss_escape_ip_address(tmp_ctx, ++ rhp_addrs[i]->reply->family, ++ address); ++ talloc_zfree(address); ++ if (safe_address == NULL) { ++ DEBUG(SSSDBG_CRIT_FAILURE, "sss_escape_ip_address failed.\n"); ++ continue; ++ } ++ ++ DEBUG(SSSDBG_CONF_SETTINGS, ++ "Will write [%s] for %s\n", ++ safe_address, dom->name); ++ ++ safe_addr_list[addr_index] = talloc_steal(safe_addr_list, ++ safe_address); ++ addr_index++; ++ } ++ ++ ret = write_krb5info_file(krb5_service, ++ safe_addr_list, ++ SSS_KRB5KDC_FO_SRV); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "write_krb5info_file failed, authentication might fail.\n"); ++ goto done; ++ } ++ ++ ret = EOK; ++done: ++ talloc_free(tmp_ctx); ++ return ret; ++} ++ ++static errno_t ipa_subdomains_write_kdcinfo_recv(struct tevent_req *req) ++{ ++ TEVENT_REQ_RETURN_ON_ERROR(req); ++ return EOK; ++} ++ + struct ipa_subdomains_refresh_state { + struct tevent_context *ev; + struct ipa_subdomains_ctx *sd_ctx; +@@ -1933,6 +2617,7 @@ static void ipa_subdomains_refresh_view_name_done(struct tevent_req *subreq); + static void ipa_subdomains_refresh_view_domain_resolution_order_done( + struct tevent_req *subreq); + static void ipa_domain_refresh_resolution_order_done(struct tevent_req *subreq); ++static void ipa_domain_refresh_kdcinfo_done(struct tevent_req *subreq); + + static struct tevent_req * + ipa_subdomains_refresh_send(TALLOC_CTX *mem_ctx, +@@ -2253,6 +2938,35 @@ ipa_domain_refresh_resolution_order_done(struct tevent_req *subreq) + return; + } + ++ subreq = ipa_subdomains_write_kdcinfo_send(state, ++ state->ev, ++ state->sd_ctx, ++ state->sd_ctx->be_ctx); ++ if (subreq == NULL) { ++ tevent_req_error(req, ENOMEM); ++ return; ++ } ++ tevent_req_set_callback(subreq, ipa_domain_refresh_kdcinfo_done, req); ++} ++ ++static void ++ipa_domain_refresh_kdcinfo_done(struct tevent_req *subreq) ++{ ++ struct tevent_req *req; ++ errno_t ret; ++ ++ req = tevent_req_callback_data(subreq, struct tevent_req); ++ ++ ret = ipa_subdomains_write_kdcinfo_recv(subreq); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Unable to write the kdc info files, authentication might " ++ "fail or time out [%d]: %s\n", ++ ret, sss_strerror(ret)); ++ /* Not fatal, let's hope DNS is set correctly */ ++ } ++ + tevent_req_done(req); + } + +-- +2.17.1 + diff --git a/SOURCES/0028-NSS-add-support-for-SSS_NSS_EX_FLAG_INVALIDATE_CACHE.patch b/SOURCES/0028-NSS-add-support-for-SSS_NSS_EX_FLAG_INVALIDATE_CACHE.patch deleted file mode 100644 index 04cc5a0..0000000 --- a/SOURCES/0028-NSS-add-support-for-SSS_NSS_EX_FLAG_INVALIDATE_CACHE.patch +++ /dev/null @@ -1,365 +0,0 @@ -From fe54de0824cac1822d6f9485165adc64bf4e0fa7 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 24 Oct 2017 14:10:53 +0200 -Subject: [PATCH 28/31] NSS: add support for SSS_NSS_EX_FLAG_INVALIDATE_CACHE - -The patch adds support for the SSS_NSS_EX_FLAG_INVALIDATE_CACHE flag and -makes the existing code more flexible and handle additional flags. - -If SSS_NSS_EX_FLAG_INVALIDATE_CACHE is set the requested object is only -looked up in the cache and if it was found on-disk and memory cache -entries will be invalidated. - -Related to https://pagure.io/SSSD/sssd/issue/2478 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 55f7d8034d783c01789d76a2b9ffc901045e8af8) ---- - src/responder/nss/nss_cmd.c | 141 +++++++++++++++++++++++++++++++-- - src/responder/nss/nss_protocol.c | 1 + - src/responder/nss/nss_protocol.h | 1 + - src/responder/nss/nss_protocol_grent.c | 9 ++- - src/responder/nss/nss_protocol_pwent.c | 6 +- - src/sss_client/idmap/sss_nss_ex.c | 20 ++++- - src/sss_client/idmap/sss_nss_idmap.h | 8 +- - 7 files changed, 171 insertions(+), 15 deletions(-) - -diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c -index c5ddd2f2cc2122cd169ea991b94a14eb5bad095f..545257a0be7e91e9de767a57848bb77c5791db4e 100644 ---- a/src/responder/nss/nss_cmd.c -+++ b/src/responder/nss/nss_cmd.c -@@ -50,6 +50,26 @@ nss_cmd_ctx_create(TALLOC_CTX *mem_ctx, - return cmd_ctx; - } - -+static errno_t eval_flags(struct nss_cmd_ctx *cmd_ctx, -+ struct cache_req_data *data) -+{ -+ if ((cmd_ctx->flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0 -+ && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Flags SSS_NSS_EX_FLAG_NO_CACHE and " -+ "SSS_NSS_EX_FLAG_INVALIDATE_CACHE are " -+ "mutually exclusive.\n"); -+ return EINVAL; -+ } -+ -+ if ((cmd_ctx->flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) { -+ cache_req_data_set_bypass_cache(data, true); -+ } else if ((cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) { -+ cache_req_data_set_bypass_dp(data, true); -+ } -+ -+ return EOK; -+} -+ - static void nss_getby_done(struct tevent_req *subreq); - static void nss_getlistby_done(struct tevent_req *subreq); - -@@ -65,7 +85,6 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx, - struct tevent_req *subreq; - const char *rawname; - errno_t ret; -- uint32_t flags = 0; - - cmd_ctx = nss_cmd_ctx_create(cli_ctx, cli_ctx, type, fill_fn); - if (cmd_ctx == NULL) { -@@ -73,8 +92,9 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx, - goto done; - } - -+ cmd_ctx->flags = 0; - if (ex_version) { -- ret = nss_protocol_parse_name_ex(cli_ctx, &rawname, &flags); -+ ret = nss_protocol_parse_name_ex(cli_ctx, &rawname, &cmd_ctx->flags); - } else { - ret = nss_protocol_parse_name(cli_ctx, &rawname); - } -@@ -92,8 +112,10 @@ static errno_t nss_getby_name(struct cli_ctx *cli_ctx, - goto done; - } - -- if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) { -- cache_req_data_set_bypass_cache(data, true); -+ ret = eval_flags(cmd_ctx, data); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "eval_flags failed.\n"); -+ goto done; - } - - subreq = nss_get_object_send(cmd_ctx, cli_ctx->ev, cli_ctx, -@@ -129,7 +151,6 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx, - struct tevent_req *subreq; - uint32_t id; - errno_t ret; -- uint32_t flags = 0; - - cmd_ctx = nss_cmd_ctx_create(cli_ctx, cli_ctx, type, fill_fn); - if (cmd_ctx == NULL) { -@@ -138,7 +159,7 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx, - } - - if (ex_version) { -- ret = nss_protocol_parse_id_ex(cli_ctx, &id, &flags); -+ ret = nss_protocol_parse_id_ex(cli_ctx, &id, &cmd_ctx->flags); - } else { - ret = nss_protocol_parse_id(cli_ctx, &id); - } -@@ -156,8 +177,10 @@ static errno_t nss_getby_id(struct cli_ctx *cli_ctx, - goto done; - } - -- if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) { -- cache_req_data_set_bypass_cache(data, true); -+ ret = eval_flags(cmd_ctx, data); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "eval_flags failed.\n"); -+ goto done; - } - - subreq = nss_get_object_send(cmd_ctx, cli_ctx->ev, cli_ctx, -@@ -425,6 +448,98 @@ done: - return EOK; - } - -+static errno_t invalidate_cache(struct nss_cmd_ctx *cmd_ctx, -+ struct cache_req_result *result) -+{ -+ int ret; -+ enum sss_mc_type memcache_type; -+ const char *name; -+ char *output_name = NULL; -+ bool is_user; -+ struct sysdb_attrs *attrs = NULL; -+ -+ switch (cmd_ctx->type) { -+ case CACHE_REQ_INITGROUPS: -+ case CACHE_REQ_INITGROUPS_BY_UPN: -+ memcache_type = SSS_MC_INITGROUPS; -+ is_user = true; -+ break; -+ case CACHE_REQ_USER_BY_NAME: -+ case CACHE_REQ_USER_BY_ID: -+ memcache_type = SSS_MC_PASSWD; -+ is_user = true; -+ break; -+ case CACHE_REQ_GROUP_BY_NAME: -+ case CACHE_REQ_GROUP_BY_ID: -+ memcache_type = SSS_MC_GROUP; -+ is_user = false; -+ break; -+ default: -+ /* nothing to do */ -+ return EOK; -+ } -+ -+ /* Find output name to invalidate memory cache entry*/ -+ name = sss_get_name_from_msg(result->domain, result->msgs[0]); -+ if (name == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Found object has no name.\n"); -+ return EINVAL; -+ } -+ ret = sss_output_fqname(cmd_ctx, result->domain, name, -+ cmd_ctx->nss_ctx->rctx->override_space, -+ &output_name); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_output_fqname failed.\n"); -+ return ret; -+ } -+ -+ memcache_delete_entry(cmd_ctx->nss_ctx, cmd_ctx->nss_ctx->rctx, NULL, -+ output_name, 0, memcache_type); -+ if (memcache_type == SSS_MC_INITGROUPS) { -+ /* Invalidate the passwd data as well */ -+ memcache_delete_entry(cmd_ctx->nss_ctx, cmd_ctx->nss_ctx->rctx, -+ result->domain, output_name, 0, SSS_MC_PASSWD); -+ } -+ talloc_free(output_name); -+ -+ /* Use sysdb name to invalidate disk cache entry */ -+ name = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_NAME, NULL); -+ if (name == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Found object has no name.\n"); -+ return EINVAL; -+ } -+ -+ if (memcache_type == SSS_MC_INITGROUPS) { -+ attrs = sysdb_new_attrs(cmd_ctx); -+ if (attrs == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_new_attrs failed.\n"); -+ return ENOMEM; -+ } -+ -+ ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, 1); -+ if (ret != EOK) { -+ talloc_free(attrs); -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_time_t failed.\n"); -+ return ret; -+ } -+ -+ ret = sysdb_set_user_attr(result->domain, name, attrs, SYSDB_MOD_REP); -+ talloc_free(attrs); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_set_user_attr failed.\n"); -+ return ret; -+ } -+ } -+ -+ ret = sysdb_invalidate_cache_entry(result->domain, name, is_user); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_invalidate_cache_entry failed.\n"); -+ return ret; -+ } -+ -+ return EOK; -+} -+ - static void nss_getby_done(struct tevent_req *subreq) - { - struct cache_req_result *result; -@@ -440,6 +555,16 @@ static void nss_getby_done(struct tevent_req *subreq) - goto done; - } - -+ if ((cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) { -+ ret = invalidate_cache(cmd_ctx, result); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to invalidate cache for [%s].\n", -+ cmd_ctx->rawname); -+ nss_protocol_done(cmd_ctx->cli_ctx, ret); -+ goto done; -+ } -+ } -+ - nss_protocol_reply(cmd_ctx->cli_ctx, cmd_ctx->nss_ctx, cmd_ctx, - result, cmd_ctx->fill_fn); - -diff --git a/src/responder/nss/nss_protocol.c b/src/responder/nss/nss_protocol.c -index 17bfc4f4e71960a72e9e04622eac95b94a865ec7..2655386498754c46fbb363bdd1f976f9ded6a434 100644 ---- a/src/responder/nss/nss_protocol.c -+++ b/src/responder/nss/nss_protocol.c -@@ -233,6 +233,7 @@ nss_protocol_parse_id_ex(struct cli_ctx *cli_ctx, uint32_t *_id, - SAFEALIGN_COPY_UINT32(&flags, body + sizeof(uint32_t), NULL); - - *_id = id; -+ *_flags = flags; - - return EOK; - } -diff --git a/src/responder/nss/nss_protocol.h b/src/responder/nss/nss_protocol.h -index ca5b040237dc18acdca9a7a3a7a7dbb64265aa95..76724d2b2db7b11c9147fa927e39abab731328b2 100644 ---- a/src/responder/nss/nss_protocol.h -+++ b/src/responder/nss/nss_protocol.h -@@ -50,6 +50,7 @@ struct nss_cmd_ctx { - struct nss_ctx *nss_ctx; - struct nss_state_ctx *state_ctx; - nss_protocol_fill_packet_fn fill_fn; -+ uint32_t flags; - - /* For initgroups- */ - const char *rawname; -diff --git a/src/responder/nss/nss_protocol_grent.c b/src/responder/nss/nss_protocol_grent.c -index ee228c722a153a1ba7aa8a1b30a1e551108424bb..6f6ae57dd97b000ad3cf174b0f649d46981563e2 100644 ---- a/src/responder/nss/nss_protocol_grent.c -+++ b/src/responder/nss/nss_protocol_grent.c -@@ -274,8 +274,10 @@ nss_protocol_fill_grent(struct nss_ctx *nss_ctx, - - num_results++; - -- /* Do not store entry in memory cache during enumeration. */ -- if (!cmd_ctx->enumeration) { -+ /* Do not store entry in memory cache during enumeration or when -+ * requested. */ -+ if (!cmd_ctx->enumeration -+ && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) { - members = (char *)&body[rp_members]; - members_size = body_len - rp_members; - ret = sss_mmap_cache_gr_store(&nss_ctx->grp_mc_ctx, name, &pwfield, -@@ -390,7 +392,8 @@ nss_protocol_fill_initgr(struct nss_ctx *nss_ctx, - num_results++; - } - -- if (nss_ctx->initgr_mc_ctx) { -+ if (nss_ctx->initgr_mc_ctx -+ && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) { - to_sized_string(&rawname, cmd_ctx->rawname); - to_sized_string(&unique_name, result->lookup_name); - -diff --git a/src/responder/nss/nss_protocol_pwent.c b/src/responder/nss/nss_protocol_pwent.c -index db5c071e2ff172a2267c08c9817fecfbcc7cabc3..f449ec69b6a86a6db2aaed368e217c1a791faaa2 100644 ---- a/src/responder/nss/nss_protocol_pwent.c -+++ b/src/responder/nss/nss_protocol_pwent.c -@@ -295,8 +295,10 @@ nss_protocol_fill_pwent(struct nss_ctx *nss_ctx, - - num_results++; - -- /* Do not store entry in memory cache during enumeration. */ -- if (!cmd_ctx->enumeration) { -+ /* Do not store entry in memory cache during enumeration or when -+ * requested. */ -+ if (!cmd_ctx->enumeration -+ && (cmd_ctx->flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) == 0) { - ret = sss_mmap_cache_pw_store(&nss_ctx->pwd_mc_ctx, name, &pwfield, - uid, gid, &gecos, &homedir, &shell); - if (ret != EOK) { -diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c -index edb3ea652ef7032b76c8f815b9f83fe185a669ea..148eb7b35ec236b6272dd203a0035399cfdef73d 100644 ---- a/src/sss_client/idmap/sss_nss_ex.c -+++ b/src/sss_client/idmap/sss_nss_ex.c -@@ -103,6 +103,18 @@ errno_t sss_nss_mc_get(struct nss_input *inp) - } - } - -+static int check_flags(uint32_t flags) -+{ -+ /* SSS_NSS_EX_FLAG_NO_CACHE and SSS_NSS_EX_FLAG_INVALIDATE_CACHE are -+ * mutually exclusive */ -+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0 -+ && (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) { -+ return EINVAL; -+ } -+ -+ return 0; -+} -+ - int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout) - { - uint8_t *repbuf = NULL; -@@ -117,7 +129,13 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout) - size_t idx; - bool skip_mc = false; - -- if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0) { -+ ret = check_flags(flags); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0 -+ || (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) { - skip_mc = true; - } - -diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h -index 1649830afbb80c617fd339f054aef8bc8e585fb9..3755643312f05a31d1cf1aa76dfc22848ef1e3ec 100644 ---- a/src/sss_client/idmap/sss_nss_idmap.h -+++ b/src/sss_client/idmap/sss_nss_idmap.h -@@ -170,9 +170,15 @@ void sss_nss_free_kv(struct sss_nss_kv *kv_list); - #define SSS_NSS_EX_FLAG_NO_FLAGS 0 - - /** Always request data from the server side, client must be privileged to do -- * so, see nss_trusted_users option in man sssd.conf for details */ -+ * so, see nss_trusted_users option in man sssd.conf for details. -+ * This flag cannot be used together with SSS_NSS_EX_FLAG_INVALIDATE_CACHE */ - #define SSS_NSS_EX_FLAG_NO_CACHE (1 << 0) - -+/** Invalidate the data in the caches, client must be privileged to do -+ * so, see nss_trusted_users option in man sssd.conf for details. -+ * This flag cannot be used together with SSS_NSS_EX_FLAG_NO_CACHE */ -+#define SSS_NSS_EX_FLAG_INVALIDATE_CACHE (1 << 1) -+ - #ifdef IPA_389DS_PLUGIN_HELPER_CALLS - - /** --- -2.13.6 - diff --git a/SOURCES/0029-MAN-Document-the-options-available-for-AD-trusted-do.patch b/SOURCES/0029-MAN-Document-the-options-available-for-AD-trusted-do.patch new file mode 100644 index 0000000..ef6ab6e --- /dev/null +++ b/SOURCES/0029-MAN-Document-the-options-available-for-AD-trusted-do.patch @@ -0,0 +1,120 @@ +From 731f098767ce352722dc4d4525c6a520cc5b5dab Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 27 Jun 2018 09:59:42 +0200 +Subject: [PATCH] MAN: Document the options available for AD trusted domains + +Related: +https://pagure.io/SSSD/sssd/issue/3291 + +Reviewed-by: Sumit Bose +(cherry picked from commit 014e7d8ab6aa4cf3051764052326258230c0bc86) +--- + src/man/sssd-ipa.5.xml | 92 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 92 insertions(+) + +diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml +index e4e58afaf6616f759ef82c77e339bdc738939dbe..e46957d5f742bafc11774992afe08d32443d061f 100644 +--- a/src/man/sssd-ipa.5.xml ++++ b/src/man/sssd-ipa.5.xml +@@ -728,6 +728,98 @@ + + + ++ ++ TRUSTED DOMAINS CONFIGURATION ++ ++ Some configuration options can be also set for a trusted domain. ++ A trusted domain configuration can either be done using ++ a subsection, for example: ++ ++[domain/ipa.domain.com/ad.domain.com] ++ad_server = dc.ad.domain.com ++ ++ ++ ++ In addition, some options can be set in the parent domain ++ and inherited by the trusted domain using the ++ subdomain_inherit option. For more details, ++ see the ++ ++ sssd.conf ++ 5 ++ manual page. ++ ++ ++ Different configuration options are tunable for a trusted ++ domain depending on whether you are configuring SSSD on an ++ IPA server or an IPA client. ++ ++ ++ OPTIONS TUNABLE ON IPA MASTERS ++ ++ The following options can be set in a subdomain ++ section on an IPA master: ++ ++ ++ ad_server ++ ++ ++ ad_backup_server ++ ++ ++ ad_site ++ ++ ++ ldap_search_base ++ ++ ++ ldap_user_search_base ++ ++ ++ ldap_group_search_base ++ ++ ++ use_fully_qualified_names ++ ++ ++ ++ ++ ++ OPTIONS TUNABLE ON IPA CLIENTS ++ ++ The following options can be set in a subdomain ++ section on an IPA client: ++ ++ ++ ad_server ++ ++ ++ ad_site ++ ++ ++ ++ ++ Note that if both options are set, only ++ ad_server is evaluated. ++ ++ ++ Since any request for a user or a group identity from a ++ trusted domain triggered from an IPA client is resolved ++ by the IPA server, the ad_server and ++ ad_site options only affect which AD DC will ++ the authentication be performed against. In particular, ++ the addresses resolved from these lists will be written to ++ kdcinfo files read by the Kerberos locator ++ plugin. Please refer to the ++ ++ sssd_krb5_locator_plugin ++ 8 ++ manual page for more details on the Kerberos ++ locator plugin. ++ ++ ++ ++ + + + +-- +2.17.1 + diff --git a/SOURCES/0029-NSS-TESTS-add-unit-tests-for-_EX-requests.patch b/SOURCES/0029-NSS-TESTS-add-unit-tests-for-_EX-requests.patch deleted file mode 100644 index 384ca17..0000000 --- a/SOURCES/0029-NSS-TESTS-add-unit-tests-for-_EX-requests.patch +++ /dev/null @@ -1,590 +0,0 @@ -From e0f1d81bc24416da1d6d646a0cd3a14bd7e3e02d Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 25 Oct 2017 21:31:54 +0200 -Subject: [PATCH 29/31] NSS/TESTS: add unit tests for *_EX requests - -The patch adds unit tests for the new *_EX requests with different input -types and flags. - -Related to https://pagure.io/SSSD/sssd/issue/2478 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 85da8a5e90bffc8b0fef5e0ea364a8d3cb50de86) ---- - src/tests/cmocka/test_nss_srv.c | 539 ++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 539 insertions(+) - -diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c -index ccedf96beaecfaa4232bbe456d5e5a8394098483..6aa726153183b5a871a75d398727ea7132358ca6 100644 ---- a/src/tests/cmocka/test_nss_srv.c -+++ b/src/tests/cmocka/test_nss_srv.c -@@ -255,6 +255,45 @@ static void mock_input_user_or_group(const char *input) - mock_parse_inp(shortname, domname, EOK); - } - -+static void mock_input_user_or_group_ex(bool do_parse_inp, const char *input, -+ uint32_t flags) -+{ -+ const char *copy; -+ const char *shortname; -+ const char *domname; -+ char *separator; -+ uint8_t *data; -+ size_t len; -+ -+ len = strlen(input); -+ len++; -+ data = talloc_size(nss_test_ctx, len + sizeof(uint32_t)); -+ assert_non_null(data); -+ memcpy(data, input, len); -+ SAFEALIGN_COPY_UINT32(data + len, &flags, NULL); -+ -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); -+ will_return(__wrap_sss_packet_get_body, data); -+ will_return(__wrap_sss_packet_get_body, len + sizeof(uint32_t)); -+ -+ if (do_parse_inp) { -+ copy = talloc_strdup(nss_test_ctx, input); -+ assert_non_null(copy); -+ -+ separator = strrchr(copy, '@'); -+ if (separator == NULL) { -+ shortname = input; -+ domname = NULL; -+ } else { -+ *separator = '\0'; -+ shortname = copy; -+ domname = separator + 1; -+ } -+ -+ mock_parse_inp(shortname, domname, EOK); -+ } -+} -+ - static void mock_input_upn(const char *upn) - { - will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); -@@ -291,6 +330,20 @@ static void mock_input_id(TALLOC_CTX *mem_ctx, uint32_t id) - will_return(__wrap_sss_packet_get_body, sizeof(uint32_t)); - } - -+static void mock_input_id_ex(TALLOC_CTX *mem_ctx, uint32_t id, uint32_t flags) -+{ -+ uint8_t *body; -+ -+ body = talloc_zero_array(mem_ctx, uint8_t, 8); -+ if (body == NULL) return; -+ -+ SAFEALIGN_SETMEM_UINT32(body, id, NULL); -+ SAFEALIGN_SETMEM_UINT32(body + sizeof(uint32_t), flags, NULL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); -+ will_return(__wrap_sss_packet_get_body, body); -+ will_return(__wrap_sss_packet_get_body, 2 * sizeof(uint32_t)); -+} -+ - static void mock_fill_user(void) - { - /* One packet for the entry and one for num entries */ -@@ -4143,6 +4196,482 @@ void test_nss_getsidbyname_neg(void **state) - assert_int_equal(ret, ENOENT); - } - -+static int test_nss_EINVAL_check(uint32_t status, uint8_t *body, size_t blen) -+{ -+ assert_int_equal(status, EINVAL); -+ assert_int_equal(blen, 0); -+ -+ return EOK; -+} -+ -+#define RESET_TCTX do { \ -+ nss_test_ctx->tctx->done = false; \ -+ nss_test_ctx->tctx->error = EIO; \ -+} while (0) -+ -+void test_nss_getpwnam_ex(void **state) -+{ -+ errno_t ret; -+ -+ ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, -+ &getpwnam_usr, NULL, 0); -+ assert_int_equal(ret, EOK); -+ -+ mock_input_user_or_group_ex(true, "testuser", 0); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM_EX); -+ mock_fill_user(); -+ -+ /* Query for that user, call a callback when command finishes */ -+ set_cmd_cb(test_nss_getpwnam_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use old input format, expect EINVAL */ -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); -+ will_return(__wrap_sss_packet_get_body, "testuser"); -+ will_return(__wrap_sss_packet_get_body, 0); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM_EX); -+ -+ set_cmd_cb(test_nss_EINVAL_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use unsupported flag combination, expect EINVAL */ -+ mock_input_user_or_group_ex(false, "testuser", -+ SSS_NSS_EX_FLAG_NO_CACHE -+ |SSS_NSS_EX_FLAG_INVALIDATE_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM_EX); -+ -+ set_cmd_cb(test_nss_EINVAL_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use flag SSS_NSS_EX_FLAG_NO_CACHE, -+ * will cause a backend lookup -> mock_account_recv_simple() */ -+ mock_input_user_or_group_ex(true, "testuser", SSS_NSS_EX_FLAG_NO_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM_EX); -+ mock_fill_user(); -+ mock_account_recv_simple(); -+ -+ set_cmd_cb(test_nss_getpwnam_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use flag SSS_NSS_EX_FLAG_INVALIDATE_CACHE */ -+ mock_input_user_or_group_ex(true, "testuser", -+ SSS_NSS_EX_FLAG_INVALIDATE_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWNAM_EX); -+ mock_fill_user(); -+ -+ set_cmd_cb(test_nss_getpwnam_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWNAM_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+} -+ -+void test_nss_getpwuid_ex(void **state) -+{ -+ errno_t ret; -+ uint32_t id = 101; -+ -+ /* Prime the cache with a valid user */ -+ ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, -+ &getpwuid_usr, NULL, 0); -+ assert_int_equal(ret, EOK); -+ -+ mock_input_id_ex(nss_test_ctx, id, 0); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID_EX); -+ mock_fill_user(); -+ -+ /* Query for that id, call a callback when command finishes */ -+ set_cmd_cb(test_nss_getpwuid_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use old input format, expect failure */ -+ mock_input_id(nss_test_ctx, id); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID_EX); -+ -+ set_cmd_cb(test_nss_EINVAL_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use unsupported flag combination, expect EINVAL */ -+ mock_input_id_ex(nss_test_ctx, id, SSS_NSS_EX_FLAG_NO_CACHE -+ |SSS_NSS_EX_FLAG_INVALIDATE_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID_EX); -+ -+ set_cmd_cb(test_nss_EINVAL_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use flag SSS_NSS_EX_FLAG_NO_CACHE, -+ * will cause a backend lookup -> mock_account_recv_simple() */ -+ mock_input_id_ex(nss_test_ctx, id, SSS_NSS_EX_FLAG_NO_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID_EX); -+ mock_fill_user(); -+ mock_account_recv_simple(); -+ -+ set_cmd_cb(test_nss_getpwuid_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use flag SSS_NSS_EX_FLAG_INVALIDATE_CACHE */ -+ mock_input_id_ex(nss_test_ctx, id, SSS_NSS_EX_FLAG_INVALIDATE_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETPWUID_EX); -+ mock_fill_user(); -+ -+ set_cmd_cb(test_nss_getpwuid_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETPWUID_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+} -+ -+void test_nss_getgrnam_ex_no_members(void **state) -+{ -+ errno_t ret; -+ -+ /* Test group is still in the cache */ -+ -+ mock_input_user_or_group_ex(true, getgrnam_no_members.gr_name, 0); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM_EX); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ -+ /* Query for that group, call a callback when command finishes */ -+ set_cmd_cb(test_nss_getgrnam_no_members_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use old input format, expect failure */ -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); -+ will_return(__wrap_sss_packet_get_body, "testgroup"); -+ will_return(__wrap_sss_packet_get_body, 0); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM_EX); -+ -+ set_cmd_cb(test_nss_EINVAL_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use unsupported flag combination, expect EINVAL */ -+ mock_input_user_or_group_ex(false, getgrnam_no_members.gr_name, -+ SSS_NSS_EX_FLAG_NO_CACHE -+ |SSS_NSS_EX_FLAG_INVALIDATE_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM_EX); -+ -+ set_cmd_cb(test_nss_EINVAL_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use flag SSS_NSS_EX_FLAG_NO_CACHE, -+ * will cause a backend lookup -> mock_account_recv_simple() */ -+ mock_input_user_or_group_ex(true, getgrnam_no_members.gr_name, -+ SSS_NSS_EX_FLAG_NO_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM_EX); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ mock_account_recv_simple(); -+ -+ set_cmd_cb(test_nss_getgrnam_no_members_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use flag SSS_NSS_EX_FLAG_INVALIDATE_CACHE */ -+ mock_input_user_or_group_ex(true, getgrnam_no_members.gr_name, -+ SSS_NSS_EX_FLAG_INVALIDATE_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRNAM_EX); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ -+ set_cmd_cb(test_nss_getgrnam_no_members_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRNAM_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+} -+ -+void test_nss_getgrgid_ex_no_members(void **state) -+{ -+ errno_t ret; -+ -+ /* Test group is still in the cache */ -+ -+ mock_input_id_ex(nss_test_ctx, getgrnam_no_members.gr_gid, 0); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRGID_EX); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ mock_account_recv_simple(); -+ -+ /* Query for that group, call a callback when command finishes */ -+ set_cmd_cb(test_nss_getgrnam_no_members_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRGID_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use old input format, expect failure */ -+ mock_input_id(nss_test_ctx, getgrnam_no_members.gr_gid); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRGID_EX); -+ -+ set_cmd_cb(test_nss_EINVAL_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRGID_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use unsupported flag combination, expect EINVAL */ -+ mock_input_id_ex(nss_test_ctx, getgrnam_no_members.gr_gid, -+ SSS_NSS_EX_FLAG_NO_CACHE -+ |SSS_NSS_EX_FLAG_INVALIDATE_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRGID_EX); -+ -+ set_cmd_cb(test_nss_EINVAL_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRGID_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use flag SSS_NSS_EX_FLAG_NO_CACHE, -+ * will cause a backend lookup -> mock_account_recv_simple() */ -+ mock_input_id_ex(nss_test_ctx, getgrnam_no_members.gr_gid, -+ SSS_NSS_EX_FLAG_NO_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRGID_EX); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ mock_account_recv_simple(); -+ mock_account_recv_simple(); -+ -+ set_cmd_cb(test_nss_getgrnam_no_members_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRGID_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use flag SSS_NSS_EX_FLAG_INVALIDATE_CACHE */ -+ mock_input_id_ex(nss_test_ctx, getgrnam_no_members.gr_gid, -+ SSS_NSS_EX_FLAG_INVALIDATE_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_GETGRGID_EX); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ -+ set_cmd_cb(test_nss_getgrnam_no_members_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_GETGRGID_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+} -+ -+void test_nss_initgroups_ex(void **state) -+{ -+ errno_t ret; -+ struct sysdb_attrs *attrs; -+ -+ attrs = sysdb_new_attrs(nss_test_ctx); -+ assert_non_null(attrs); -+ -+ ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, -+ time(NULL) + 300); -+ assert_int_equal(ret, EOK); -+ -+ ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, "upninitgr@upndomain.test"); -+ assert_int_equal(ret, EOK); -+ -+ ret = store_user(nss_test_ctx, nss_test_ctx->tctx->dom, -+ &testinitgr_usr, attrs, 0); -+ assert_int_equal(ret, EOK); -+ -+ mock_input_user_or_group_ex(true, "testinitgr", 0); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR_EX); -+ mock_fill_user(); -+ -+ /* Query for that user, call a callback when command finishes */ -+ set_cmd_cb(test_nss_initgr_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use old input format, expect failure */ -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_WRAPPER); -+ will_return(__wrap_sss_packet_get_body, "testinitgr"); -+ will_return(__wrap_sss_packet_get_body, 0); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR_EX); -+ -+ set_cmd_cb(test_nss_EINVAL_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use unsupported flag combination, expect EINVAL */ -+ mock_input_user_or_group_ex(false, "testinitgr", -+ SSS_NSS_EX_FLAG_NO_CACHE -+ |SSS_NSS_EX_FLAG_INVALIDATE_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR_EX); -+ -+ set_cmd_cb(test_nss_EINVAL_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use flag SSS_NSS_EX_FLAG_NO_CACHE, -+ * will cause a backend lookup -> mock_account_recv_simple() */ -+ mock_input_user_or_group_ex(true, "testinitgr", -+ SSS_NSS_EX_FLAG_NO_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR_EX); -+ mock_fill_user(); -+ mock_account_recv_simple(); -+ -+ set_cmd_cb(test_nss_initgr_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+ RESET_TCTX; -+ -+ /* Use flag SSS_NSS_EX_FLAG_INVALIDATE_CACHE */ -+ mock_input_user_or_group_ex(true, "testinitgr", -+ SSS_NSS_EX_FLAG_INVALIDATE_CACHE); -+ will_return(__wrap_sss_packet_get_cmd, SSS_NSS_INITGR_EX); -+ mock_fill_user(); -+ -+ set_cmd_cb(test_nss_initgr_check); -+ ret = sss_cmd_execute(nss_test_ctx->cctx, SSS_NSS_INITGR_EX, -+ nss_test_ctx->nss_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(nss_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+} -+ - int main(int argc, const char *argv[]) - { - int rv; -@@ -4288,6 +4817,16 @@ int main(int argc, const char *argv[]) - nss_test_setup, nss_test_teardown), - cmocka_unit_test_setup_teardown(test_nss_getsidbyname_neg, - nss_test_setup, nss_test_teardown), -+ cmocka_unit_test_setup_teardown(test_nss_getpwnam_ex, -+ nss_test_setup, nss_test_teardown), -+ cmocka_unit_test_setup_teardown(test_nss_getpwuid_ex, -+ nss_test_setup, nss_test_teardown), -+ cmocka_unit_test_setup_teardown(test_nss_getgrnam_ex_no_members, -+ nss_test_setup, nss_test_teardown), -+ cmocka_unit_test_setup_teardown(test_nss_getgrgid_ex_no_members, -+ nss_test_setup, nss_test_teardown), -+ cmocka_unit_test_setup_teardown(test_nss_initgroups_ex, -+ nss_test_setup, nss_test_teardown), - }; - - /* Set debug level to invalid value so we can deside if -d 0 was used. */ --- -2.13.6 - diff --git a/SOURCES/0030-AD-consider-resource_groups-in-PAC-as-well.patch b/SOURCES/0030-AD-consider-resource_groups-in-PAC-as-well.patch new file mode 100644 index 0000000..212bab0 --- /dev/null +++ b/SOURCES/0030-AD-consider-resource_groups-in-PAC-as-well.patch @@ -0,0 +1,334 @@ +From a7b308a01914458234bc05539e773e4c0762ad4b Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Thu, 28 Jun 2018 12:41:41 +0200 +Subject: [PATCH] AD: consider resource_groups in PAC as well + +With recent versions of Active Directory the SIDs of Domain Local groups +might be only available in the resource_groups section of the PAC, this +feature is also called SID compression. To get a complete list of groups +the user is a member of the SIDs from this section must be extracted as +well. + +Resolves https://pagure.io/SSSD/sssd/issue/3767 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 13c8450788a429fa49ba532b40ebfd7f3a4132e4) + +DOWNSTREAM: +Resolves: rhbz#1592964 - Groups go missing with PAC enabled in sssd +--- + src/external/samba.m4 | 8 ++ + src/providers/ad/ad_pac.c | 130 ++++++++++++++++++++++++------ + src/tests/cmocka/test_ad_common.c | 95 ++++++++++++++++++++++ + 3 files changed, 210 insertions(+), 23 deletions(-) + +diff --git a/src/external/samba.m4 b/src/external/samba.m4 +index 794cac2461d7fbd5e690ea105cd346cbe6fcce9a..7a8c1eb7b9069f18def4e915b0fb9ab054a68e01 100644 +--- a/src/external/samba.m4 ++++ b/src/external/samba.m4 +@@ -122,3 +122,11 @@ int main(void) + AC_DEFINE_UNQUOTED(SMB_IDMAP_INTERFACE_VERSION, $idmap_version, + [Detected version of Samba's idmap plugin interface]) + fi ++ ++SAVE_CFLAGS=$CFLAGS ++CFLAGS="$CFLAGS $SMBCLIENT_CFLAGS $NDR_NBT_CFLAGS $NDR_KRB5PAC_CFLAGS -I/usr/include/samba-4.0" ++AC_CHECK_MEMBERS([struct PAC_LOGON_INFO.resource_groups], , , ++ [[ #include ++ #include ++ #include ]]) ++CFLAGS=$SAVE_CFLAGS +diff --git a/src/providers/ad/ad_pac.c b/src/providers/ad/ad_pac.c +index 1a344725fbf57d4d95c46163f2e31d44e69b3e65..80424b44e334958402cb8cfebedc1898f1e2f9c8 100644 +--- a/src/providers/ad/ad_pac.c ++++ b/src/providers/ad/ad_pac.c +@@ -146,6 +146,87 @@ errno_t check_if_pac_is_available(TALLOC_CTX *mem_ctx, + return EOK; + } + ++static errno_t ++add_sids_from_rid_array_to_hash_table(struct dom_sid *dom_sid, ++ struct samr_RidWithAttributeArray *groups, ++ struct sss_idmap_ctx *idmap_ctx, ++ hash_table_t *sid_table) ++{ ++ enum idmap_error_code err; ++ char *dom_sid_str = NULL; ++ size_t dom_sid_str_len; ++ char *sid_str = NULL; ++ char *rid_start; ++ hash_key_t key; ++ hash_value_t value; ++ int ret; ++ size_t c; ++ TALLOC_CTX *tmp_ctx = NULL; ++ ++ tmp_ctx = talloc_new(NULL); ++ if (tmp_ctx == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); ++ return ENOMEM; ++ } ++ ++ key.type = HASH_KEY_STRING; ++ value.type = HASH_VALUE_ULONG; ++ ++ err = sss_idmap_smb_sid_to_sid(idmap_ctx, dom_sid, &dom_sid_str); ++ if (err != IDMAP_SUCCESS) { ++ DEBUG(SSSDBG_OP_FAILURE, "sss_idmap_smb_sid_to_sid failed.\n"); ++ ret = EFAULT; ++ goto done; ++ } ++ ++ dom_sid_str_len = strlen(dom_sid_str); ++ sid_str = talloc_zero_size(tmp_ctx, dom_sid_str_len + 12); ++ if (sid_str == NULL) { ++ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n"); ++ ret = ENOMEM; ++ goto done; ++ } ++ rid_start = sid_str + dom_sid_str_len; ++ ++ memcpy(sid_str, dom_sid_str, dom_sid_str_len); ++ ++ for (c = 0; c < groups->count; c++) { ++ memset(rid_start, '\0', 12); ++ ret = snprintf(rid_start, 12, "-%lu", ++ (unsigned long) groups->rids[c].rid); ++ if (ret < 0 || ret > 12) { ++ DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); ++ ret = EIO; ++ goto done; ++ } ++ ++ key.str = sid_str; ++ value.ul = 0; ++ ++ ret = hash_enter(sid_table, &key, &value); ++ if (ret != HASH_SUCCESS) { ++ DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", ++ ret, hash_error_string(ret)); ++ ret = EIO; ++ goto done; ++ } ++ ++ } ++ ++ ret = EOK; ++ ++done: ++ sss_idmap_free_sid(idmap_ctx, dom_sid_str); ++ talloc_free(tmp_ctx); ++ ++ return ret; ++} ++ ++struct resource_groups { ++ struct dom_sid2 *domain_sid; ++ struct samr_RidWithAttributeArray groups; ++}; ++ + errno_t ad_get_sids_from_pac(TALLOC_CTX *mem_ctx, + struct sss_idmap_ctx *idmap_ctx, + struct PAC_LOGON_INFO *logon_info, +@@ -157,6 +238,7 @@ errno_t ad_get_sids_from_pac(TALLOC_CTX *mem_ctx, + int ret; + size_t s; + struct netr_SamInfo3 *info3; ++ struct resource_groups resource_groups = { 0 }; + char *sid_str = NULL; + char *msid_str = NULL; + char *user_dom_sid_str = NULL; +@@ -188,9 +270,15 @@ errno_t ad_get_sids_from_pac(TALLOC_CTX *mem_ctx, + } + + info3 = &logon_info->info3; ++#ifdef HAVE_STRUCT_PAC_LOGON_INFO_RESOURCE_GROUPS ++ resource_groups.domain_sid = logon_info->resource_groups.domain_sid; ++ resource_groups.groups.count = logon_info->resource_groups.groups.count; ++ resource_groups.groups.rids = logon_info->resource_groups.groups.rids; ++#endif + + ret = sss_hash_create(tmp_ctx, +- info3->sidcount + info3->base.groups.count + 2, ++ info3->sidcount + info3->base.groups.count + 2 ++ + resource_groups.groups.count, + &sid_table); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_hash_create failed.\n"); +@@ -265,28 +353,13 @@ errno_t ad_get_sids_from_pac(TALLOC_CTX *mem_ctx, + goto done; + } + +- +- for (s = 0; s < info3->base.groups.count; s++) { +- memset(rid_start, '\0', 12); +- ret = snprintf(rid_start, 12, "-%lu", +- (unsigned long) info3->base.groups.rids[s].rid); +- if (ret < 0 || ret > 12) { +- DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n"); +- ret = EIO; +- goto done; +- } +- +- key.str = sid_str; +- value.ul = 0; +- +- ret = hash_enter(sid_table, &key, &value); +- if (ret != HASH_SUCCESS) { +- DEBUG(SSSDBG_OP_FAILURE, "hash_enter failed [%d][%s].\n", +- ret, hash_error_string(ret)); +- ret = EIO; +- goto done; +- } +- ++ ret = add_sids_from_rid_array_to_hash_table(info3->base.domain_sid, ++ &info3->base.groups, ++ idmap_ctx, sid_table); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "add_sids_from_rid_array_to_hash_table failed.\n"); ++ goto done; + } + + for(s = 0; s < info3->sidcount; s++) { +@@ -311,6 +384,17 @@ errno_t ad_get_sids_from_pac(TALLOC_CTX *mem_ctx, + } + } + ++ if (resource_groups.domain_sid != NULL) { ++ ret = add_sids_from_rid_array_to_hash_table(resource_groups.domain_sid, ++ &resource_groups.groups, ++ idmap_ctx, sid_table); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "add_sids_from_rid_array_to_hash_table failed.\n"); ++ goto done; ++ } ++ } ++ + num_sids = hash_count(sid_table); + sid_list = talloc_array(tmp_ctx, char *, num_sids); + if (sid_list == NULL) { +diff --git a/src/tests/cmocka/test_ad_common.c b/src/tests/cmocka/test_ad_common.c +index 39ebbc63324ca40d071f30582d2f15d732f6c466..ac3b0d0ab3c7b0a0ee4d21d96e1b4783ff1b4139 100644 +--- a/src/tests/cmocka/test_ad_common.c ++++ b/src/tests/cmocka/test_ad_common.c +@@ -207,6 +207,29 @@ static void test_check_if_pac_is_available(void **state) + "BEAEUAVgBFAEwAdv///4yBQZ5ZQnp3qwj2lKGcd0UAAAAAdv//" \ + "/39fn4UneD5l6YxP8w/U0coAAAAA" + ++#define TEST_PAC_RESOURCE_GROUPS_BASE64 \ ++ "BQAAAAAAAAABAAAA8AEAAFgAAAAAAAAACgAAABQAAABIAgAA" \ ++ "AAAAAAwAAABYAAAAYAIAAAAAAAAGAAAAEAAAALgCAAAAAAAA" \ ++ "BwAAABQAAADIAgAAAAAAAAEQCADMzMzM4AEAAAAAAAAAAAIA" \ ++ "Rr0gPUQO1AH/////////f/////////9/TRPNRwtu0wFN0zZy" \ ++ "1G7TAf////////9/CgAKAAQAAgAKAAoACAACAAAAAAAMAAIA" \ ++ "AAAAABAAAgAAAAAAFAACAAAAAAAYAAIACwAAAFEEAAABAgAA" \ ++ "AwAAABwAAgAgAgAAAAAAAAAAAAAAAAAAAAAAAAQABgAgAAIA" \ ++ "BgAIACQAAgAoAAIAAAAAAAAAAAAQAgAAAAAAAAAAAAAAAAAA" \ ++ "AAAAAAAAAAAAAAAAAAAAAAEAAAAsAAIANAACAAEAAAA4AAIA" \ ++ "BQAAAAAAAAAFAAAAdAB1AHMAZQByAAAABQAAAAAAAAAFAAAA" \ ++ "dAB1AHMAZQByAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" \ ++ "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAECAAAHAAAA" \ ++ "YgQAAAcAAABjBAAABwAAAAMAAAAAAAAAAgAAAEQAQwAEAAAA" \ ++ "AAAAAAMAAABXAEkATgAAAAQAAAABBAAAAAAABRUAAAAkYm0r" \ ++ "SyFumd73jX0BAAAAMAACAAcAAAABAAAAAQEAAAAAABIBAAAA" \ ++ "BAAAAAEEAAAAAAAFFQAAACRibStLIW6Z3veNfQEAAABoBAAA" \ ++ "BwAAIAAAAACAEuVfRA7UAQoAdAB1AHMAZQByAAAAAAAoABAA" \ ++ "HAA4AAAAAAAAAAAAdAB1AHMAZQByAEAAdwBpAG4ALgB0AHIA" \ ++ "dQBzAHQALgB0AGUAcwB0AFcASQBOAC4AVABSAFUAUwBUAC4A" \ ++ "VABFAFMAVAAAAAAAEAAAAOGTj7I9Qn7XebOqdHb///+fHhrZ" \ ++ "kBt0So4jOFBk84sDAAAAAA==" ++ + static void test_ad_get_data_from_pac(void **state) + { + int ret; +@@ -303,6 +326,73 @@ static void test_ad_get_sids_from_pac(void **state) + sss_idmap_free(idmap_ctx); + } + ++#ifdef HAVE_STRUCT_PAC_LOGON_INFO_RESOURCE_GROUPS ++static void test_ad_get_sids_from_pac_with_resource_groups(void **state) ++{ ++ int ret; ++ struct PAC_LOGON_INFO *logon_info; ++ uint8_t *test_pac_blob; ++ size_t test_pac_blob_size; ++ char *user_sid; ++ char *primary_group_sid; ++ size_t num_sids; ++ char **sid_list; ++ struct sss_idmap_ctx *idmap_ctx; ++ enum idmap_error_code err; ++ size_t c; ++ size_t s; ++ ++ const char *sid_check_list[] = { "S-1-5-21-728588836-2574131531-2106456030-513", ++ "S-1-5-21-728588836-2574131531-2106456030-1122", ++ "S-1-5-21-728588836-2574131531-2106456030-1123", ++ "S-1-5-21-728588836-2574131531-2106456030-1128", ++ "S-1-18-1", ++ NULL }; ++ ++ struct ad_common_test_ctx *test_ctx = talloc_get_type(*state, ++ struct ad_common_test_ctx); ++ ++ err = sss_idmap_init(sss_idmap_talloc, test_ctx, sss_idmap_talloc_free, ++ &idmap_ctx); ++ assert_int_equal(err, IDMAP_SUCCESS); ++ ++ test_pac_blob = sss_base64_decode(test_ctx, TEST_PAC_RESOURCE_GROUPS_BASE64, ++ &test_pac_blob_size); ++ assert_non_null(test_pac_blob_size); ++ ++ ret = ad_get_data_from_pac(test_ctx, test_pac_blob, test_pac_blob_size, ++ &logon_info); ++ assert_int_equal(ret, EOK); ++ ++ ret = ad_get_sids_from_pac(test_ctx, idmap_ctx, logon_info, &user_sid, ++ &primary_group_sid, &num_sids, &sid_list); ++ assert_int_equal(ret, EOK); ++ assert_string_equal(user_sid, ++ "S-1-5-21-728588836-2574131531-2106456030-1105"); ++ assert_string_equal(primary_group_sid, ++ "S-1-5-21-728588836-2574131531-2106456030-513"); ++ assert_int_equal(num_sids, 5); ++ ++ for (c = 0; sid_check_list[c] != NULL; c++) { ++ for (s = 0; s < num_sids; s++) { ++ if (strcmp(sid_check_list[c], sid_list[s]) == 0) { ++ break; ++ } ++ } ++ if (s == num_sids) { ++ fail_msg("SID [%s] not found in SID list.", sid_check_list[c]); ++ } ++ } ++ ++ talloc_free(test_pac_blob); ++ talloc_free(logon_info); ++ talloc_free(user_sid); ++ talloc_free(primary_group_sid); ++ talloc_free(sid_list); ++ sss_idmap_free(idmap_ctx); ++} ++#endif ++ + static void test_ad_get_pac_data_from_user_entry(void **state) + { + int ret; +@@ -912,6 +1002,11 @@ int main(int argc, const char *argv[]) + cmocka_unit_test_setup_teardown(test_ad_get_sids_from_pac, + test_ad_common_setup, + test_ad_common_teardown), ++#ifdef HAVE_STRUCT_PAC_LOGON_INFO_RESOURCE_GROUPS ++ cmocka_unit_test_setup_teardown(test_ad_get_sids_from_pac_with_resource_groups, ++ test_ad_common_setup, ++ test_ad_common_teardown), ++#endif + cmocka_unit_test_setup_teardown(test_ad_get_pac_data_from_user_entry, + test_ad_common_setup, + test_ad_common_teardown), +-- +2.17.1 + diff --git a/SOURCES/0030-nss-idmap-add-timeout-version-of-old-sss_nss_-calls.patch b/SOURCES/0030-nss-idmap-add-timeout-version-of-old-sss_nss_-calls.patch deleted file mode 100644 index caf0dc0..0000000 --- a/SOURCES/0030-nss-idmap-add-timeout-version-of-old-sss_nss_-calls.patch +++ /dev/null @@ -1,494 +0,0 @@ -From a12e6ac8001025174cf201bcaa2143edb1b0c017 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 2 Nov 2017 10:32:41 +0100 -Subject: [PATCH 30/31] nss-idmap: add timeout version of old sss_nss_* calls - -Reviewed-by: Jakub Hrozek -(cherry picked from commit e54db68cbb9c12d8a6867f2c7766fb2115ab0997) ---- - Makefile.am | 2 +- - src/sss_client/idmap/sss_nss_idmap.c | 126 ++++++++++++++++++-------- - src/sss_client/idmap/sss_nss_idmap.exports | 7 ++ - src/sss_client/idmap/sss_nss_idmap.h | 124 +++++++++++++++++++++++++ - src/sss_client/idmap/sss_nss_idmap.unit_tests | 2 +- - src/tests/cmocka/sss_nss_idmap-tests.c | 13 +-- - 6 files changed, 229 insertions(+), 45 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index dd25d1f7ea1be66388aa1b393bac290c4d7501a2..286ba47e3c421864362717be5258de960efca9f2 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -2974,7 +2974,6 @@ test_sysdb_domain_resolution_order_LDADD = \ - - test_wbc_calls_SOURCES = \ - src/tests/cmocka/test_wbc_calls.c \ -- src/sss_client/idmap/sss_nss_idmap.c \ - src/sss_client/libwbclient/wbc_sid_sssd.c \ - src/sss_client/libwbclient/wbclient_common.c \ - src/sss_client/libwbclient/wbc_sid_common.c \ -@@ -2993,6 +2992,7 @@ test_wbc_calls_LDADD = \ - $(TALLOC_LIBS) \ - $(SSSD_INTERNAL_LTLIBS) \ - libsss_test_common.la \ -+ libsss_nss_idmap.la \ - $(NULL) - - test_be_ptask_SOURCES = \ -diff --git a/src/sss_client/idmap/sss_nss_idmap.c b/src/sss_client/idmap/sss_nss_idmap.c -index 6f3af267a1e763e7dce77e3862be377ae2bfe984..6e7685d2b1d80956b6a6668e9bbb146abd9e86ed 100644 ---- a/src/sss_client/idmap/sss_nss_idmap.c -+++ b/src/sss_client/idmap/sss_nss_idmap.c -@@ -28,10 +28,13 @@ - - #include "sss_client/sss_cli.h" - #include "sss_client/idmap/sss_nss_idmap.h" -+#include "sss_client/idmap/sss_nss_idmap_private.h" - #include "util/strtonum.h" - - #define DATA_START (3 * sizeof(uint32_t)) - #define LIST_START (2 * sizeof(uint32_t)) -+#define NO_TIMEOUT ((unsigned int) -1) -+ - union input { - const char *str; - uint32_t id; -@@ -198,8 +201,8 @@ done: - return ret; - } - --static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , -- struct output *out) -+static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd, -+ unsigned int timeout, struct output *out) - { - int ret; - size_t inp_len; -@@ -215,6 +218,7 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , - struct sss_nss_kv *kv_list; - char **names; - enum sss_id_type *types; -+ int time_left = SSS_CLI_SOCKET_TIMEOUT; - - switch (cmd) { - case SSS_NSS_GETSIDBYNAME: -@@ -250,9 +254,14 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd , - return EINVAL; - } - -- sss_nss_lock(); -+ if (timeout == NO_TIMEOUT) { -+ sss_nss_lock(); -+ } else { -+ sss_nss_timedlock(timeout, &time_left); -+ } - -- nret = sss_nss_make_request(cmd, &rd, &repbuf, &replen, &errnop); -+ nret = sss_nss_make_request_timeout(cmd, &rd, time_left, &repbuf, &replen, -+ &errnop); - if (nret != NSS_STATUS_SUCCESS) { - ret = nss_status_to_errno(nret); - goto done; -@@ -347,8 +356,8 @@ done: - return ret; - } - --int sss_nss_getsidbyname(const char *fq_name, char **sid, -- enum sss_id_type *type) -+int sss_nss_getsidbyname_timeout(const char *fq_name, unsigned int timeout, -+ char **sid, enum sss_id_type *type) - { - int ret; - union input inp; -@@ -360,7 +369,7 @@ int sss_nss_getsidbyname(const char *fq_name, char **sid, - - inp.str = fq_name; - -- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYNAME, &out); -+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYNAME, timeout, &out); - if (ret == EOK) { - *sid = out.d.str; - *type = out.type; -@@ -369,7 +378,14 @@ int sss_nss_getsidbyname(const char *fq_name, char **sid, - return ret; - } - --int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type) -+int sss_nss_getsidbyname(const char *fq_name, char **sid, -+ enum sss_id_type *type) -+{ -+ return sss_nss_getsidbyname_timeout(fq_name, NO_TIMEOUT, sid, type); -+} -+ -+int sss_nss_getsidbyid_timeout(uint32_t id, unsigned int timeout, -+ char **sid, enum sss_id_type *type) - { - int ret; - union input inp; -@@ -381,7 +397,7 @@ int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type) - - inp.id = id; - -- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYID, &out); -+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETSIDBYID, timeout, &out); - if (ret == EOK) { - *sid = out.d.str; - *type = out.type; -@@ -390,8 +406,13 @@ int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type) - return ret; - } - --int sss_nss_getnamebysid(const char *sid, char **fq_name, -- enum sss_id_type *type) -+int sss_nss_getsidbyid(uint32_t id, char **sid, enum sss_id_type *type) -+{ -+ return sss_nss_getsidbyid_timeout(id, NO_TIMEOUT, sid, type); -+} -+ -+int sss_nss_getnamebysid_timeout(const char *sid, unsigned int timeout, -+ char **fq_name, enum sss_id_type *type) - { - int ret; - union input inp; -@@ -403,7 +424,7 @@ int sss_nss_getnamebysid(const char *sid, char **fq_name, - - inp.str = sid; - -- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYSID, &out); -+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYSID, timeout, &out); - if (ret == EOK) { - *fq_name = out.d.str; - *type = out.type; -@@ -412,7 +433,14 @@ int sss_nss_getnamebysid(const char *sid, char **fq_name, - return ret; - } - --int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type) -+int sss_nss_getnamebysid(const char *sid, char **fq_name, -+ enum sss_id_type *type) -+{ -+ return sss_nss_getnamebysid_timeout(sid, NO_TIMEOUT, fq_name, type); -+} -+ -+int sss_nss_getidbysid_timeout(const char *sid, unsigned int timeout, -+ uint32_t *id, enum sss_id_type *id_type) - { - int ret; - union input inp; -@@ -424,7 +452,7 @@ int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type) - - inp.str = sid; - -- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETIDBYSID, &out); -+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETIDBYSID, timeout, &out); - if (ret == EOK) { - *id = out.d.id; - *id_type = out.type; -@@ -433,8 +461,14 @@ int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type) - return ret; - } - --int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, -- enum sss_id_type *type) -+int sss_nss_getidbysid(const char *sid, uint32_t *id, enum sss_id_type *id_type) -+{ -+ return sss_nss_getidbysid_timeout(sid, NO_TIMEOUT, id, id_type); -+} -+ -+int sss_nss_getorigbyname_timeout(const char *fq_name, unsigned int timeout, -+ struct sss_nss_kv **kv_list, -+ enum sss_id_type *type) - { - int ret; - union input inp; -@@ -446,7 +480,7 @@ int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, - - inp.str = fq_name; - -- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETORIGBYNAME, &out); -+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETORIGBYNAME, timeout, &out); - if (ret == EOK) { - *kv_list = out.d.kv_list; - *type = out.type; -@@ -455,30 +489,42 @@ int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, - return ret; - } - -+int sss_nss_getorigbyname(const char *fq_name, struct sss_nss_kv **kv_list, -+ enum sss_id_type *type) -+{ -+ return sss_nss_getorigbyname_timeout(fq_name, NO_TIMEOUT, kv_list, type); -+} -+ -+int sss_nss_getnamebycert_timeout(const char *cert, unsigned int timeout, -+ char **fq_name, enum sss_id_type *type) -+{ -+ int ret; -+ union input inp; -+ struct output out; -+ -+ if (fq_name == NULL || cert == NULL || *cert == '\0') { -+ return EINVAL; -+ } -+ -+ inp.str = cert; -+ -+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYCERT, timeout, &out); -+ if (ret == EOK) { -+ *fq_name = out.d.str; -+ *type = out.type; -+ } -+ -+ return ret; -+} -+ - int sss_nss_getnamebycert(const char *cert, char **fq_name, - enum sss_id_type *type) - { -- int ret; -- union input inp; -- struct output out; -- -- if (fq_name == NULL || cert == NULL || *cert == '\0') { -- return EINVAL; -- } -- -- inp.str = cert; -- -- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETNAMEBYCERT, &out); -- if (ret == EOK) { -- *fq_name = out.d.str; -- *type = out.type; -- } -- -- return ret; -+ return sss_nss_getnamebycert_timeout(cert, NO_TIMEOUT, fq_name, type); - } - --int sss_nss_getlistbycert(const char *cert, char ***fq_name, -- enum sss_id_type **type) -+int sss_nss_getlistbycert_timeout(const char *cert, unsigned int timeout, -+ char ***fq_name, enum sss_id_type **type) - { - int ret; - union input inp; -@@ -490,7 +536,7 @@ int sss_nss_getlistbycert(const char *cert, char ***fq_name, - - inp.str = cert; - -- ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETLISTBYCERT, &out); -+ ret = sss_nss_getyyybyxxx(inp, SSS_NSS_GETLISTBYCERT, timeout, &out); - if (ret == EOK) { - *fq_name = out.d.names; - *type = out.types; -@@ -498,3 +544,9 @@ int sss_nss_getlistbycert(const char *cert, char ***fq_name, - - return ret; - } -+ -+int sss_nss_getlistbycert(const char *cert, char ***fq_name, -+ enum sss_id_type **type) -+{ -+ return sss_nss_getlistbycert_timeout(cert, NO_TIMEOUT, fq_name, type); -+} -diff --git a/src/sss_client/idmap/sss_nss_idmap.exports b/src/sss_client/idmap/sss_nss_idmap.exports -index 788d05ecc3bd56fa88e68a98b9c8096cf7140a09..8d0a24f42aa3fb3dd9c2ed125bf79e2c7792993f 100644 ---- a/src/sss_client/idmap/sss_nss_idmap.exports -+++ b/src/sss_client/idmap/sss_nss_idmap.exports -@@ -40,4 +40,11 @@ SSS_NSS_IDMAP_0.4.0 { - sss_nss_getgrnam_timeout; - sss_nss_getgrgid_timeout; - sss_nss_getgrouplist_timeout; -+ sss_nss_getsidbyname_timeout; -+ sss_nss_getsidbyid_timeout; -+ sss_nss_getnamebysid_timeout; -+ sss_nss_getidbysid_timeout; -+ sss_nss_getorigbyname_timeout; -+ sss_nss_getnamebycert_timeout; -+ sss_nss_getlistbycert_timeout; - } SSS_NSS_IDMAP_0.3.0; -diff --git a/src/sss_client/idmap/sss_nss_idmap.h b/src/sss_client/idmap/sss_nss_idmap.h -index 3755643312f05a31d1cf1aa76dfc22848ef1e3ec..125e72a6486f5916f90d37f27e1743d181bfa3e5 100644 ---- a/src/sss_client/idmap/sss_nss_idmap.h -+++ b/src/sss_client/idmap/sss_nss_idmap.h -@@ -303,5 +303,129 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp, - int sss_nss_getgrouplist_timeout(const char *name, gid_t group, - gid_t *groups, int *ngroups, - uint32_t flags, unsigned int timeout); -+/** -+ * @brief Find SID by fully qualified name with timeout -+ * -+ * @param[in] fq_name Fully qualified name of a user or a group -+ * @param[in] timeout timeout in milliseconds -+ * @param[out] sid String representation of the SID of the requested user -+ * or group, must be freed by the caller -+ * @param[out] type Type of the object related to the given name -+ * -+ * @return -+ * - 0 (EOK): success, sid contains the requested SID -+ * - ENOENT: requested object was not found in the domain extracted from the given name -+ * - ENETUNREACH: SSSD does not know how to handle the domain extracted from the given name -+ * - ENOSYS: this call is not supported by the configured provider -+ * - EINVAL: input cannot be parsed -+ * - EIO: remote servers cannot be reached -+ * - EFAULT: any other error -+ * - ETIME: request timed out but was send to SSSD -+ * - ETIMEDOUT: request timed out but was not send to SSSD -+ */ -+int sss_nss_getsidbyname_timeout(const char *fq_name, unsigned int timeout, -+ char **sid, enum sss_id_type *type); -+ -+/** -+ * @brief Find SID by a POSIX UID or GID with timeout -+ * -+ * @param[in] id POSIX UID or GID -+ * @param[in] timeout timeout in milliseconds -+ * @param[out] sid String representation of the SID of the requested user -+ * or group, must be freed by the caller -+ * @param[out] type Type of the object related to the given ID -+ * -+ * @return -+ * - see #sss_nss_getsidbyname_timeout -+ */ -+int sss_nss_getsidbyid_timeout(uint32_t id, unsigned int timeout, -+ char **sid, enum sss_id_type *type); -+ -+/** -+ * @brief Return the fully qualified name for the given SID with timeout -+ * -+ * @param[in] sid String representation of the SID -+ * @param[in] timeout timeout in milliseconds -+ * @param[out] fq_name Fully qualified name of a user or a group, -+ * must be freed by the caller -+ * @param[out] type Type of the object related to the SID -+ * -+ * @return -+ * - see #sss_nss_getsidbyname_timeout -+ */ -+int sss_nss_getnamebysid_timeout(const char *sid, unsigned int timeout, -+ char **fq_name, enum sss_id_type *type); -+ -+/** -+ * @brief Return the POSIX ID for the given SID with timeout -+ * -+ * @param[in] sid String representation of the SID -+ * @param[in] timeout timeout in milliseconds -+ * @param[out] id POSIX ID related to the SID -+ * @param[out] id_type Type of the object related to the SID -+ * -+ * @return -+ * - see #sss_nss_getsidbyname_timeout -+ */ -+int sss_nss_getidbysid_timeout(const char *sid, unsigned int timeout, -+ uint32_t *id, enum sss_id_type *id_type); -+ -+/** -+ * @brief Find original data by fully qualified name with timeout -+ * -+ * @param[in] fq_name Fully qualified name of a user or a group -+ * @param[in] timeout timeout in milliseconds -+ * @param[out] kv_list A NULL terminate list of key-value pairs where the key -+ * is the attribute name in the cache of SSSD, -+ * must be freed by the caller with sss_nss_free_kv() -+ * @param[out] type Type of the object related to the given name -+ * -+ * @return -+ * - 0 (EOK): success, sid contains the requested SID -+ * - ENOENT: requested object was not found in the domain extracted from the given name -+ * - ENETUNREACH: SSSD does not know how to handle the domain extracted from the given name -+ * - ENOSYS: this call is not supported by the configured provider -+ * - EINVAL: input cannot be parsed -+ * - EIO: remote servers cannot be reached -+ * - EFAULT: any other error -+ * - ETIME: request timed out but was send to SSSD -+ * - ETIMEDOUT: request timed out but was not send to SSSD -+ */ -+int sss_nss_getorigbyname_timeout(const char *fq_name, unsigned int timeout, -+ struct sss_nss_kv **kv_list, -+ enum sss_id_type *type); -+ -+/** -+ * @brief Return the fully qualified name for the given base64 encoded -+ * X.509 certificate in DER format with timeout -+ * -+ * @param[in] cert base64 encoded certificate -+ * @param[in] timeout timeout in milliseconds -+ * @param[out] fq_name Fully qualified name of a user or a group, -+ * must be freed by the caller -+ * @param[out] type Type of the object related to the cert -+ * -+ * @return -+ * - see #sss_nss_getsidbyname_timeout -+ */ -+int sss_nss_getnamebycert_timeout(const char *cert, unsigned int timeout, -+ char **fq_name, enum sss_id_type *type); -+ -+/** -+ * @brief Return a list of fully qualified names for the given base64 encoded -+ * X.509 certificate in DER format with timeout -+ * -+ * @param[in] cert base64 encoded certificate -+ * @param[in] timeout timeout in milliseconds -+ * @param[out] fq_name List of fully qualified name of users or groups, -+ * must be freed by the caller -+ * @param[out] type List of types of the objects related to the cert -+ * -+ * @return -+ * - see #sss_nss_getsidbyname_timeout -+ */ -+int sss_nss_getlistbycert_timeout(const char *cert, unsigned int timeout, -+ char ***fq_name, enum sss_id_type **type); -+ - #endif /* IPA_389DS_PLUGIN_HELPER_CALLS */ - #endif /* SSS_NSS_IDMAP_H_ */ -diff --git a/src/sss_client/idmap/sss_nss_idmap.unit_tests b/src/sss_client/idmap/sss_nss_idmap.unit_tests -index 361cc3b134ead52cf458afe27c055739d6728441..05c474f008e1d59aae5976acfd81613c3c3e6540 100644 ---- a/src/sss_client/idmap/sss_nss_idmap.unit_tests -+++ b/src/sss_client/idmap/sss_nss_idmap.unit_tests -@@ -2,5 +2,5 @@ - UNIT_TEST_ONLY { - # should not be part of installed library - global: -- sss_nss_make_request; -+ sss_nss_make_request_timeout; - }; -diff --git a/src/tests/cmocka/sss_nss_idmap-tests.c b/src/tests/cmocka/sss_nss_idmap-tests.c -index 8807eca619d7b07d919168e5629042cf38f654ac..2e37040d2d3523bea157804706685fa0b36df16a 100644 ---- a/src/tests/cmocka/sss_nss_idmap-tests.c -+++ b/src/tests/cmocka/sss_nss_idmap-tests.c -@@ -61,10 +61,11 @@ uint8_t buf_orig1[] = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0 - #error "unknow endianess" - #endif - --enum nss_status sss_nss_make_request(enum sss_cli_command cmd, -- struct sss_cli_req_data *rd, -- uint8_t **repbuf, size_t *replen, -- int *errnop) -+enum nss_status sss_nss_make_request_timeout(enum sss_cli_command cmd, -+ struct sss_cli_req_data *rd, -+ int timeout, -+ uint8_t **repbuf, size_t *replen, -+ int *errnop) - { - struct sss_nss_make_request_test_data *d; - -@@ -114,7 +115,7 @@ void test_getsidbyname(void **state) - sid = NULL; - - for (c = 0; d[c].d.repbuf != NULL; c++) { -- will_return(sss_nss_make_request, &d[0].d); -+ will_return(sss_nss_make_request_timeout, &d[0].d); - - ret = sss_nss_getsidbyname("test", &sid, &type); - assert_int_equal(ret, d[0].ret); -@@ -134,7 +135,7 @@ void test_getorigbyname(void **state) - enum sss_id_type type; - struct sss_nss_make_request_test_data d = {buf_orig1, sizeof(buf_orig1), 0, NSS_STATUS_SUCCESS}; - -- will_return(sss_nss_make_request, &d); -+ will_return(sss_nss_make_request_timeout, &d); - ret = sss_nss_getorigbyname("test", &kv_list, &type); - assert_int_equal(ret, EOK); - assert_int_equal(type, SSS_ID_TYPE_UID); --- -2.13.6 - diff --git a/SOURCES/0031-LDAP-Remove-the-legacy-POSIX-check-itself.patch b/SOURCES/0031-LDAP-Remove-the-legacy-POSIX-check-itself.patch new file mode 100644 index 0000000..86f9235 --- /dev/null +++ b/SOURCES/0031-LDAP-Remove-the-legacy-POSIX-check-itself.patch @@ -0,0 +1,321 @@ +From 5fcce16c212037b5193556dc2f6bcb7e4d7f0f85 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Sat, 30 Jun 2018 13:21:18 +0200 +Subject: [PATCH] LDAP: Remove the legacy POSIX check itself +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This code is no longer needed now. + +Related: +https://pagure.io/SSSD/sssd/issue/3755 + +Reviewed-by: Pavel Březina +(cherry picked from commit 5b2b6493dfb3c1f2cb945356e34c70d8c5d64185) + +DOWNSTREAM: +Resolves: rhbz#1582975 - The search filter for detecting POSIX attributes in global catalog is too broad and can cause a high load on the servers +--- + src/providers/ad/ad_common.c | 2 - + src/providers/ldap/ldap_common.c | 17 --- + src/providers/ldap/ldap_common.h | 7 -- + src/providers/ldap/sdap.h | 1 - + src/providers/ldap/sdap_async.c | 174 ------------------------------- + src/providers/ldap/sdap_async.h | 13 --- + 6 files changed, 214 deletions(-) + +diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c +index eaf0814f1aaf51a5085e992efa633240f32c498e..6d395cfb1d4148e803a656a8f7205fe13570085b 100644 +--- a/src/providers/ad/ad_common.c ++++ b/src/providers/ad/ad_common.c +@@ -1388,7 +1388,6 @@ ad_gc_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx, + clist[cindex] = ad_ctx->gc_ctx; + clist[cindex]->ignore_mark_offline = true; + clist[cindex]->no_mpg_user_fallback = true; +- clist[cindex]->check_posix_attrs = true; + cindex++; + } + +@@ -1435,7 +1434,6 @@ ad_user_conn_list(TALLOC_CTX *mem_ctx, + && IS_SUBDOMAIN(dom)) { + clist[cindex] = ad_ctx->gc_ctx; + clist[cindex]->ignore_mark_offline = true; +- clist[cindex]->check_posix_attrs = true; + cindex++; + } + +diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c +index a0a9b8523310b2551ee992f8d0c2e369dafaa56d..9cd8ec09c7fdc6bd1c8d64da150178f483f2a5a3 100644 +--- a/src/providers/ldap/ldap_common.c ++++ b/src/providers/ldap/ldap_common.c +@@ -884,20 +884,3 @@ sdap_id_ctx_new(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, + + return sdap_ctx; + } +- +-bool should_run_posix_check(struct sdap_id_ctx *ctx, +- struct sdap_id_conn_ctx *conn, +- bool use_id_mapping, +- bool posix_request) +-{ +- if (use_id_mapping == false && +- posix_request == true && +- ctx->opts->schema_type == SDAP_SCHEMA_AD && +- conn->check_posix_attrs == true && +- ctx->srv_opts && +- ctx->srv_opts->posix_checked == false) { +- return true; +- } +- +- return false; +-} +diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h +index 3de3568cb28c258c00f9b522c0b9120adca81d81..6c08d789b339424649c938b845e7118f5ea88f73 100644 +--- a/src/providers/ldap/ldap_common.h ++++ b/src/providers/ldap/ldap_common.h +@@ -59,8 +59,6 @@ struct sdap_id_conn_ctx { + bool ignore_mark_offline; + /* do not fall back to user lookups for mpg domains on this connection */ + bool no_mpg_user_fallback; +- /* check if this connection contains POSIX attributes */ +- bool check_posix_attrs; + }; + + struct sdap_id_ctx { +@@ -309,11 +307,6 @@ char *get_enterprise_principal_string_filter(TALLOC_CTX *mem_ctx, + const char *princ, + struct dp_option *sdap_basic_opts); + +-bool should_run_posix_check(struct sdap_id_ctx *ctx, +- struct sdap_id_conn_ctx *conn, +- bool id_mapping, +- bool posix_request); +- + char *sdap_get_access_filter(TALLOC_CTX *mem_ctx, + const char *base_filter); + +diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h +index e892c407103b18a296ae6baaf3dcfff11ca4bf31..0790544818633e26ee5a8fbdca556b8230b1df3f 100644 +--- a/src/providers/ldap/sdap.h ++++ b/src/providers/ldap/sdap.h +@@ -511,7 +511,6 @@ struct sdap_server_opts { + char *max_group_value; + char *max_service_value; + char *max_sudo_value; +- bool posix_checked; + }; + + struct sdap_id_ctx; +diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c +index 1e77b1c3c612d28a7d1f7e686cbc0b094b07c89d..8fc832ae5720acac07b0e2a24255f6c5e3d6994b 100644 +--- a/src/providers/ldap/sdap_async.c ++++ b/src/providers/ldap/sdap_async.c +@@ -2572,180 +2572,6 @@ int sdap_asq_search_recv(struct tevent_req *req, + return EOK; + } + +-/* ==POSIX attribute presence test================================= */ +-static void sdap_gc_posix_check_done(struct tevent_req *subreq); +-static errno_t sdap_gc_posix_check_parse(struct sdap_handle *sh, +- struct sdap_msg *msg, +- void *pvt); +- +-struct sdap_gc_posix_check_state { +- struct tevent_context *ev; +- struct sdap_options *opts; +- struct sdap_handle *sh; +- int timeout; +- +- const char **attrs; +- const char *filter; +- +- bool has_posix; +-}; +- +-struct tevent_req * +-sdap_gc_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, +- struct sdap_options *opts, struct sdap_handle *sh, +- int timeout) +-{ +- struct tevent_req *req = NULL; +- struct tevent_req *subreq = NULL; +- struct sdap_gc_posix_check_state *state; +- errno_t ret; +- +- req = tevent_req_create(memctx, &state, struct sdap_gc_posix_check_state); +- if (req == NULL) { +- return NULL; +- } +- state->ev = ev; +- state->sh = sh; +- state->opts = opts; +- state->timeout = timeout; +- +- state->attrs = talloc_array(state, const char *, 4); +- if (state->attrs == NULL) { +- ret = ENOMEM; +- goto fail; +- } +- state->attrs[0] = "objectclass"; +- state->attrs[1] = opts->user_map[SDAP_AT_USER_UID].name; +- state->attrs[2] = opts->group_map[SDAP_AT_GROUP_GID].name; +- state->attrs[3] = NULL; +- +- state->filter = talloc_asprintf(state, +- "(|(&(%s=*)(objectclass=%s))(&(%s=*)(objectclass=%s)))", +- opts->user_map[SDAP_AT_USER_UID].name, +- opts->user_map[SDAP_OC_USER].name, +- opts->group_map[SDAP_AT_GROUP_GID].name, +- opts->group_map[SDAP_OC_GROUP].name); +- if (state->filter == NULL) { +- ret = ENOMEM; +- goto fail; +- } +- +- subreq = sdap_get_generic_ext_send(state, state->ev, state->opts, +- state->sh, +- "", +- LDAP_SCOPE_SUBTREE, state->filter, +- state->attrs, +- NULL, NULL, 1, state->timeout, +- sdap_gc_posix_check_parse, state, +- SDAP_SRCH_FLG_SIZELIMIT_SILENT); +- if (subreq == NULL) { +- ret = ENOMEM; +- goto fail; +- } +- tevent_req_set_callback(subreq, sdap_gc_posix_check_done, req); +- +- return req; +- +-fail: +- tevent_req_error(req, ret); +- tevent_req_post(req, ev); +- return req; +-} +- +-static errno_t sdap_gc_posix_check_parse(struct sdap_handle *sh, +- struct sdap_msg *msg, +- void *pvt) +-{ +- struct berval **vals = NULL; +- struct sdap_gc_posix_check_state *state = +- talloc_get_type(pvt, struct sdap_gc_posix_check_state); +- char *dn; +- char *endptr; +- +- dn = ldap_get_dn(sh->ldap, msg->msg); +- if (dn == NULL) { +- DEBUG(SSSDBG_TRACE_LIBS, +- "Search did not find any entry with POSIX attributes\n"); +- goto done; +- } +- DEBUG(SSSDBG_TRACE_LIBS, "Found [%s] with POSIX attributes\n", dn); +- ldap_memfree(dn); +- +- vals = ldap_get_values_len(sh->ldap, msg->msg, +- state->opts->user_map[SDAP_AT_USER_UID].name); +- if (vals == NULL) { +- vals = ldap_get_values_len(sh->ldap, msg->msg, +- state->opts->group_map[SDAP_AT_GROUP_GID].name); +- if (vals == NULL) { +- DEBUG(SSSDBG_TRACE_LIBS, "Entry does not have POSIX attrs?\n"); +- goto done; +- } +- } +- +- if (vals[0] == NULL) { +- DEBUG(SSSDBG_TRACE_LIBS, "No value for POSIX attr\n"); +- goto done; +- } +- +- errno = 0; +- strtouint32(vals[0]->bv_val, &endptr, 10); +- if (errno || *endptr || (vals[0]->bv_val == endptr)) { +- DEBUG(SSSDBG_MINOR_FAILURE, +- "POSIX attribute is not a number: %s\n", vals[0]->bv_val); +- } +- +- state->has_posix = true; +-done: +- ldap_value_free_len(vals); +- return EOK; +-} +- +-static void sdap_gc_posix_check_done(struct tevent_req *subreq) +-{ +- struct tevent_req *req = tevent_req_callback_data(subreq, +- struct tevent_req); +- struct sdap_gc_posix_check_state *state = +- tevent_req_data(req, struct sdap_gc_posix_check_state); +- errno_t ret; +- +- ret = sdap_get_generic_ext_recv(subreq, NULL, NULL, NULL); +- talloc_zfree(subreq); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, +- "sdap_get_generic_ext_recv failed [%d]: %s\n", +- ret, strerror(ret)); +- tevent_req_error(req, ret); +- return; +- } +- +- /* Positive hit is definitive, no need to search other bases */ +- if (state->has_posix == true) { +- DEBUG(SSSDBG_FUNC_DATA, "Server has POSIX attributes. Global Catalog will " +- "be used for user and group lookups. Note that if " +- "only a subset of POSIX attributes is present " +- "in GC, the non-replicated attributes are " +- "currently not read from the LDAP port\n"); +- tevent_req_done(req); +- return; +- } +- +- /* All bases done! */ +- DEBUG(SSSDBG_TRACE_LIBS, "Cycled through all bases\n"); +- tevent_req_done(req); +-} +- +-int sdap_gc_posix_check_recv(struct tevent_req *req, +- bool *_has_posix) +-{ +- struct sdap_gc_posix_check_state *state = tevent_req_data(req, +- struct sdap_gc_posix_check_state); +- +- TEVENT_REQ_RETURN_ON_ERROR(req); +- +- *_has_posix = state->has_posix; +- return EOK; +-} +- + /* ==Generic Deref Search============================================ */ + enum sdap_deref_type { + SDAP_DEREF_OPENLDAP, +diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h +index 6ca3ed8d82ea7e4cb049b1c65c639b2773b8c296..6d09aca7a3465df4503991f0dc82e2af3871ccd5 100644 +--- a/src/providers/ldap/sdap_async.h ++++ b/src/providers/ldap/sdap_async.h +@@ -281,19 +281,6 @@ int sdap_deref_search_recv(struct tevent_req *req, + size_t *reply_count, + struct sdap_deref_attrs ***reply); + +-/* +- * This request should only be ran against a Global Catalog connection +- * because it uses a NULL search base to search all domains in the forest, +- * which would return an error with an LDAP port: +- * https://technet.microsoft.com/en-us/library/cc755809(v=ws.10).aspx +- */ +-struct tevent_req * +-sdap_gc_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, +- struct sdap_options *opts, struct sdap_handle *sh, +- int timeout); +- +-int sdap_gc_posix_check_recv(struct tevent_req *req, +- bool *_has_posix); + + struct tevent_req * + sdap_sd_search_send(TALLOC_CTX *memctx, +-- +2.17.1 + diff --git a/SOURCES/0031-nss-idmap-allow-empty-buffer-with-SSS_NSS_EX_FLAG_IN.patch b/SOURCES/0031-nss-idmap-allow-empty-buffer-with-SSS_NSS_EX_FLAG_IN.patch deleted file mode 100644 index 7724a87..0000000 --- a/SOURCES/0031-nss-idmap-allow-empty-buffer-with-SSS_NSS_EX_FLAG_IN.patch +++ /dev/null @@ -1,184 +0,0 @@ -From 464a19ecef7c4a0aad22cd9d2c7b2364e3680351 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 2 Nov 2017 11:09:20 +0100 -Subject: [PATCH 31/31] nss-idmap: allow empty buffer with - SSS_NSS_EX_FLAG_INVALIDATE_CACHE - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 859bddc2bf51dc426a3dc56bd9f365e9c5722b65) ---- - src/sss_client/idmap/sss_nss_ex.c | 89 ++++++++++++++++++++++++++------------- - 1 file changed, 60 insertions(+), 29 deletions(-) - -diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c -index 148eb7b35ec236b6272dd203a0035399cfdef73d..dcd9619a8b07ced7498f61b7e809fa46ebffe09e 100644 ---- a/src/sss_client/idmap/sss_nss_ex.c -+++ b/src/sss_client/idmap/sss_nss_ex.c -@@ -103,8 +103,11 @@ errno_t sss_nss_mc_get(struct nss_input *inp) - } - } - --static int check_flags(uint32_t flags) -+static int check_flags(struct nss_input *inp, uint32_t flags, -+ bool *skip_mc, bool *skip_data) - { -+ bool no_data = false; -+ - /* SSS_NSS_EX_FLAG_NO_CACHE and SSS_NSS_EX_FLAG_INVALIDATE_CACHE are - * mutually exclusive */ - if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0 -@@ -112,6 +115,52 @@ static int check_flags(uint32_t flags) - return EINVAL; - } - -+ *skip_mc = false; -+ if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0 -+ || (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) { -+ *skip_mc = true; -+ } -+ -+ switch(inp->cmd) { -+ case SSS_NSS_GETPWNAM: -+ case SSS_NSS_GETPWNAM_EX: -+ case SSS_NSS_GETPWUID: -+ case SSS_NSS_GETPWUID_EX: -+ if (inp->result.pwrep.buffer == NULL -+ || inp->result.pwrep.buflen == 0) { -+ no_data = true; -+ } -+ break; -+ case SSS_NSS_GETGRNAM: -+ case SSS_NSS_GETGRNAM_EX: -+ case SSS_NSS_GETGRGID: -+ case SSS_NSS_GETGRGID_EX: -+ if (inp->result.grrep.buffer == NULL -+ || inp->result.grrep.buflen == 0) { -+ no_data = true; -+ } -+ break; -+ case SSS_NSS_INITGR: -+ case SSS_NSS_INITGR_EX: -+ if (inp->result.initgrrep.ngroups == 0 -+ || inp->result.initgrrep.groups == NULL) { -+ return EINVAL; -+ } -+ break; -+ default: -+ return EINVAL; -+ } -+ -+ *skip_data = false; -+ /* Allow empty buffer with SSS_NSS_EX_FLAG_INVALIDATE_CACHE */ -+ if (no_data) { -+ if ((flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) { -+ *skip_data = true; -+ } else { -+ return ERANGE; -+ } -+ } -+ - return 0; - } - -@@ -128,18 +177,14 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout) - gid_t *new_groups; - size_t idx; - bool skip_mc = false; -+ bool skip_data = false; - -- ret = check_flags(flags); -+ ret = check_flags(inp, flags, &skip_mc, &skip_data); - if (ret != 0) { - return ret; - } - -- if ((flags & SSS_NSS_EX_FLAG_NO_CACHE) != 0 -- || (flags & SSS_NSS_EX_FLAG_INVALIDATE_CACHE) != 0) { -- skip_mc = true; -- } -- -- if (!skip_mc) { -+ if (!skip_mc && !skip_data) { - ret = sss_nss_mc_get(inp); - switch (ret) { - case 0: -@@ -159,7 +204,7 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout) - - sss_nss_timedlock(timeout, &time_left); - -- if (!skip_mc) { -+ if (!skip_mc && !skip_data) { - /* previous thread might already initialize entry in mmap cache */ - ret = sss_nss_mc_get(inp); - switch (ret) { -@@ -196,6 +241,12 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout) - goto out; - } - -+ if (skip_data) { -+ /* No data requested, just return the return code */ -+ ret = 0; -+ goto out; -+ } -+ - if (inp->cmd == SSS_NSS_INITGR || inp->cmd == SSS_NSS_INITGR_EX) { - if ((*(inp->result.initgrrep.ngroups) - *(inp->result.initgrrep.start)) - < num_results) { -@@ -311,10 +362,6 @@ int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd, - .result.pwrep.buffer = buffer, - .result.pwrep.buflen = buflen}; - -- if (buffer == NULL || buflen == 0) { -- return ERANGE; -- } -- - ret = make_name_flag_req_data(name, flags, &inp.rd); - if (ret != 0) { - return ret; -@@ -346,10 +393,6 @@ int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd, - .result.pwrep.buffer = buffer, - .result.pwrep.buflen = buflen}; - -- if (buffer == NULL || buflen == 0) { -- return ERANGE; -- } -- - SAFEALIGN_COPY_UINT32(&req_data[0], &uid, NULL); - SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL); - *result = NULL; -@@ -373,10 +416,6 @@ int sss_nss_getgrnam_timeout(const char *name, struct group *grp, - .result.grrep.buffer = buffer, - .result.grrep.buflen = buflen}; - -- if (buffer == NULL || buflen == 0) { -- return ERANGE; -- } -- - ret = make_name_flag_req_data(name, flags, &inp.rd); - if (ret != 0) { - return ret; -@@ -407,10 +446,6 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp, - .result.grrep.buffer = buffer, - .result.grrep.buflen = buflen}; - -- if (buffer == NULL || buflen == 0) { -- return ERANGE; -- } -- - SAFEALIGN_COPY_UINT32(&req_data[0], &gid, NULL); - SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL); - *result = NULL; -@@ -434,10 +469,6 @@ int sss_nss_getgrouplist_timeout(const char *name, gid_t group, - .input.name = name, - .cmd = SSS_NSS_INITGR_EX}; - -- if (groups == NULL || ngroups == NULL || *ngroups == 0) { -- return EINVAL; -- } -- - ret = make_name_flag_req_data(name, flags, &inp.rd); - if (ret != 0) { - return ret; --- -2.13.6 - diff --git a/SOURCES/0032-BUILD-Properly-expand-variables-in-sssd-ifp.service.patch b/SOURCES/0032-BUILD-Properly-expand-variables-in-sssd-ifp.service.patch deleted file mode 100644 index be96f01..0000000 --- a/SOURCES/0032-BUILD-Properly-expand-variables-in-sssd-ifp.service.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 1925a1bb1e0ea210bd40ec3374726948fb6e4760 Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Tue, 7 Nov 2017 17:11:52 +0100 -Subject: [PATCH 32/35] BUILD: Properly expand variables in sssd-ifp.service -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -systemd[1]: [/usr/lib/systemd/system/sssd-ifp.service:9] - Path '-@environment_file@' is not absolute, ignoring. - -sh-4.2# systemctl cat sssd-ifp.service - # /usr/lib/systemd/system/sssd-ifp.service -[Unit] -Description=SSSD IFP Service responder -Documentation=man:sssd-ifp(5) -After=sssd.service -BindsTo=sssd.service - -[Service] -Environment=DEBUG_LOGGER=--logger=files -EnvironmentFile=-@environment_file@ -Type=dbus -BusName=org.freedesktop.sssd.infopipe -ExecStart=/usr/libexec/sssd/sssd_ifp --uid 0 --gid 0 --dbus-activated ${DEBUG_LOGGER} - -Resolves: -https://pagure.io/SSSD/sssd/issue/3433 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit b495522f3eadde9ad4bb8d125fd70b0d5f07596a) ---- - Makefile.am | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/Makefile.am b/Makefile.am -index 286ba47e3c421864362717be5258de960efca9f2..bbc90d9bad4d22ca0284ea95281a487d42399c05 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1491,7 +1491,7 @@ EXTRA_DIST += \ - src/responder/ifp/org.freedesktop.sssd.infopipe.service.in \ - $(NULL) - --ifp_edit_cmd = $(SED) \ -+ifp_edit_cmd = $(edit_cmd) \ - -e 's|@ifp_exec_cmd[@]|$(ifp_exec_cmd)|g' \ - -e 's|@ifp_systemdservice[@]|$(ifp_systemdservice)|g' \ - -e 's|@ifp_restart[@]|$(ifp_restart)|g' --- -2.13.6 - diff --git a/SOURCES/0032-LDAP-AD-Remove-the-legacy-POSIX-check-from-user-grou.patch b/SOURCES/0032-LDAP-AD-Remove-the-legacy-POSIX-check-from-user-grou.patch new file mode 100644 index 0000000..430f309 --- /dev/null +++ b/SOURCES/0032-LDAP-AD-Remove-the-legacy-POSIX-check-from-user-grou.patch @@ -0,0 +1,385 @@ +From ba23021935fcc984b1000bc007fcd3e52fa752cd Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Sat, 30 Jun 2018 12:31:13 +0200 +Subject: [PATCH] LDAP/AD: Remove the legacy POSIX check from user, group and + enumeration searches +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This code is superseded by the POSIX check in the subdomains provider. + +Related: +https://pagure.io/SSSD/sssd/issue/3755 + +Reviewed-by: Pavel Březina +(cherry picked from commit 8d78119811e2572bb1a05da5abb7c5a2d43d1f97) +--- + src/providers/ad/ad_id.c | 43 +--------- + src/providers/ldap/ldap_id.c | 121 --------------------------- + src/providers/ldap/sdap_async_enum.c | 105 +---------------------- + 3 files changed, 4 insertions(+), 265 deletions(-) + +diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c +index 782d9bc402e71d6b20976367f6afbae82bd25750..96c5677c681e40419172c2e5aa3c32b8403147b1 100644 +--- a/src/providers/ad/ad_id.c ++++ b/src/providers/ad/ad_id.c +@@ -29,28 +29,6 @@ + #include "providers/ldap/sdap_idmap.h" + #include "providers/ldap/sdap_async.h" + +-static void +-disable_gc(struct ad_options *ad_options) +-{ +- errno_t ret; +- +- if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_GC) == false) { +- return; +- } +- +- DEBUG(SSSDBG_IMPORTANT_INFO, "POSIX attributes were requested " +- "but are not present on the server side. Global Catalog " +- "lookups will be disabled\n"); +- +- ret = dp_opt_set_bool(ad_options->basic, +- AD_ENABLE_GC, false); +- if (ret != EOK) { +- DEBUG(SSSDBG_MINOR_FAILURE, +- "Could not turn off GC support\n"); +- /* Not fatal */ +- } +-} +- + static bool ad_account_can_shortcut(struct sdap_idmap_ctx *idmap_ctx, + struct sss_domain_info *domain, + int filter_type, +@@ -296,14 +274,12 @@ ad_handle_acct_info_done(struct tevent_req *subreq) + if (sdap_err == EOK) { + tevent_req_done(req); + return; +- } else if (sdap_err == ERR_NO_POSIX) { +- disable_gc(state->ad_options); + } else if (sdap_err != ENOENT) { + ret = EIO; + goto fail; + } + +- /* Ret is only ENOENT or ERR_NO_POSIX now. Try the next connection */ ++ /* Ret is only ENOENT now. Try the next connection */ + state->cindex++; + ret = ad_handle_acct_info_step(req); + if (ret != EAGAIN) { +@@ -710,22 +686,7 @@ ad_enumeration_done(struct tevent_req *subreq) + + ret = sdap_dom_enum_ex_recv(subreq); + talloc_zfree(subreq); +- if (ret == ERR_NO_POSIX) { +- /* Retry enumerating the same domain again, this time w/o +- * connecting to GC +- */ +- disable_gc(state->id_ctx->ad_options); +- ret = ad_enum_sdom(req, state->sditer, state->id_ctx); +- if (ret != EOK) { +- DEBUG(SSSDBG_OP_FAILURE, +- "Could not retry domain %s\n", state->sditer->dom->name); +- tevent_req_error(req, ret); +- return; +- } +- +- /* Execution will resume in ad_enumeration_done */ +- return; +- } else if (ret != EOK) { ++ if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Could not enumerate domain %s\n", state->sditer->dom->name); + tevent_req_error(req, ret); +diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c +index ebf5d9cb2e2d1cc4b356d431965a00588a876444..9e8289904e60512e088aae77666bcd765bfe3392 100644 +--- a/src/providers/ldap/ldap_id.c ++++ b/src/providers/ldap/ldap_id.c +@@ -66,7 +66,6 @@ struct users_get_state { + + static int users_get_retry(struct tevent_req *req); + static void users_get_connect_done(struct tevent_req *subreq); +-static void users_get_posix_check_done(struct tevent_req *subreq); + static void users_get_search(struct tevent_req *req); + static void users_get_done(struct tevent_req *subreq); + +@@ -408,66 +407,6 @@ static void users_get_connect_done(struct tevent_req *subreq) + return; + } + +- /* If POSIX attributes have been requested with an AD server and we +- * have no idea about POSIX attributes support, run a one-time check +- */ +- if (should_run_posix_check(state->ctx, +- state->conn, +- state->use_id_mapping, +- !state->non_posix)) { +- subreq = sdap_gc_posix_check_send(state, state->ev, state->ctx->opts, +- sdap_id_op_handle(state->op), +- dp_opt_get_int(state->ctx->opts->basic, +- SDAP_SEARCH_TIMEOUT)); +- if (subreq == NULL) { +- tevent_req_error(req, ENOMEM); +- return; +- } +- tevent_req_set_callback(subreq, users_get_posix_check_done, req); +- return; +- } +- +- users_get_search(req); +-} +- +-static void users_get_posix_check_done(struct tevent_req *subreq) +-{ +- errno_t ret; +- errno_t ret2; +- bool has_posix; +- int dp_error; +- struct tevent_req *req = tevent_req_callback_data(subreq, +- struct tevent_req); +- struct users_get_state *state = tevent_req_data(req, +- struct users_get_state); +- +- ret = sdap_gc_posix_check_recv(subreq, &has_posix); +- talloc_zfree(subreq); +- if (ret != EOK) { +- /* We can only finish the id_op on error as the connection +- * is re-used by the user search +- */ +- ret2 = sdap_id_op_done(state->op, ret, &dp_error); +- if (dp_error == DP_ERR_OK && ret2 != EOK) { +- /* retry */ +- ret = users_get_retry(req); +- if (ret != EOK) { +- tevent_req_error(req, ret); +- } +- return; +- } +- } +- +- state->ctx->srv_opts->posix_checked = true; +- +- /* If the check ran to completion, we know for certain about the attributes +- */ +- if (ret == EOK && has_posix == false) { +- state->sdap_ret = ERR_NO_POSIX; +- tevent_req_done(req); +- return; +- } +- + users_get_search(req); + } + +@@ -691,7 +630,6 @@ struct groups_get_state { + + static int groups_get_retry(struct tevent_req *req); + static void groups_get_connect_done(struct tevent_req *subreq); +-static void groups_get_posix_check_done(struct tevent_req *subreq); + static void groups_get_mpg_done(struct tevent_req *subreq); + static errno_t groups_get_handle_no_group(struct tevent_req *req); + static void groups_get_search(struct tevent_req *req); +@@ -953,65 +891,6 @@ static void groups_get_connect_done(struct tevent_req *subreq) + return; + } + +- /* If POSIX attributes have been requested with an AD server and we +- * have no idea about POSIX attributes support, run a one-time check +- */ +- if (should_run_posix_check(state->ctx, +- state->conn, +- state->use_id_mapping, +- !state->non_posix)) { +- subreq = sdap_gc_posix_check_send(state, state->ev, state->ctx->opts, +- sdap_id_op_handle(state->op), +- dp_opt_get_int(state->ctx->opts->basic, +- SDAP_SEARCH_TIMEOUT)); +- if (subreq == NULL) { +- tevent_req_error(req, ENOMEM); +- return; +- } +- tevent_req_set_callback(subreq, groups_get_posix_check_done, req); +- return; +- } +- +- groups_get_search(req); +-} +- +-static void groups_get_posix_check_done(struct tevent_req *subreq) +-{ +- errno_t ret; +- bool has_posix; +- int dp_error; +- struct tevent_req *req = tevent_req_callback_data(subreq, +- struct tevent_req); +- struct groups_get_state *state = tevent_req_data(req, +- struct groups_get_state); +- +- ret = sdap_gc_posix_check_recv(subreq, &has_posix); +- talloc_zfree(subreq); +- if (ret != EOK) { +- /* We can only finish the id_op on error as the connection +- * is re-used by the group search +- */ +- ret = sdap_id_op_done(state->op, ret, &dp_error); +- if (dp_error == DP_ERR_OK && ret != EOK) { +- /* retry */ +- ret = groups_get_retry(req); +- if (ret != EOK) { +- tevent_req_error(req, ret); +- } +- return; +- } +- } +- +- state->ctx->srv_opts->posix_checked = true; +- +- /* If the check ran to completion, we know for certain about the attributes +- */ +- if (has_posix == false) { +- state->sdap_ret = ERR_NO_POSIX; +- tevent_req_done(req); +- return; +- } +- + groups_get_search(req); + } + +diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c +index ea9d51adc7f94145cd7e689893bf7fd81028c5bb..899d59d3831bf473a98b44a7bf4d2007fac84c5e 100644 +--- a/src/providers/ldap/sdap_async_enum.c ++++ b/src/providers/ldap/sdap_async_enum.c +@@ -69,8 +69,6 @@ static errno_t sdap_dom_enum_ex_retry(struct tevent_req *req, + tevent_req_fn tcb); + static bool sdap_dom_enum_ex_connected(struct tevent_req *subreq); + static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq); +-static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq); +-static errno_t sdap_dom_enum_search_users(struct tevent_req *req); + static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq); + static void sdap_dom_enum_ex_get_groups(struct tevent_req *subreq); + static void sdap_dom_enum_ex_groups_done(struct tevent_req *subreq); +@@ -181,118 +179,19 @@ static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq) + struct tevent_req); + struct sdap_dom_enum_ex_state *state = tevent_req_data(req, + struct sdap_dom_enum_ex_state); +- bool use_id_mapping; +- errno_t ret; + + if (sdap_dom_enum_ex_connected(subreq) == false) { + return; + } + +- use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( +- state->ctx->opts->idmap_ctx, +- state->sdom->dom->name, +- state->sdom->dom->domain_id); +- +- /* If POSIX attributes have been requested with an AD server and we +- * have no idea about POSIX attributes support, run a one-time check +- */ +- if (should_run_posix_check(state->ctx, +- state->user_conn, +- use_id_mapping, +- true)) { +- subreq = sdap_gc_posix_check_send(state, state->ev, state->ctx->opts, +- sdap_id_op_handle(state->user_op), +- dp_opt_get_int(state->ctx->opts->basic, +- SDAP_SEARCH_TIMEOUT)); +- if (subreq == NULL) { +- tevent_req_error(req, ENOMEM); +- return; +- } +- tevent_req_set_callback(subreq, +- sdap_dom_enum_ex_posix_check_done, req); +- return; +- } +- +- +- ret = sdap_dom_enum_search_users(req); +- if (ret != EOK) { +- tevent_req_error(req, ret); +- return; +- } +- /* Execution resumes in sdap_dom_enum_ex_users_done */ +-} +- +-static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq) +-{ +- errno_t ret; +- bool has_posix; +- int dp_error; +- +- struct tevent_req *req = tevent_req_callback_data(subreq, +- struct tevent_req); +- struct sdap_dom_enum_ex_state *state = tevent_req_data(req, +- struct sdap_dom_enum_ex_state); +- +- ret = sdap_gc_posix_check_recv(subreq, &has_posix); +- talloc_zfree(subreq); +- if (ret != EOK && ret != ERR_NO_POSIX) { +- /* We can only finish the id_op on error as the connection +- * is re-used by the user search +- */ +- ret = sdap_id_op_done(state->user_op, ret, &dp_error); +- if (dp_error == DP_ERR_OK && ret != EOK) { +- /* retry */ +- ret = sdap_dom_enum_ex_retry(req, state->user_op, +- sdap_dom_enum_ex_get_users); +- if (ret != EOK) { +- tevent_req_error(req, ret); +- } +- return; +- } else if (dp_error == DP_ERR_OFFLINE) { +- DEBUG(SSSDBG_TRACE_FUNC, "Backend is offline, retrying later\n"); +- tevent_req_done(req); +- return; +- } else { +- /* Non-recoverable error */ +- DEBUG(SSSDBG_OP_FAILURE, +- "POSIX check failed: %d: %s\n", ret, sss_strerror(ret)); +- tevent_req_error(req, ret); +- return; +- } +- } +- +- state->ctx->srv_opts->posix_checked = true; +- +- /* If the check ran to completion, we know for certain about the attributes +- */ +- if (has_posix == false) { +- tevent_req_error(req, ERR_NO_POSIX); +- return; +- } +- +- +- ret = sdap_dom_enum_search_users(req); +- if (ret != EOK) { +- tevent_req_error(req, ret); +- return; +- } +- /* Execution resumes in sdap_dom_enum_ex_users_done */ +-} +- +-static errno_t sdap_dom_enum_search_users(struct tevent_req *req) +-{ +- struct sdap_dom_enum_ex_state *state = tevent_req_data(req, +- struct sdap_dom_enum_ex_state); +- struct tevent_req *subreq; +- + subreq = enum_users_send(state, state->ev, + state->ctx, state->sdom, + state->user_op, state->purge); + if (subreq == NULL) { +- return ENOMEM; ++ tevent_req_error(req, ENOMEM); ++ return; + } + tevent_req_set_callback(subreq, sdap_dom_enum_ex_users_done, req); +- return EOK; + } + + static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq) +-- +2.17.1 + diff --git a/SOURCES/0033-AD-Remove-the-legacy-check-from-ad_get_account_domai.patch b/SOURCES/0033-AD-Remove-the-legacy-check-from-ad_get_account_domai.patch new file mode 100644 index 0000000..2862524 --- /dev/null +++ b/SOURCES/0033-AD-Remove-the-legacy-check-from-ad_get_account_domai.patch @@ -0,0 +1,122 @@ +From dcf8f47b85c0c93dd0c70d5a2093fff82f333e91 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 4 Jul 2018 20:10:30 +0200 +Subject: [PATCH] AD: Remove the legacy check from + ad_get_account_domain_posix_check request +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Previously, the POSIX attribute presence check was run as part of the ID +request, so it was necessary to also run the check as part of the +get-domain-for-ID request. + +Since moving the POSIX check to being a part of the subdomain provider, +this is no longer needed as the subdomain provider disables the GC +support on its own if required. Therefore we can just remove the POSIX +check from the get-domain-for-ID request. + +Related: +https://pagure.io/SSSD/sssd/issue/3755 + +Reviewed-by: Pavel Březina +(cherry picked from commit 4273ac0490eeef72d2daa0c7f6cee80d65b6b34d) +--- + src/providers/ad/ad_id.c | 74 ---------------------------------------- + 1 file changed, 74 deletions(-) + +diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c +index 96c5677c681e40419172c2e5aa3c32b8403147b1..1da48433eeb01b069ea6e2829122d93a696fb8a3 100644 +--- a/src/providers/ad/ad_id.c ++++ b/src/providers/ad/ad_id.c +@@ -1041,7 +1041,6 @@ ad_enumeration_recv(struct tevent_req *req) + static errno_t ad_get_account_domain_prepare_search(struct tevent_req *req); + static errno_t ad_get_account_domain_connect_retry(struct tevent_req *req); + static void ad_get_account_domain_connect_done(struct tevent_req *subreq); +-static void ad_get_account_domain_posix_check_done(struct tevent_req *subreq); + static void ad_get_account_domain_search(struct tevent_req *req); + static void ad_get_account_domain_search_done(struct tevent_req *subreq); + static void ad_get_account_domain_evaluate(struct tevent_req *req); +@@ -1264,79 +1263,6 @@ static void ad_get_account_domain_connect_done(struct tevent_req *subreq) + return; + } + +- /* If POSIX attributes have been requested with an AD server and we +- * have no idea about POSIX attributes support, run a one-time check +- */ +- if (state->sdap_id_ctx->srv_opts && +- state->sdap_id_ctx->srv_opts->posix_checked == false) { +- subreq = sdap_gc_posix_check_send(state, +- state->ev, +- state->sdap_id_ctx->opts, +- sdap_id_op_handle(state->op), +- dp_opt_get_int( +- state->sdap_id_ctx->opts->basic, +- SDAP_SEARCH_TIMEOUT)); +- if (subreq == NULL) { +- tevent_req_error(req, ENOMEM); +- return; +- } +- tevent_req_set_callback(subreq, ad_get_account_domain_posix_check_done, req); +- return; +- } +- +- ad_get_account_domain_search(req); +-} +- +-static void ad_get_account_domain_posix_check_done(struct tevent_req *subreq) +-{ +- struct tevent_req *req = tevent_req_callback_data(subreq, +- struct tevent_req); +- struct ad_get_account_domain_state *state = tevent_req_data(req, +- struct ad_get_account_domain_state); +- int dp_error = DP_ERR_FATAL; +- bool has_posix; +- errno_t ret; +- errno_t ret2; +- +- ret = sdap_gc_posix_check_recv(subreq, &has_posix); +- talloc_zfree(subreq); +- if (ret != EOK) { +- /* We can only finish the id_op on error as the connection +- * is re-used by the real search +- */ +- ret2 = sdap_id_op_done(state->op, ret, &dp_error); +- if (dp_error == DP_ERR_OK && ret2 != EOK) { +- /* retry */ +- ret = ad_get_account_domain_connect_retry(req); +- if (ret != EOK) { +- tevent_req_error(req, ret); +- } +- return; +- } +- +- tevent_req_error(req, ret); +- return; +- } +- +- state->sdap_id_ctx->srv_opts->posix_checked = true; +- +- /* +- * If the GC has no POSIX attributes, there is nothing we can do. +- * Return an error and let the responders disable the functionality +- * from now on. +- */ +- if (has_posix == false) { +- DEBUG(SSSDBG_CONF_SETTINGS, +- "The Global Catalog has no POSIX attributes\n"); +- +- disable_gc(state->id_ctx->ad_options); +- dp_reply_std_set(&state->reply, +- DP_ERR_DECIDE, ERR_GET_ACCT_DOM_NOT_SUPPORTED, +- NULL); +- tevent_req_done(req); +- return; +- } +- + ad_get_account_domain_search(req); + } + +-- +2.17.1 + diff --git a/SOURCES/0033-SYSTEMD-Clean-pid-file-in-corner-cases.patch b/SOURCES/0033-SYSTEMD-Clean-pid-file-in-corner-cases.patch deleted file mode 100644 index ce1c4ec..0000000 --- a/SOURCES/0033-SYSTEMD-Clean-pid-file-in-corner-cases.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 7f4a89ff4e7dc7c3ffac24ac87187dca1e9e7d1e Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Wed, 8 Nov 2017 14:09:36 +0100 -Subject: [PATCH 33/35] SYSTEMD: Clean pid file in corner cases -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -SSSD can cleanup pid file in case of standard stopping of daemon. -It's done in function monitor_cleanup. However monitor does not have a -change to cleanup file in case of OOM or sending SIGKILL to monitor. - -Even though PIDFile is not necessary for services with Type notify -we should let systemd to clean this file in unexpected situations. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3528 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit f4b808c83ecbaf36c7069440535d62990e32d55d) ---- - src/sysv/systemd/sssd.service.in | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/sysv/systemd/sssd.service.in b/src/sysv/systemd/sssd.service.in -index cea848fac80303d6fae12dd84316a91dbc60072d..0c515d34caaa3ea397c4c7e95eef0188df170840 100644 ---- a/src/sysv/systemd/sssd.service.in -+++ b/src/sysv/systemd/sssd.service.in -@@ -10,6 +10,7 @@ EnvironmentFile=-@environment_file@ - ExecStart=@sbindir@/sssd -i ${DEBUG_LOGGER} - Type=notify - NotifyAccess=main -+PIDFile=@localstatedir@/run/sssd.pid - - [Install] - WantedBy=multi-user.target --- -2.13.6 - diff --git a/SOURCES/0034-AD-Add-Global-Catalog-usability-check-in-subdomain-c.patch b/SOURCES/0034-AD-Add-Global-Catalog-usability-check-in-subdomain-c.patch new file mode 100644 index 0000000..0c323ec --- /dev/null +++ b/SOURCES/0034-AD-Add-Global-Catalog-usability-check-in-subdomain-c.patch @@ -0,0 +1,423 @@ +From 7f9567ba8d62536c4aeb68897316781e82116c21 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 4 Jul 2018 13:14:40 +0200 +Subject: [PATCH] AD: Add Global Catalog usability check in subdomain code by + looking at the schema +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Addsa a new tevent request which checks for the presence of uidNumber +and gidNumber under the schema naming context, which is typically +cn=schema,cn=configuration,$BASEDN. For both objects representing each of +the attributes, the isMemberOfPartialAttributeSet attribute is requested. If +this attribute is set to TRUE, then the attribute corresponding to this +schema object had been replicated to the Global Catalog. + +Because the isMemberOfPartialAttributeSet is not replicated to the GC +itself, we use the LDAP connection for the search. + +Related: +https://pagure.io/SSSD/sssd/issue/3755 + +Reviewed-by: Pavel Březina +(cherry picked from commit ba96e7b839b875946f03787a3a57f259230a0fef) +--- + src/providers/ad/ad_subdomains.c | 308 +++++++++++++++++++++++++++++-- + 1 file changed, 288 insertions(+), 20 deletions(-) + +diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c +index 84886e920b37f8803d85ce0903b74e6c809a8904..549c2c1f76d4bbccdf03c6ab619fba5f9186358f 100644 +--- a/src/providers/ad/ad_subdomains.c ++++ b/src/providers/ad/ad_subdomains.c +@@ -54,9 +54,39 @@ + #define SLAVE_DOMAIN_FILTER "(&"SLAVE_DOMAIN_FILTER_BASE")" + #define FOREST_ROOT_FILTER_FMT "(&"SLAVE_DOMAIN_FILTER_BASE"(cn=%s))" + ++/* Attributes of schema objects. See e.g. ++ * https://docs.microsoft.com/en-us/windows/desktop/AD/characteristics-of-attributes ++ * for more details ++ */ ++#define AD_SCHEMA_AT_OC "attributeSchema" ++#define AD_AT_SCHEMA_NAME "cn" ++#define AD_AT_SCHEMA_IS_REPL "isMemberOfPartialAttributeSet" ++ + /* do not refresh more often than every 5 seconds for now */ + #define AD_SUBDOMAIN_REFRESH_LIMIT 5 + ++static void ++ad_disable_gc(struct ad_options *ad_options) ++{ ++ errno_t ret; ++ ++ if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_GC) == false) { ++ return; ++ } ++ ++ DEBUG(SSSDBG_IMPORTANT_INFO, "POSIX attributes were requested " ++ "but are not present on the server side. Global Catalog " ++ "lookups will be disabled\n"); ++ ++ ret = dp_opt_set_bool(ad_options->basic, ++ AD_ENABLE_GC, false); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, ++ "Could not turn off GC support\n"); ++ /* Not fatal */ ++ } ++} ++ + static struct sss_domain_info * + ads_get_root_domain(struct be_ctx *be_ctx, struct sysdb_attrs *attrs) + { +@@ -1261,6 +1291,212 @@ static errno_t ad_get_root_domain_recv(TALLOC_CTX *mem_ctx, + return EOK; + } + ++static void ad_check_gc_usability_search_done(struct tevent_req *subreq); ++ ++struct ad_check_gc_usability_state { ++ struct sdap_options *sdap_opts; ++ ++ const char *attrs[3]; ++ ++ bool is_gc_usable; ++}; ++ ++static struct tevent_req * ++ad_check_gc_usability_send(TALLOC_CTX *mem_ctx, ++ struct tevent_context *ev, ++ struct ad_options *ad_options, ++ struct sdap_options *sdap_opts, ++ struct sdap_id_op *op, ++ const char *domain_name, ++ const char *domain_sid) ++{ ++ struct ad_check_gc_usability_state *state = NULL; ++ struct tevent_req *req = NULL; ++ struct tevent_req *subreq = NULL; ++ const char *filter = NULL; ++ errno_t ret; ++ bool uses_id_mapping; ++ ++ req = tevent_req_create(mem_ctx, &state, ++ struct ad_check_gc_usability_state); ++ if (req == NULL) { ++ return NULL; ++ } ++ state->sdap_opts = sdap_opts; ++ state->is_gc_usable = false; ++ ++ if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_GC) == false) { ++ DEBUG(SSSDBG_TRACE_FUNC, "GC explicitly disabled\n"); ++ state->is_gc_usable = false; ++ ret = EOK; ++ goto immediately; ++ } ++ ++ uses_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( ++ sdap_opts->idmap_ctx, ++ domain_name, ++ domain_sid); ++ if (uses_id_mapping == true) { ++ DEBUG(SSSDBG_TRACE_FUNC, "GC always usable while ID mapping\n"); ++ state->is_gc_usable = true; ++ ret = EOK; ++ goto immediately; ++ } ++ ++ /* The schema partition is replicated across all DCs in the forest, so ++ * it's safe to use the baseDN even if e.g. joined to a child domain ++ * even though the base DN "looks" like a part of the forest root ++ * tree. On the other hand, it doesn't make sense to guess the value ++ * if we can't detect it from the rootDSE. ++ */ ++ if (state->sdap_opts->schema_basedn == NULL) { ++ DEBUG(SSSDBG_TRACE_FUNC, ++ "No idea where to look for the schema, disabling GC\n"); ++ state->is_gc_usable = false; ++ ret = EOK; ++ goto immediately; ++ } ++ ++ state->attrs[0] = AD_AT_SCHEMA_NAME; ++ state->attrs[1] = AD_AT_SCHEMA_IS_REPL; ++ state->attrs[2] = NULL; ++ ++ DEBUG(SSSDBG_TRACE_FUNC, "Checking for POSIX attributes in GC\n"); ++ ++ filter = talloc_asprintf( ++ state, ++ "(&(objectclass=%s)(|(%s=%s)(%s=%s)))", ++ AD_SCHEMA_AT_OC, ++ AD_AT_SCHEMA_NAME, ++ state->sdap_opts->user_map[SDAP_AT_USER_UID].name, ++ AD_AT_SCHEMA_NAME, ++ state->sdap_opts->group_map[SDAP_AT_GROUP_GID].name); ++ if (filter == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } ++ ++ subreq = sdap_get_generic_send(state, ++ ev, ++ state->sdap_opts, ++ sdap_id_op_handle(op), ++ state->sdap_opts->schema_basedn, ++ LDAP_SCOPE_SUBTREE, ++ filter, ++ state->attrs, ++ NULL, 0, ++ dp_opt_get_int(state->sdap_opts->basic, ++ SDAP_SEARCH_TIMEOUT), ++ false); ++ if (subreq == NULL) { ++ ret = ENOMEM; ++ goto immediately; ++ } ++ tevent_req_set_callback(subreq, ad_check_gc_usability_search_done, req); ++ ++ return req; ++ ++immediately: ++ if (ret == EOK) { ++ tevent_req_done(req); ++ } else { ++ tevent_req_error(req, ret); ++ } ++ tevent_req_post(req, ev); ++ ++ return req; ++} ++ ++static void ad_check_gc_usability_search_done(struct tevent_req *subreq) ++{ ++ struct tevent_req *req = tevent_req_callback_data(subreq, ++ struct tevent_req); ++ struct ad_check_gc_usability_state *state = tevent_req_data(req, ++ struct ad_check_gc_usability_state); ++ errno_t ret; ++ size_t reply_count; ++ struct sysdb_attrs **reply = NULL; ++ bool uid = false; ++ bool gid = false; ++ ++ ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_OP_FAILURE, ++ "sdap_get_generic_recv failed [%d]: %s\n", ++ ret, strerror(ret)); ++ /* We continue to finish sdap_id_op. */ ++ } ++ ++ if (reply_count == 0) { ++ DEBUG(SSSDBG_TRACE_LIBS, ++ "Nothing found, so no POSIX attrs can exist\n"); ++ state->is_gc_usable = false; ++ tevent_req_done(req); ++ return; ++ } ++ ++ for (size_t i = 0; i < reply_count; i++) { ++ const char *name = NULL; ++ const char *is_in_partial_set = NULL; ++ bool *val = NULL; ++ ++ ret = sysdb_attrs_get_string(reply[i], AD_AT_SCHEMA_NAME, &name); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot get "AD_AT_SCHEMA_NAME); ++ continue; ++ } ++ ++ if (strcasecmp(name, state->sdap_opts->user_map[SDAP_AT_USER_UID].name) == 0) { ++ val = &uid; ++ } else if (strcasecmp(name, state->sdap_opts->user_map[SDAP_AT_USER_GID].name) == 0) { ++ val = &gid; ++ } else { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected attribute\n"); ++ continue; ++ } ++ ++ ret = sysdb_attrs_get_string(reply[i], ++ AD_AT_SCHEMA_IS_REPL, ++ &is_in_partial_set); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot get "AD_AT_SCHEMA_IS_REPL); ++ continue; ++ } ++ ++ if (strcasecmp(is_in_partial_set, "true") == 0) { ++ *val = true; ++ } ++ } ++ ++ if (uid == true && gid == true) { ++ state->is_gc_usable = true; ++ } ++ ++ if (state->is_gc_usable == true) { ++ DEBUG(SSSDBG_FUNC_DATA, "Server has POSIX attributes. Global Catalog will " ++ "be used for user and group lookups. Note that if " ++ "only a subset of POSIX attributes is present " ++ "in GC, the non-replicated attributes are " ++ "currently not read from the LDAP port\n"); ++ } ++ ++ tevent_req_done(req); ++} ++ ++static errno_t ad_check_gc_usability_recv(struct tevent_req *req, ++ bool *_is_gc_usable) ++{ ++ struct ad_check_gc_usability_state *state = NULL; ++ ++ state = tevent_req_data(req, struct ad_check_gc_usability_state); ++ ++ TEVENT_REQ_RETURN_ON_ERROR(req); ++ ++ *_is_gc_usable = state->is_gc_usable; ++ return EOK; ++} ++ + struct ad_subdomains_refresh_state { + struct tevent_context *ev; + struct be_ctx *be_ctx; +@@ -1268,11 +1504,14 @@ struct ad_subdomains_refresh_state { + struct sdap_id_op *sdap_op; + struct sdap_id_ctx *id_ctx; + struct ad_options *ad_options; ++ ++ char *forest; + }; + + static errno_t ad_subdomains_refresh_retry(struct tevent_req *req); + static void ad_subdomains_refresh_connect_done(struct tevent_req *subreq); + static void ad_subdomains_refresh_master_done(struct tevent_req *subreq); ++static void ad_subdomains_refresh_gc_check_done(struct tevent_req *subreq); + static void ad_subdomains_refresh_root_done(struct tevent_req *subreq); + static void ad_subdomains_refresh_done(struct tevent_req *subreq); + +@@ -1385,37 +1624,73 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq) + struct ad_subdomains_refresh_state *state; + struct tevent_req *req; + const char *realm; +- const char *ad_domain; + char *master_sid; + char *flat_name; +- char *forest; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct ad_subdomains_refresh_state); + + ret = ad_master_domain_recv(subreq, state, &flat_name, &master_sid, +- NULL, &forest); ++ NULL, &state->forest); + talloc_zfree(subreq); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get master domain information " + "[%d]: %s\n", ret, sss_strerror(ret)); +- goto done; ++ tevent_req_error(req, ret); ++ return; + } + + realm = dp_opt_get_cstring(state->ad_options->basic, AD_KRB5_REALM); + if (realm == NULL) { + DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm.\n"); +- ret = EINVAL; +- goto done; ++ tevent_req_error(req, EINVAL); ++ return; + } + + ret = sysdb_master_domain_add_info(state->be_ctx->domain, realm, +- flat_name, master_sid, forest, NULL); ++ flat_name, master_sid, state->forest, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot save master domain info [%d]: %s\n", + ret, sss_strerror(ret)); +- goto done; ++ tevent_req_error(req, ret); ++ return; ++ } ++ ++ subreq = ad_check_gc_usability_send(state, ++ state->ev, ++ state->ad_options, ++ state->id_ctx->opts, ++ state->sdap_op, ++ state->be_ctx->domain->name, ++ master_sid); ++ if (subreq == NULL) { ++ tevent_req_error(req, ENOMEM); ++ return; ++ } ++ tevent_req_set_callback(subreq, ad_subdomains_refresh_gc_check_done, req); ++} ++ ++static void ad_subdomains_refresh_gc_check_done(struct tevent_req *subreq) ++{ ++ struct ad_subdomains_refresh_state *state; ++ struct tevent_req *req; ++ const char *ad_domain; ++ bool is_gc_usable; ++ errno_t ret; ++ ++ req = tevent_req_callback_data(subreq, struct tevent_req); ++ state = tevent_req_data(req, struct ad_subdomains_refresh_state); ++ ++ ret = ad_check_gc_usability_recv(subreq, &is_gc_usable); ++ talloc_zfree(subreq); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get GC usability status\n"); ++ is_gc_usable = false; ++ } ++ ++ if (is_gc_usable == false) { ++ ad_disable_gc(state->ad_options); + } + + /* +@@ -1428,7 +1703,8 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq) + state->be_ctx->domain->name) == 0) { + DEBUG(SSSDBG_TRACE_FUNC, + "No other enabled domain than master.\n"); +- goto done; ++ tevent_req_done(req); ++ return; + } + } + } +@@ -1440,24 +1716,16 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq) + ad_domain = state->sd_ctx->be_ctx->domain->name; + } + +- subreq = ad_get_root_domain_send(state, state->ev, ad_domain, forest, ++ subreq = ad_get_root_domain_send(state, state->ev, ad_domain, state->forest, + sdap_id_op_handle(state->sdap_op), + state->sd_ctx); + if (subreq == NULL) { +- ret = ENOMEM; +- goto done; ++ tevent_req_error(req, ENOMEM); ++ return; + } + + tevent_req_set_callback(subreq, ad_subdomains_refresh_root_done, req); + return; +- +-done: +- if (ret != EOK) { +- tevent_req_error(req, ret); +- return; +- } +- +- tevent_req_done(req); + } + + static void ad_subdomains_refresh_root_done(struct tevent_req *subreq) +-- +2.17.1 + diff --git a/SOURCES/0034-CHILD-Pass-information-about-logger-to-children.patch b/SOURCES/0034-CHILD-Pass-information-about-logger-to-children.patch deleted file mode 100644 index a254cd8..0000000 --- a/SOURCES/0034-CHILD-Pass-information-about-logger-to-children.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 3ada67750d3d0dc6188c03cc996b98e7578971a4 Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Wed, 8 Nov 2017 08:13:02 +0100 -Subject: [PATCH 34/35] CHILD: Pass information about logger to children -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Variables debug_to_file or debug_to_stderr were not set -because back-end already user parameter --logger=%s. -And therefore logs were not sent to files. - -It could only work in case of direct usage of --debug-to-files in back-end via -command configuration option. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3433 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit a24954cc19285b197fb287bfa7aa01949c92b17d) ---- - src/p11_child/p11_child_nss.c | 4 +++- - src/providers/ad/ad_gpo_child.c | 3 ++- - src/providers/ipa/selinux_child.c | 3 ++- - src/providers/krb5/krb5_child.c | 3 ++- - src/providers/ldap/ldap_child.c | 3 ++- - src/util/child_common.c | 24 ++++++++++-------------- - 6 files changed, 21 insertions(+), 19 deletions(-) - -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index e7dbcb689220d1cd2585fbde5f26e84f8fa15cc2..b0ec69be321c4b4186ce851c07bfcc3e1afe9694 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -537,7 +537,7 @@ int main(int argc, const char *argv[]) - int opt; - poptContext pc; - int debug_fd = -1; -- char *opt_logger = NULL; -+ const char *opt_logger = NULL; - errno_t ret; - TALLOC_CTX *main_ctx = NULL; - char *cert; -@@ -673,7 +673,9 @@ int main(int argc, const char *argv[]) - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n"); - } -+ opt_logger = sss_logger_str[FILES_LOGGER]; - } -+ - sss_set_logger(opt_logger); - - DEBUG(SSSDBG_TRACE_FUNC, "p11_child started.\n"); -diff --git a/src/providers/ad/ad_gpo_child.c b/src/providers/ad/ad_gpo_child.c -index 5375cc691e8649c289672b74c4bfe5266c8222c9..a0bd6e13a31fe0f92924d49302d1b8b17bac4d67 100644 ---- a/src/providers/ad/ad_gpo_child.c -+++ b/src/providers/ad/ad_gpo_child.c -@@ -687,7 +687,7 @@ main(int argc, const char *argv[]) - int opt; - poptContext pc; - int debug_fd = -1; -- char *opt_logger = NULL; -+ const char *opt_logger = NULL; - errno_t ret; - int sysvol_gpt_version; - int result; -@@ -744,6 +744,7 @@ main(int argc, const char *argv[]) - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n"); - } -+ opt_logger = sss_logger_str[FILES_LOGGER]; - } - - sss_set_logger(opt_logger); -diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c -index 120492686963241b7e419413f489cc38953e32f2..a7e20f715626d0f3ecef7cc06f3de5d44b6a15c1 100644 ---- a/src/providers/ipa/selinux_child.c -+++ b/src/providers/ipa/selinux_child.c -@@ -206,7 +206,7 @@ int main(int argc, const char *argv[]) - struct response *resp = NULL; - ssize_t written; - bool needs_update; -- char *opt_logger = NULL; -+ const char *opt_logger = NULL; - - struct poptOption long_options[] = { - POPT_AUTOHELP -@@ -254,6 +254,7 @@ int main(int argc, const char *argv[]) - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n"); - } -+ opt_logger = sss_logger_str[FILES_LOGGER]; - } - - sss_set_logger(opt_logger); -diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c -index 700338e47a3f9ac6fcf11b4c92364dbdb4f9bcf7..7b56002377ac22472c3eea1aef687109757c22db 100644 ---- a/src/providers/krb5/krb5_child.c -+++ b/src/providers/krb5/krb5_child.c -@@ -3020,7 +3020,7 @@ int main(int argc, const char *argv[]) - int opt; - poptContext pc; - int debug_fd = -1; -- char *opt_logger = NULL; -+ const char *opt_logger = NULL; - errno_t ret; - krb5_error_code kerr; - uid_t fast_uid; -@@ -3097,6 +3097,7 @@ int main(int argc, const char *argv[]) - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n"); - } -+ opt_logger = sss_logger_str[FILES_LOGGER]; - } - - sss_set_logger(opt_logger); -diff --git a/src/providers/ldap/ldap_child.c b/src/providers/ldap/ldap_child.c -index baeed239db5dc7ffa482edcbc155f25f718c8249..c0618d6d8828f102c32cf56731995e2b370590e7 100644 ---- a/src/providers/ldap/ldap_child.c -+++ b/src/providers/ldap/ldap_child.c -@@ -599,7 +599,7 @@ int main(int argc, const char *argv[]) - int kerr; - int opt; - int debug_fd = -1; -- char *opt_logger = NULL; -+ const char *opt_logger = NULL; - poptContext pc; - TALLOC_CTX *main_ctx = NULL; - uint8_t *buf = NULL; -@@ -657,6 +657,7 @@ int main(int argc, const char *argv[]) - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "set_debug_file_from_fd failed.\n"); - } -+ opt_logger = sss_logger_str[FILES_LOGGER]; - } - - sss_set_logger(opt_logger); -diff --git a/src/util/child_common.c b/src/util/child_common.c -index dc070f26446305e07cbb34edd1e4d72db72aedc5..203c115f9e7c4ecc2178b5660473d4f960fbbb6d 100644 ---- a/src/util/child_common.c -+++ b/src/util/child_common.c -@@ -630,14 +630,11 @@ static errno_t prepare_child_argv(TALLOC_CTX *mem_ctx, - } - - /* Save the current state in case an interrupt changes it */ -- bool child_debug_to_file = debug_to_file; - bool child_debug_timestamps = debug_timestamps; - bool child_debug_microseconds = debug_microseconds; -- bool child_debug_stderr = debug_to_stderr; - - if (!extra_args_only) { -- if (child_debug_to_file) argc++; -- if (child_debug_stderr) argc++; -+ argc++; - } - - if (extra_argv) { -@@ -675,21 +672,20 @@ static errno_t prepare_child_argv(TALLOC_CTX *mem_ctx, - goto fail; - } - -- if (child_debug_stderr) { -- argv[--argc] = talloc_strdup(argv, "--logger=stderr"); -- if (argv[argc] == NULL) { -- ret = ENOMEM; -- goto fail; -- } -- } -- -- if (child_debug_to_file) { -+ if (sss_logger == FILES_LOGGER) { - argv[--argc] = talloc_asprintf(argv, "--debug-fd=%d", - child_debug_fd); - if (argv[argc] == NULL) { - ret = ENOMEM; - goto fail; - } -+ } else { -+ argv[--argc] = talloc_asprintf(argv, "--logger=%s", -+ sss_logger_str[sss_logger]); -+ if (argv[argc] == NULL) { -+ ret = ENOMEM; -+ goto fail; -+ } - } - - argv[--argc] = talloc_asprintf(argv, "--debug-timestamps=%d", -@@ -816,7 +812,7 @@ errno_t child_debug_init(const char *logfile, int *debug_fd) - return EOK; - } - -- if (debug_to_file != 0 && *debug_fd == -1) { -+ if (sss_logger == FILES_LOGGER && *debug_fd == -1) { - ret = open_debug_file_ex(logfile, &debug_filep, false); - if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, "Error setting up logging (%d) [%s]\n", --- -2.13.6 - diff --git a/SOURCES/0035-LDAP-Improve-error-treatment-from-sdap_cli_connect-i.patch b/SOURCES/0035-LDAP-Improve-error-treatment-from-sdap_cli_connect-i.patch deleted file mode 100644 index 0854ab3..0000000 --- a/SOURCES/0035-LDAP-Improve-error-treatment-from-sdap_cli_connect-i.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 1f46fa6760913de0f757e39106936d24e5736912 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= -Date: Tue, 7 Nov 2017 23:34:42 +0100 -Subject: [PATCH 35/35] LDAP: Improve error treatment from sdap_cli_connect() - in ldap_auth -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Because we weren't treating the errors coming from -sdap_cli_connect_recv() properly we ended up introducing a regression in -the commit add72860c7, related to offline authentication. - -From now on, let's properly treat errors coming from auth_connect_send(), -which were treated before by going offline when be_resolve_server_recv() -failed, and propagate ETIMEDOUT to the request, thus going offline and -allowing offline authentication on those cases. - -Related: -https://pagure.io/SSSD/sssd/issue/3451 - -Signed-off-by: Fabiano Fidêncio -Reviewed-by: Sumit Bose -(cherry picked from commit 20d18db36096e3fa2636143a83a12a2e3a7f26d6) ---- - src/providers/ldap/ldap_auth.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c -index a3b1480aae4272d2e10f105a1eaf3a5816c3487c..2e0e2cfd6f8af2bf0c9ad15bd956a55a34777a3c 100644 ---- a/src/providers/ldap/ldap_auth.c -+++ b/src/providers/ldap/ldap_auth.c -@@ -716,8 +716,20 @@ static void auth_connect_done(struct tevent_req *subreq) - ret = sdap_cli_connect_recv(subreq, state, NULL, &state->sh, NULL); - talloc_zfree(subreq); - if (ret != EOK) { -- if (auth_connect_send(req) == NULL) { -- tevent_req_error(req, ENOMEM); -+ /* As sdap_cli_connect_recv() returns EIO in case all the servers are -+ * down and we have to go offline, let's treat it accordingly here and -+ * allow the PAM responder to with to offline authentication. -+ * -+ * Unfortunately, there's not much pattern within our code and the way -+ * to indicate we're going down in this part of the code is returning -+ * an ETIMEDOUT. -+ */ -+ if (ret == EIO) { -+ tevent_req_error(req, ETIMEDOUT); -+ } else { -+ if (auth_connect_send(req) == NULL) { -+ tevent_req_error(req, ENOMEM); -+ } - } - return; - } --- -2.13.6 - diff --git a/SOURCES/0035-SDAP-Detect-schemaNamingContext-from-the-rootDSE.patch b/SOURCES/0035-SDAP-Detect-schemaNamingContext-from-the-rootDSE.patch new file mode 100644 index 0000000..6397fc5 --- /dev/null +++ b/SOURCES/0035-SDAP-Detect-schemaNamingContext-from-the-rootDSE.patch @@ -0,0 +1,92 @@ +From bf4580b2f893cfb29d804a9fe6bb2d6247bb5cf2 Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Sun, 8 Jul 2018 22:17:41 +0200 +Subject: [PATCH] SDAP: Detect schemaNamingContext from the rootDSE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Whether an attribute is replicated to the Global Catalog or not can be +detected by checking the value of the isMemberOfPartialAttributeSet +attribute: +https://docs.microsoft.com/en-us/windows/desktop/ADSchema/a-ismemberofpartialattributeset + +This attribute is present in all objects with the objectClass +attributeSchema in AD: +https://docs.microsoft.com/en-us/windows/desktop/AD/characteristics-of-attributes + +And finally, the attributeSchema objects in AD are present in a schema +naming context. The schema naming context is replicated to all DCs in the +forest even though their own naming context might be different: +https://docs.microsoft.com/en-us/windows/desktop/ad/naming-contexts-and-partitions + +Where the schema naming context is located is given by the +schemaNamingContext attribute of the rootDSE. + +This patch is trivial on its own and just reads schemaNamingContext from +the rootDSE and stores it in the sdap_options structure for later use. + +Related: +https://pagure.io/SSSD/sssd/issue/3755 + +Reviewed-by: Pavel Březina +(cherry picked from commit c8d1c1b734a1763b3e1233f060cc5c8d6db078e9) +--- + src/providers/ldap/sdap.c | 10 ++++++++++ + src/providers/ldap/sdap.h | 3 +++ + 2 files changed, 13 insertions(+) + +diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c +index 0241a99e49e94345753399d5d62639c99b95ee77..5c9d0a45dfb96e8901467aa6a3391b8df84f6d42 100644 +--- a/src/providers/ldap/sdap.c ++++ b/src/providers/ldap/sdap.c +@@ -1284,6 +1284,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx, + const char *last_usn_name; + const char *last_usn_value; + const char *entry_usn_name; ++ const char *schema_nc = NULL; + char *endptr = NULL; + int ret; + int i; +@@ -1400,6 +1401,15 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx, + "(%s). Continuing without AD performance enhancements\n", + strerror(ret)); + } ++ ++ ret = sysdb_attrs_get_string(rootdse, ++ SDAP_ROOTDSE_ATTR_AD_SCHEMA_NC, ++ &schema_nc); ++ if (ret == EOK) { ++ DEBUG(SSSDBG_CONF_SETTINGS, ++ "Will look for schema at [%s]\n", schema_nc); ++ opts->schema_basedn = talloc_strdup(opts, schema_nc); ++ } + } + + if (!last_usn_name) { +diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h +index 0790544818633e26ee5a8fbdca556b8230b1df3f..31c25c32f059b4290a7511600cee638ee7a269e8 100644 +--- a/src/providers/ldap/sdap.h ++++ b/src/providers/ldap/sdap.h +@@ -130,6 +130,7 @@ struct sdap_ppolicy_data { + #define SDAP_ROOTDSE_ATTR_NAMING_CONTEXTS "namingContexts" + #define SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT "defaultNamingContext" + #define SDAP_ROOTDSE_ATTR_AD_VERSION "domainControllerFunctionality" ++#define SDAP_ROOTDSE_ATTR_AD_SCHEMA_NC "schemaNamingContext" + + #define SDAP_IPA_USN "entryUSN" + #define SDAP_IPA_LAST_USN "lastUSN" +@@ -496,8 +497,10 @@ struct sdap_options { + /* The search bases for the domain or its subdomain */ + struct sdap_domain *sdom; + ++ /* The options below are normally only used with AD */ + bool support_matching_rule; + enum dc_functional_level dc_functional_level; ++ const char *schema_basedn; + + /* Certificate mapping support */ + struct sdap_certmap_ctx *sdap_certmap_ctx; +-- +2.17.1 + diff --git a/SOURCES/0036-deskprofile-don-t-bail-if-we-fail-to-save-one-profil.patch b/SOURCES/0036-deskprofile-don-t-bail-if-we-fail-to-save-one-profil.patch new file mode 100644 index 0000000..820722b --- /dev/null +++ b/SOURCES/0036-deskprofile-don-t-bail-if-we-fail-to-save-one-profil.patch @@ -0,0 +1,45 @@ +From ef96cf36996d9e5802e529e5e812515ec3bda65c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= +Date: Thu, 12 Jul 2018 23:55:03 +0200 +Subject: [PATCH] deskprofile: don't bail if we fail to save one profile +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Due to different reasons (a bug on fleet-commander, for instance?) we +may face the situation where one profile ends up stored in freeipa on a +half-broken state (with no data, for instance). + +In case it happens, we should try our best to save the not broken +profiles and just skip the broken ones instead of bailing the whole +operation. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3773 + +Signed-off-by: Fabiano Fidêncio +Reviewed-by: Jakub Hrozek +(cherry picked from commit efd6702e5f70bb3df0f840dd3ce9f8f9264661ba) + +DOWNSTREAM: +Resolves: rhbz#1600822 - SSSD bails out saving desktop profiles in case an invalid profile is found +--- + src/providers/ipa/ipa_session.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/providers/ipa/ipa_session.c b/src/providers/ipa/ipa_session.c +index 25ad5ce519e6923d7a4d8aa81e72b109ae36dbe1..33c64e5b7af9bd3353770f422be42a0b6ac23e09 100644 +--- a/src/providers/ipa/ipa_session.c ++++ b/src/providers/ipa/ipa_session.c +@@ -768,7 +768,7 @@ ipa_pam_session_handler_save_deskprofile_rules( + DEBUG(SSSDBG_OP_FAILURE, + "Failed to save a Desktop Profile Rule to disk [%d]: %s\n", + ret, sss_strerror(ret)); +- goto done; ++ continue; + } + } + +-- +2.17.1 + diff --git a/SOURCES/0036-p11_child-return-multiple-certs.patch b/SOURCES/0036-p11_child-return-multiple-certs.patch deleted file mode 100644 index d504f7f..0000000 --- a/SOURCES/0036-p11_child-return-multiple-certs.patch +++ /dev/null @@ -1,598 +0,0 @@ -From 426dd731fe7c804c4b9d96c62d1a60a9022dcb09 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 17 Jan 2017 15:55:18 +0100 -Subject: [PATCH 36/46] p11_child: return multiple certs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch refactors the handling of certificates in p11_child. Not only -the first but all certificates suitable for authentication are returned. -The PAM responder component calling p11_child is refactored to handle -multiple certificate returned by p11_child but so far only returns the -first one to its callers. - -Related to https://pagure.io/SSSD/sssd/issue/3560 - -Reviewed-by: Fabiano Fidêncio -Tested-by: Scott Poore -(cherry picked from commit 39fd336e4390ece3a8465714735ef4203f329e54) ---- - src/p11_child/p11_child_nss.c | 131 +++++++++++++--------- - src/responder/pam/pamsrv.h | 2 + - src/responder/pam/pamsrv_p11.c | 242 +++++++++++++++++++++++------------------ - 3 files changed, 219 insertions(+), 156 deletions(-) - -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index b0ec69be321c4b4186ce851c07bfcc3e1afe9694..50bde2f4f91f6c00260b0db383d0962112686ebc 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -72,8 +72,7 @@ static char *password_passthrough(PK11SlotInfo *slot, PRBool retry, void *arg) - int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - enum op_mode mode, const char *pin, - struct cert_verify_opts *cert_verify_opts, -- char **cert, char **token_name_out, char **module_name_out, -- char **key_id_out) -+ char **_multi) - { - int ret; - SECStatus rv; -@@ -110,7 +109,10 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - PK11SlotListElement *le; - SECItem *key_id = NULL; - char *key_id_str = NULL; -- -+ CERTCertList *valid_certs = NULL; -+ char *cert_b64 = NULL; -+ char *multi = NULL; -+ PRCList *node; - - nss_ctx = NSS_InitContext(nss_db, "", "", SECMOD_DB, ¶meters, flags); - if (nss_ctx == NULL) { -@@ -303,6 +305,14 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - } - - found_cert = NULL; -+ valid_certs = CERT_NewCertList(); -+ if (valid_certs == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "CERT_NewCertList failed [%d].\n", -+ PR_GetError()); -+ ret = ENOMEM; -+ goto done; -+ } -+ - DEBUG(SSSDBG_TRACE_ALL, "Filtered certificates:\n"); - for (cert_list_node = CERT_LIST_HEAD(cert_list); - !CERT_LIST_END(cert_list_node, cert_list); -@@ -326,6 +336,13 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - } - } - -+ rv = CERT_AddCertToListTail(valid_certs, cert_list_node->cert); -+ if (rv != SECSuccess) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "CERT_AddCertToListTail failed [%d].\n", PR_GetError()); -+ ret = EIO; -+ goto done; -+ } - - if (found_cert == NULL) { - found_cert = cert_list_node->cert; -@@ -352,9 +369,7 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - - if (found_cert == NULL) { - DEBUG(SSSDBG_TRACE_ALL, "No certificate found.\n"); -- *cert = NULL; -- *token_name_out = NULL; -- *module_name_out = NULL; -+ *_multi = NULL; - ret = EOK; - goto done; - } -@@ -421,51 +436,55 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - "Certificate verified and validated.\n"); - } - -- key_id = PK11_GetLowLevelKeyIDForCert(slot, found_cert, NULL); -- if (key_id == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "PK11_GetLowLevelKeyIDForCert failed [%d].\n", -- PR_GetError()); -- ret = EINVAL; -- goto done; -- } -- -- key_id_str = CERT_Hexify(key_id, PR_FALSE); -- if (key_id_str == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n", PR_GetError()); -+ multi = talloc_strdup(mem_ctx, ""); -+ if (multi == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create output string.\n"); - ret = ENOMEM; - goto done; - } - -- DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n", key_id_str); -+ for (cert_list_node = CERT_LIST_HEAD(valid_certs); -+ !CERT_LIST_END(cert_list_node, valid_certs); -+ cert_list_node = CERT_LIST_NEXT(cert_list_node)) { - -- *key_id_out = talloc_strdup(mem_ctx, key_id_str); -- if (*key_id_out == NULL) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy key id.\n"); -- ret = ENOMEM; -- goto done; -- } -+ found_cert = cert_list_node->cert; - -- *cert = sss_base64_encode(mem_ctx, found_cert->derCert.data, -- found_cert->derCert.len); -- if (*cert == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "sss_base64_encode failed.\n"); -- ret = ENOMEM; -- goto done; -- } -+ SECITEM_FreeItem(key_id, PR_TRUE); -+ PORT_Free(key_id_str); -+ key_id = PK11_GetLowLevelKeyIDForCert(slot, found_cert, NULL); -+ if (key_id == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "PK11_GetLowLevelKeyIDForCert failed [%d].\n", -+ PR_GetError()); -+ ret = EINVAL; -+ goto done; -+ } - -- *token_name_out = talloc_strdup(mem_ctx, token_name); -- if (*token_name_out == NULL) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy slot name.\n"); -- ret = ENOMEM; -- goto done; -- } -+ key_id_str = CERT_Hexify(key_id, PR_FALSE); -+ if (key_id_str == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n", -+ PR_GetError()); -+ ret = ENOMEM; -+ goto done; -+ } - -- *module_name_out = talloc_strdup(mem_ctx, module_name); -- if (*module_name_out == NULL) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to copy module_name_out name.\n"); -- ret = ENOMEM; -- goto done; -+ talloc_free(cert_b64); -+ cert_b64 = sss_base64_encode(mem_ctx, found_cert->derCert.data, -+ found_cert->derCert.len); -+ if (cert_b64 == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_encode failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n", -+ key_id_str); -+ -+ multi = talloc_asprintf_append(multi, "%s\n%s\n%s\n%s\n", -+ token_name, module_name, key_id_str, -+ cert_b64); - } -+ *_multi = multi; - - ret = EOK; - -@@ -474,6 +493,18 @@ done: - PK11_FreeSlot(slot); - } - -+ if (valid_certs != NULL) { -+ /* The certificates can be found in valid_certs and cert_list and -+ * CERT_DestroyCertList() will free the certificates as well. To avoid -+ * a double free the nodes from valid_certs are removed first because -+ * valid_certs will only have a sub-set of the certificates. */ -+ while (!PR_CLIST_IS_EMPTY(&valid_certs->list)) { -+ node = PR_LIST_HEAD(&valid_certs->list); -+ PR_REMOVE_LINK(node); -+ } -+ CERT_DestroyCertList(valid_certs); -+ } -+ - if (cert_list != NULL) { - CERT_DestroyCertList(cert_list); - } -@@ -483,6 +514,8 @@ done: - - PORT_Free(signed_random_value.data); - -+ talloc_free(cert_b64); -+ - rv = NSS_ShutdownContext(nss_ctx); - if (rv != SECSuccess) { - DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d].\n", -@@ -540,17 +573,14 @@ int main(int argc, const char *argv[]) - const char *opt_logger = NULL; - errno_t ret; - TALLOC_CTX *main_ctx = NULL; -- char *cert; - enum op_mode mode = OP_NONE; - enum pin_mode pin_mode = PIN_NONE; - char *pin = NULL; - char *slot_name_in = NULL; -- char *token_name_out = NULL; -- char *module_name_out = NULL; -- char *key_id_out = NULL; - char *nss_db = NULL; - struct cert_verify_opts *cert_verify_opts; - char *verify_opts = NULL; -+ char *multi = NULL; - - struct poptOption long_options[] = { - POPT_AUTOHELP -@@ -715,17 +745,14 @@ int main(int argc, const char *argv[]) - } - - ret = do_work(main_ctx, nss_db, slot_name_in, mode, pin, cert_verify_opts, -- &cert, &token_name_out, &module_name_out, &key_id_out); -+ &multi); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "do_work failed.\n"); - goto fail; - } - -- if (cert != NULL) { -- fprintf(stdout, "%s\n", token_name_out); -- fprintf(stdout, "%s\n", module_name_out); -- fprintf(stdout, "%s\n", key_id_out); -- fprintf(stdout, "%s\n", cert); -+ if (multi != NULL) { -+ fprintf(stdout, "%s", multi); - } - - talloc_free(main_ctx); -diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h -index 57a37b72594f030995f5e22255eb7a8fcd63d10e..896f71befbc9947a53b5eb20cba0bb3d104c4cf2 100644 ---- a/src/responder/pam/pamsrv.h -+++ b/src/responder/pam/pamsrv.h -@@ -88,6 +88,8 @@ int LOCAL_pam_handler(struct pam_auth_req *preq); - - errno_t p11_child_init(struct pam_ctx *pctx); - -+struct cert_auth_info; -+ - struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - int child_debug_fd, -diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c -index 4dce43800c3c6b026c545df35c846269cbb49610..ff32d1e726808caa36ca7cca557220866ef1a9ab 100644 ---- a/src/responder/pam/pamsrv_p11.c -+++ b/src/responder/pam/pamsrv_p11.c -@@ -35,6 +35,15 @@ - #define P11_CHILD_LOG_FILE "p11_child" - #define P11_CHILD_PATH SSSD_LIBEXEC_PATH"/p11_child" - -+struct cert_auth_info { -+ char *cert; -+ char *token_name; -+ char *module_name; -+ char *key_id; -+ struct cert_auth_info *prev; -+ struct cert_auth_info *next; -+}; -+ - errno_t p11_child_init(struct pam_ctx *pctx) - { - return child_debug_init(P11_CHILD_LOG_FILE, &pctx->p11_child_debug_fd); -@@ -132,18 +141,15 @@ static errno_t get_p11_child_write_buffer(TALLOC_CTX *mem_ctx, - } - - static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, -- ssize_t buf_len, char **_cert, -- char **_token_name, char **_module_name, -- char **_key_id) -+ ssize_t buf_len, -+ struct cert_auth_info **_cert_list) - { - int ret; - TALLOC_CTX *tmp_ctx = NULL; - uint8_t *p; - uint8_t *pn; -- char *cert = NULL; -- char *token_name = NULL; -- char *module_name = NULL; -- char *key_id = NULL; -+ struct cert_auth_info *cert_list = NULL; -+ struct cert_auth_info *cert_auth_info; - - if (buf_len < 0) { - DEBUG(SSSDBG_CRIT_FAILURE, -@@ -157,108 +163,132 @@ static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, - goto done; - } - -- p = memchr(buf, '\n', buf_len); -- if (p == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "Missing new-line in p11_child response.\n"); -- return EINVAL; -- } -- if (p == buf) { -- DEBUG(SSSDBG_OP_FAILURE, "Missing counter in p11_child response.\n"); -- return EINVAL; -- } -- - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); - return ENOMEM; - } - -- token_name = talloc_strndup(tmp_ctx, (char*) buf, (p - buf)); -- if (token_name == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); -- ret = ENOMEM; -- goto done; -- } -+ p = buf; - -- p++; -- pn = memchr(p, '\n', buf_len - (p - buf)); -- if (pn == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Missing new-line in p11_child response.\n"); -- ret = EINVAL; -- goto done; -- } -+ do { -+ cert_auth_info = talloc_zero(tmp_ctx, struct cert_auth_info); -+ if (cert_auth_info == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n"); -+ return ENOMEM; -+ } - -- if (pn == p) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Missing module name in p11_child response.\n"); -- ret = EINVAL; -- goto done; -- } -+ pn = memchr(p, '\n', buf_len - (p - buf)); -+ if (pn == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Missing new-line in p11_child response.\n"); -+ return EINVAL; -+ } -+ if (pn == p) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Missing counter in p11_child response.\n"); -+ return EINVAL; -+ } - -- module_name = talloc_strndup(tmp_ctx, (char *) p, (pn - p)); -- if (module_name == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); -- ret = ENOMEM; -- goto done; -- } -- DEBUG(SSSDBG_TRACE_ALL, "Found module name [%s].\n", module_name); -+ cert_auth_info->token_name = talloc_strndup(cert_auth_info, (char *)p, -+ (pn - p)); -+ if (cert_auth_info->token_name == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ DEBUG(SSSDBG_TRACE_ALL, "Found token name [%s].\n", -+ cert_auth_info->token_name); - -- p = ++pn; -- pn = memchr(p, '\n', buf_len - (p - buf)); -- if (pn == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Missing new-line in p11_child response.\n"); -- ret = EINVAL; -- goto done; -- } -+ p = ++pn; -+ pn = memchr(p, '\n', buf_len - (p - buf)); -+ if (pn == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Missing new-line in p11_child response.\n"); -+ ret = EINVAL; -+ goto done; -+ } - -- if (pn == p) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Missing key id in p11_child response.\n"); -- ret = EINVAL; -- goto done; -- } -+ if (pn == p) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Missing module name in p11_child response.\n"); -+ ret = EINVAL; -+ goto done; -+ } - -- key_id = talloc_strndup(tmp_ctx, (char *) p, (pn - p)); -- if (key_id == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); -- ret = ENOMEM; -- goto done; -- } -- DEBUG(SSSDBG_TRACE_ALL, "Found key id [%s].\n", key_id); -+ cert_auth_info->module_name = talloc_strndup(cert_auth_info, (char *)p, -+ (pn - p)); -+ if (cert_auth_info->module_name == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ DEBUG(SSSDBG_TRACE_ALL, "Found module name [%s].\n", -+ cert_auth_info->module_name); - -- p = pn + 1; -- pn = memchr(p, '\n', buf_len - (p - buf)); -- if (pn == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Missing new-line in p11_child response.\n"); -- ret = EINVAL; -- goto done; -- } -+ p = ++pn; -+ pn = memchr(p, '\n', buf_len - (p - buf)); -+ if (pn == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Missing new-line in p11_child response.\n"); -+ ret = EINVAL; -+ goto done; -+ } - -- if (pn == p) { -- DEBUG(SSSDBG_OP_FAILURE, "Missing cert in p11_child response.\n"); -- ret = EINVAL; -- goto done; -- } -+ if (pn == p) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Missing key id in p11_child response.\n"); -+ ret = EINVAL; -+ goto done; -+ } - -- cert = talloc_strndup(tmp_ctx, (char *) p, (pn - p)); -- if(cert == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); -- ret = ENOMEM; -- goto done; -- } -- DEBUG(SSSDBG_TRACE_ALL, "Found cert [%s].\n", cert); -+ cert_auth_info->key_id = talloc_strndup(cert_auth_info, (char *)p, -+ (pn - p)); -+ if (cert_auth_info->key_id == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ DEBUG(SSSDBG_TRACE_ALL, "Found key id [%s].\n", cert_auth_info->key_id); -+ -+ p = ++pn; -+ pn = memchr(p, '\n', buf_len - (p - buf)); -+ if (pn == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Missing new-line in p11_child response.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ if (pn == p) { -+ DEBUG(SSSDBG_OP_FAILURE, "Missing cert in p11_child response.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ cert_auth_info->cert = talloc_strndup(cert_auth_info, (char *)p, -+ (pn - p)); -+ if (cert_auth_info->cert == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ DEBUG(SSSDBG_TRACE_ALL, "Found cert [%s].\n", cert_auth_info->cert); -+ -+ DLIST_ADD(cert_list, cert_auth_info); -+ -+ p = ++pn; -+ } while ((pn - buf) < buf_len); - - ret = EOK; - - done: - if (ret == EOK) { -- *_token_name = talloc_steal(mem_ctx, token_name); -- *_cert = talloc_steal(mem_ctx, cert); -- *_module_name = talloc_steal(mem_ctx, module_name); -- *_key_id = talloc_steal(mem_ctx, key_id); -+ DLIST_FOR_EACH(cert_auth_info, cert_list) { -+ talloc_steal(mem_ctx, cert_auth_info); -+ } -+ -+ *_cert_list = cert_list; - } - - talloc_free(tmp_ctx); -@@ -273,10 +303,8 @@ struct pam_check_cert_state { - struct tevent_context *ev; - - struct child_io_fds *io; -- char *cert; -- char *token_name; -- char *module_name; -- char *key_id; -+ -+ struct cert_auth_info *cert_list; - }; - - static void p11_child_write_done(struct tevent_req *subreq); -@@ -349,9 +377,6 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - - state->ev = ev; - state->child_status = EFAULT; -- state->cert = NULL; -- state->token_name = NULL; -- state->module_name = NULL; - state->io = talloc(state, struct child_io_fds); - if (state->io == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n"); -@@ -514,11 +539,9 @@ static void p11_child_done(struct tevent_req *subreq) - - PIPE_FD_CLOSE(state->io->read_from_child_fd); - -- ret = parse_p11_child_response(state, buf, buf_len, &state->cert, -- &state->token_name, &state->module_name, -- &state->key_id); -+ ret = parse_p11_child_response(state, buf, buf_len, &state->cert_list); - if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "parse_p11_child_respose failed.\n"); -+ DEBUG(SSSDBG_OP_FAILURE, "parse_p11_child_response failed.\n"); - tevent_req_error(req, ret); - return; - } -@@ -551,20 +574,31 @@ errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - - TEVENT_REQ_RETURN_ON_ERROR(req); - -+ if (state->cert_list == NULL) { -+ *token_name = NULL; -+ *cert = NULL; -+ *module_name = NULL; -+ *key_id = NULL; -+ } -+ - if (cert != NULL) { -- *cert = talloc_steal(mem_ctx, state->cert); -+ *cert = (state->cert_list == NULL) ? NULL -+ : talloc_steal(mem_ctx, state->cert_list->cert); - } - - if (token_name != NULL) { -- *token_name = talloc_steal(mem_ctx, state->token_name); -+ *token_name = (state->cert_list == NULL) ? NULL -+ : talloc_steal(mem_ctx, state->cert_list->token_name); - } - - if (module_name != NULL) { -- *module_name = talloc_steal(mem_ctx, state->module_name); -+ *module_name = (state->cert_list == NULL) ? NULL -+ : talloc_steal(mem_ctx, state->cert_list->module_name); - } - - if (key_id != NULL) { -- *key_id = talloc_steal(mem_ctx, state->key_id); -+ *key_id = (state->cert_list == NULL) ? NULL -+ : talloc_steal(mem_ctx, state->cert_list->key_id); - } - - return EOK; --- -2.13.6 - diff --git a/SOURCES/0037-PAM-handled-multiple-certs-in-the-responder.patch b/SOURCES/0037-PAM-handled-multiple-certs-in-the-responder.patch deleted file mode 100644 index dfac98b..0000000 --- a/SOURCES/0037-PAM-handled-multiple-certs-in-the-responder.patch +++ /dev/null @@ -1,1074 +0,0 @@ -From f4cac6544b5b6fb094d2088bf75f443fb74028bc Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 25 Aug 2017 12:51:09 +0200 -Subject: [PATCH 37/47] PAM: handled multiple certs in the responder -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch refactors the handling of the certificate and the attributes -to address the certificate on the Smartcard (module name, token name and -key id). Instead of using individual variables the values are put into a -new struct cert_auth_info. Since the new struct can be used as a list -the PAM responder can now handle multiple certificates on the Smartcard -and can send the needed data to pam_sss with multiple SSS_PAM_CERT_INFO -messages. - -Unit tests are added to confirm the expected behavior. - -Related to https://pagure.io/SSSD/sssd/issue/3560 - -Reviewed-by: Fabiano Fidêncio -Tested-by: Scott Poore -(cherry picked from commit 0bdd8800c16f39b8fe308d20694ad905c669dff3) - -The following binaries have been removed from the original patch: -- src/tests/cmocka/p11_nssdb_2certs/cert9.db -- src/tests/cmocka/p11_nssdb_2certs/key4.db - -The reason for that is that we can't apply a patch which is a binary -file using rpm, thus removing the patches here and adding them as source -files in the sssd.spec seems to be the best solution. ---- - Makefile.am | 2 + - src/responder/pam/pamsrv.h | 25 ++- - src/responder/pam/pamsrv_cmd.c | 257 ++++++++++++++++++--------- - src/responder/pam/pamsrv_p11.c | 181 ++++++++++++++----- - src/tests/cmocka/p11_nssdb_2certs/pkcs11.txt | 4 + - src/tests/cmocka/test_pam_srv.c | 216 +++++++++++++++++++++- - src/tests/whitespace_test | 2 +- - 7 files changed, 538 insertions(+), 149 deletions(-) - create mode 100644 src/tests/cmocka/p11_nssdb_2certs/pkcs11.txt - -diff --git a/Makefile.am b/Makefile.am -index bbc90d9bad4d22ca0284ea95281a487d42399c05..4ed872a532daf9b934537cc5f64ce77778121e2a 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -481,6 +481,8 @@ dist_noinst_DATA = \ - contrib/ci/sssd.supp \ - src/tests/cmocka/p11_nssdb/cert9.db \ - src/tests/cmocka/p11_nssdb/key4.db \ -+ src/tests/cmocka/p11_nssdb_2certs/cert9.db \ -+ src/tests/cmocka/p11_nssdb_2certs/key4.db \ - $(SYSTEMTAP_PROBES) \ - $(NULL) - -diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h -index 896f71befbc9947a53b5eb20cba0bb3d104c4cf2..f15f7f19f1f38626288416c9f2038371c6f58b47 100644 ---- a/src/responder/pam/pamsrv.h -+++ b/src/responder/pam/pamsrv.h -@@ -73,10 +73,8 @@ struct pam_auth_req { - struct pam_auth_dp_req *dpreq_spy; - - struct ldb_message *user_obj; -- struct ldb_result *cert_user_objs; -- char *token_name; -- char *module_name; -- char *key_id; -+ struct cert_auth_info *cert_list; -+ struct cert_auth_info *current_cert; - bool cert_auth_local; - }; - -@@ -89,6 +87,16 @@ int LOCAL_pam_handler(struct pam_auth_req *preq); - errno_t p11_child_init(struct pam_ctx *pctx); - - struct cert_auth_info; -+const char *sss_cai_get_cert(struct cert_auth_info *i); -+const char *sss_cai_get_token_name(struct cert_auth_info *i); -+const char *sss_cai_get_module_name(struct cert_auth_info *i); -+const char *sss_cai_get_key_id(struct cert_auth_info *i); -+struct cert_auth_info *sss_cai_get_next(struct cert_auth_info *i); -+struct ldb_result *sss_cai_get_cert_user_objs(struct cert_auth_info *i); -+void sss_cai_set_cert_user_objs(struct cert_auth_info *i, -+ struct ldb_result *cert_user_objs); -+void sss_cai_check_users(struct cert_auth_info **list, size_t *_cert_count, -+ size_t *_cert_user_count); - - struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, -@@ -98,12 +106,11 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - const char *verify_opts, - struct pam_data *pd); - errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, -- char **cert, char **token_name, char **module_name, -- char **key_id); -+ struct cert_auth_info **cert_list); - --errno_t add_pam_cert_response(struct pam_data *pd, const char *user, -- const char *token_name, const char *module_name, -- const char *key_id, enum response_type type); -+errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username, -+ struct cert_auth_info *cert_info, -+ enum response_type type); - - bool may_do_cert_auth(struct pam_ctx *pctx, struct pam_data *pd); - -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index 51d8185650cf823da289a3398b10133065d82ae4..8b2c086e206796ad4c977495be957c56b3255e7f 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -1389,21 +1389,17 @@ done: - return pam_check_user_done(preq, ret); - } - -+static errno_t pam_user_by_cert_step(struct pam_auth_req *preq); - static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req); - static void pam_forwarder_cert_cb(struct tevent_req *req) - { - struct pam_auth_req *preq = tevent_req_callback_data(req, - struct pam_auth_req); -- struct cli_ctx *cctx = preq->cctx; - struct pam_data *pd; - errno_t ret = EOK; -- char *cert; -- struct pam_ctx *pctx = -- talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); -+ const char *cert; - -- ret = pam_check_cert_recv(req, preq, &cert, &preq->token_name, -- &preq->module_name, -- &preq->key_id); -+ ret = pam_check_cert_recv(req, preq, &preq->cert_list); - talloc_free(req); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "get_cert request failed.\n"); -@@ -1412,6 +1408,8 @@ static void pam_forwarder_cert_cb(struct tevent_req *req) - - pd = preq->pd; - -+ cert = sss_cai_get_cert(preq->cert_list); -+ - if (cert == NULL) { - if (pd->logon_name == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, -@@ -1431,21 +1429,42 @@ static void pam_forwarder_cert_cb(struct tevent_req *req) - goto done; - } - -+ preq->current_cert = preq->cert_list; -+ ret = pam_user_by_cert_step(preq); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "pam_user_by_cert_step failed.\n"); -+ goto done; -+ } -+ -+ return; -+ -+done: -+ pam_check_user_done(preq, ret); -+} -+ -+static errno_t pam_user_by_cert_step(struct pam_auth_req *preq) -+{ -+ struct cli_ctx *cctx = preq->cctx; -+ struct tevent_req *req; -+ struct pam_ctx *pctx = -+ talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); -+ -+ if (preq->current_cert == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing certificate data.\n"); -+ return EINVAL; -+ } - - req = cache_req_user_by_cert_send(preq, cctx->ev, cctx->rctx, - pctx->rctx->ncache, 0, - preq->req_dom_type, NULL, -- cert); -+ sss_cai_get_cert(preq->current_cert)); - if (req == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "cache_req_user_by_cert_send failed.\n"); -- ret = ENOMEM; -- goto done; -+ return ENOMEM; - } -+ - tevent_req_set_callback(req, pam_forwarder_lookup_by_cert_done, preq); -- return; -- --done: -- pam_check_user_done(preq, ret); -+ return EOK; - } - - static errno_t get_results_from_all_domains(TALLOC_CTX *mem_ctx, -@@ -1511,6 +1530,9 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - struct pam_auth_req *preq = tevent_req_callback_data(req, - struct pam_auth_req); - const char *cert_user = NULL; -+ size_t cert_count = 0; -+ size_t cert_user_count = 0; -+ struct ldb_result *cert_user_objs; - - ret = cache_req_recv(preq, req, &results); - talloc_zfree(req); -@@ -1521,12 +1543,39 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - - if (ret == EOK) { - ret = get_results_from_all_domains(preq, results, -- &preq->cert_user_objs); -+ &cert_user_objs); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "get_results_from_all_domains failed.\n"); - goto done; - } - -+ sss_cai_set_cert_user_objs(preq->current_cert, cert_user_objs); -+ } -+ -+ preq->current_cert = sss_cai_get_next(preq->current_cert); -+ if (preq->current_cert != NULL) { -+ ret = pam_user_by_cert_step(preq); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "pam_user_by_cert_step failed.\n"); -+ goto done; -+ } -+ return; -+ } -+ -+ sss_cai_check_users(&preq->cert_list, &cert_count, &cert_user_count); -+ DEBUG(SSSDBG_TRACE_ALL, -+ "Found [%zu] certificates and [%zu] related users.\n", -+ cert_count, cert_user_count); -+ -+ if (cert_user_count == 0) { -+ if (preq->pd->logon_name == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Missing logon name and no certificate user found.\n"); -+ ret = ENOENT; -+ goto done; -+ } -+ } else { -+ - if (preq->pd->logon_name == NULL) { - if (preq->pd->cmd != SSS_PAM_PREAUTH) { - DEBUG(SSSDBG_CRIT_FAILURE, -@@ -1535,9 +1584,39 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - goto done; - } - -- if (preq->cert_user_objs->count == 1) { -+ if (cert_count > 1) { -+ for (preq->current_cert = preq->cert_list; -+ preq->current_cert != NULL; -+ preq->current_cert = sss_cai_get_next(preq->current_cert)) { -+ -+ ret = add_pam_cert_response(preq->pd, "", -+ preq->current_cert, -+ preq->cctx->rctx->domains->user_name_hint -+ ? SSS_PAM_CERT_INFO_WITH_HINT -+ : SSS_PAM_CERT_INFO); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "add_pam_cert_response failed.\n"); -+ preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL; -+ } -+ } -+ -+ ret = EOK; -+ preq->pd->pam_status = PAM_SUCCESS; -+ pam_reply(preq); -+ goto done; -+ } -+ -+ if (cert_user_count == 1) { -+ cert_user_objs = sss_cai_get_cert_user_objs(preq->cert_list); -+ if (cert_user_objs == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing certificate user.\n"); -+ ret = ENOENT; -+ goto done; -+ } -+ - cert_user = ldb_msg_find_attr_as_string( -- preq->cert_user_objs->msgs[0], -+ cert_user_objs->msgs[0], - SYSDB_NAME, NULL); - if (cert_user == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, -@@ -1564,9 +1643,7 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - - if (preq->cctx->rctx->domains->user_name_hint) { - ret = add_pam_cert_response(preq->pd, cert_user, -- preq->token_name, -- preq->module_name, -- preq->key_id, -+ preq->cert_list, - SSS_PAM_CERT_INFO_WITH_HINT); - preq->pd->pam_status = PAM_SUCCESS; - if (ret != EOK) { -@@ -1596,13 +1673,6 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - goto done; - } - } -- } else { -- if (preq->pd->logon_name == NULL) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "Missing logon name and no certificate user found.\n"); -- ret = ENOENT; -- goto done; -- } - } - - if (preq->user_obj == NULL) { -@@ -1884,7 +1954,9 @@ static void pam_dom_forwarder(struct pam_auth_req *preq) - struct pam_ctx *pctx = - talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx); - const char *cert_user; -+ struct ldb_result *cert_user_objs; - size_t c; -+ bool found = false; - - if (!preq->pd->domain) { - preq->pd->domain = preq->domain->name; -@@ -1921,76 +1993,87 @@ static void pam_dom_forwarder(struct pam_auth_req *preq) - return; - } - -- if (may_do_cert_auth(pctx, preq->pd) && preq->cert_user_objs != NULL) { -+ if (may_do_cert_auth(pctx, preq->pd) && preq->cert_list != NULL) { - /* Check if user matches certificate user */ -- for (c = 0; c < preq->cert_user_objs->count; c++) { -- cert_user = ldb_msg_find_attr_as_string( -- preq->cert_user_objs->msgs[c], -- SYSDB_NAME, -- NULL); -- if (cert_user == NULL) { -- /* Even if there might be other users mapped to the -- * certificate a missing SYSDB_NAME indicates some critical -- * condition which justifies that the whole request is aborted -- * */ -- DEBUG(SSSDBG_CRIT_FAILURE, -- "Certificate user object has no name.\n"); -- preq->pd->pam_status = PAM_USER_UNKNOWN; -- pam_reply(preq); -- return; -+ found = false; -+ for (preq->current_cert = preq->cert_list; -+ preq->current_cert != NULL; -+ preq->current_cert = sss_cai_get_next(preq->current_cert)) { -+ -+ cert_user_objs = sss_cai_get_cert_user_objs(preq->current_cert); -+ if (cert_user_objs == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Unexpteced missing certificate user, " -+ "trying next certificate.\n"); -+ continue; - } - -- /* pam_check_user_search() calls pd_set_primary_name() is the search -- * was successful, so pd->user contains the canonical sysdb name -- * as well */ -- if (ldb_dn_compare(preq->cert_user_objs->msgs[c]->dn, -- preq->user_obj->dn) == 0) { -- -- if (preq->pd->cmd == SSS_PAM_PREAUTH) { -- ret = sss_authtok_set_sc(preq->pd->authtok, -- SSS_AUTHTOK_TYPE_SC_PIN, NULL, 0, -- preq->token_name, 0, -- preq->module_name, 0, -- preq->key_id, 0); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_set_sc failed, " -- "Smartcard authentication " -- "detection might fail in the " -- "backend.\n"); -- } -- -- ret = add_pam_cert_response(preq->pd, cert_user, -- preq->token_name, -- preq->module_name, -- preq->key_id, -- SSS_PAM_CERT_INFO); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "add_pam_cert_response failed.\n"); -- preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL; -- } -- } -- -- /* We are done if we do not have to call the backend */ -- if (preq->pd->cmd == SSS_PAM_AUTHENTICATE -- && preq->cert_auth_local) { -- preq->pd->pam_status = PAM_SUCCESS; -- preq->callback = pam_reply; -+ for (c = 0; c < cert_user_objs->count; c++) { -+ cert_user = ldb_msg_find_attr_as_string(cert_user_objs->msgs[c], -+ SYSDB_NAME, NULL); -+ if (cert_user == NULL) { -+ /* Even if there might be other users mapped to the -+ * certificate a missing SYSDB_NAME indicates some critical -+ * condition which justifies that the whole request is aborted -+ * */ -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Certificate user object has no name.\n"); -+ preq->pd->pam_status = PAM_USER_UNKNOWN; - pam_reply(preq); - return; - } -+ -+ if (ldb_dn_compare(cert_user_objs->msgs[c]->dn, -+ preq->user_obj->dn) == 0) { -+ found = true; -+ if (preq->pd->cmd == SSS_PAM_PREAUTH) { -+ ret = sss_authtok_set_sc(preq->pd->authtok, -+ SSS_AUTHTOK_TYPE_SC_PIN, NULL, 0, -+ sss_cai_get_token_name(preq->current_cert), 0, -+ sss_cai_get_module_name(preq->current_cert), 0, -+ sss_cai_get_key_id(preq->current_cert), 0); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sss_authtok_set_sc failed, Smartcard " -+ "authentication detection might fail in " -+ "the backend.\n"); -+ } -+ -+ /* FIXME: use the right cert info */ -+ ret = add_pam_cert_response(preq->pd, cert_user, -+ preq->current_cert, -+ SSS_PAM_CERT_INFO); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "add_pam_cert_response failed.\n"); -+ preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL; -+ } -+ } -+ -+ } - } - } - -- if (preq->pd->cmd == SSS_PAM_PREAUTH) { -- DEBUG(SSSDBG_TRACE_FUNC, -- "User and certificate user do not match, " -- "continue with other authentication methods.\n"); -+ if (found) { -+ /* We are done if we do not have to call the backend */ -+ if (preq->pd->cmd == SSS_PAM_AUTHENTICATE -+ && preq->cert_auth_local) { -+ preq->pd->pam_status = PAM_SUCCESS; -+ preq->callback = pam_reply; -+ pam_reply(preq); -+ return; -+ } - } else { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "User and certificate user do not match.\n"); -- preq->pd->pam_status = PAM_AUTH_ERR; -- pam_reply(preq); -- return; -+ if (preq->pd->cmd == SSS_PAM_PREAUTH) { -+ DEBUG(SSSDBG_TRACE_FUNC, -+ "User and certificate user do not match, " -+ "continue with other authentication methods.\n"); -+ } else { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "User and certificate user do not match.\n"); -+ preq->pd->pam_status = PAM_AUTH_ERR; -+ pam_reply(preq); -+ return; -+ } - } - } - -diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c -index ff32d1e726808caa36ca7cca557220866ef1a9ab..57c8e1e464f4262f2d78f869c52ca48bd469d90a 100644 ---- a/src/responder/pam/pamsrv_p11.c -+++ b/src/responder/pam/pamsrv_p11.c -@@ -40,10 +40,80 @@ struct cert_auth_info { - char *token_name; - char *module_name; - char *key_id; -+ struct ldb_result *cert_user_objs; - struct cert_auth_info *prev; - struct cert_auth_info *next; - }; - -+const char *sss_cai_get_cert(struct cert_auth_info *i) -+{ -+ return i != NULL ? i->cert : NULL; -+} -+ -+const char *sss_cai_get_token_name(struct cert_auth_info *i) -+{ -+ return i != NULL ? i->token_name : NULL; -+} -+ -+const char *sss_cai_get_module_name(struct cert_auth_info *i) -+{ -+ return i != NULL ? i->module_name : NULL; -+} -+ -+const char *sss_cai_get_key_id(struct cert_auth_info *i) -+{ -+ return i != NULL ? i->key_id : NULL; -+} -+ -+struct cert_auth_info *sss_cai_get_next(struct cert_auth_info *i) -+{ -+ return i != NULL ? i->next : NULL; -+} -+ -+struct ldb_result *sss_cai_get_cert_user_objs(struct cert_auth_info *i) -+{ -+ return i != NULL ? i->cert_user_objs : NULL; -+} -+ -+void sss_cai_set_cert_user_objs(struct cert_auth_info *i, -+ struct ldb_result *cert_user_objs) -+{ -+ if (i->cert_user_objs != NULL) { -+ talloc_free(i->cert_user_objs); -+ } -+ i->cert_user_objs = talloc_steal(i, cert_user_objs); -+} -+ -+void sss_cai_check_users(struct cert_auth_info **list, size_t *_cert_count, -+ size_t *_cert_user_count) -+{ -+ struct cert_auth_info *c; -+ struct cert_auth_info *tmp; -+ size_t cert_count = 0; -+ size_t cert_user_count = 0; -+ struct ldb_result *user_objs; -+ -+ DLIST_FOR_EACH_SAFE(c, tmp, *list) { -+ user_objs = sss_cai_get_cert_user_objs(c); -+ if (user_objs != NULL) { -+ cert_count++; -+ cert_user_count += user_objs->count; -+ } else { -+ DLIST_REMOVE(*list, c); -+ } -+ } -+ -+ if (_cert_count != NULL) { -+ *_cert_count = cert_count; -+ } -+ -+ if (_cert_user_count != NULL) { -+ *_cert_user_count = cert_user_count; -+ } -+ -+ return; -+} -+ - errno_t p11_child_init(struct pam_ctx *pctx) - { - return child_debug_init(P11_CHILD_LOG_FILE, &pctx->p11_child_debug_fd); -@@ -566,39 +636,71 @@ static void p11_child_timeout(struct tevent_context *ev, - } - - errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, -- char **cert, char **token_name, char **module_name, -- char **key_id) -+ struct cert_auth_info **cert_list) - { -+ struct cert_auth_info *tmp_cert_auth_info; - struct pam_check_cert_state *state = - tevent_req_data(req, struct pam_check_cert_state); - - TEVENT_REQ_RETURN_ON_ERROR(req); - -- if (state->cert_list == NULL) { -- *token_name = NULL; -- *cert = NULL; -- *module_name = NULL; -- *key_id = NULL; -+ if (cert_list != NULL) { -+ DLIST_FOR_EACH(tmp_cert_auth_info, state->cert_list) { -+ talloc_steal(mem_ctx, tmp_cert_auth_info); -+ } -+ -+ *cert_list = state->cert_list; - } - -- if (cert != NULL) { -- *cert = (state->cert_list == NULL) ? NULL -- : talloc_steal(mem_ctx, state->cert_list->cert); -+ return EOK; -+} -+ -+static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username, -+ struct cert_auth_info *cert_info, -+ uint8_t **_msg, size_t *_msg_len) -+{ -+ uint8_t *msg = NULL; -+ size_t msg_len; -+ const char *token_name; -+ const char *module_name; -+ const char *key_id; -+ size_t user_len; -+ size_t token_len; -+ size_t module_len; -+ size_t key_id_len; -+ const char *username = ""; -+ -+ if (sysdb_username != NULL) { -+ username = sysdb_username; - } - -- if (token_name != NULL) { -- *token_name = (state->cert_list == NULL) ? NULL -- : talloc_steal(mem_ctx, state->cert_list->token_name); -+ token_name = sss_cai_get_token_name(cert_info); -+ module_name = sss_cai_get_module_name(cert_info); -+ key_id = sss_cai_get_key_id(cert_info); -+ -+ user_len = strlen(username) + 1; -+ token_len = strlen(token_name) + 1; -+ module_len = strlen(module_name) + 1; -+ key_id_len = strlen(key_id) + 1; -+ msg_len = user_len + token_len + module_len + key_id_len; -+ -+ msg = talloc_zero_size(mem_ctx, msg_len); -+ if (msg == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n"); -+ return ENOMEM; - } - -- if (module_name != NULL) { -- *module_name = (state->cert_list == NULL) ? NULL -- : talloc_steal(mem_ctx, state->cert_list->module_name); -+ memcpy(msg, username, user_len); -+ memcpy(msg + user_len, token_name, token_len); -+ memcpy(msg + user_len + token_len, module_name, module_len); -+ memcpy(msg + user_len + token_len + module_len, key_id, key_id_len); -+ -+ if (_msg != NULL) { -+ *_msg = msg; - } - -- if (key_id != NULL) { -- *key_id = (state->cert_list == NULL) ? NULL -- : talloc_steal(mem_ctx, state->cert_list->key_id); -+ if (_msg_len != NULL) { -+ *_msg_len = msg_len; - } - - return EOK; -@@ -613,18 +715,13 @@ errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - #define PKCS11_LOGIN_TOKEN_ENV_NAME "PKCS11_LOGIN_TOKEN_NAME" - - errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username, -- const char *token_name, const char *module_name, -- const char *key_id, enum response_type type) -+ struct cert_auth_info *cert_info, -+ enum response_type type) - { - uint8_t *msg = NULL; - char *env = NULL; -- size_t user_len; - size_t msg_len; -- size_t slot_len; -- size_t module_len; -- size_t key_id_len; - int ret; -- const char *username = ""; - - if (type != SSS_PAM_CERT_INFO && type != SSS_PAM_CERT_INFO_WITH_HINT) { - DEBUG(SSSDBG_CRIT_FAILURE, "Invalid response type [%d].\n", type); -@@ -632,26 +729,14 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username, - } - - if ((type == SSS_PAM_CERT_INFO && sysdb_username == NULL) -- || token_name == NULL || module_name == NULL || key_id == NULL) { -+ || cert_info == NULL -+ || sss_cai_get_token_name(cert_info) == NULL -+ || sss_cai_get_module_name(cert_info) == NULL -+ || sss_cai_get_key_id(cert_info) == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Missing mandatory user or slot name.\n"); - return EINVAL; - } - -- if (sysdb_username != NULL) { -- username = sysdb_username; -- } -- user_len = strlen(username) + 1; -- slot_len = strlen(token_name) + 1; -- module_len = strlen(module_name) + 1; -- key_id_len = strlen(key_id) + 1; -- msg_len = user_len + slot_len + module_len + key_id_len; -- -- msg = talloc_zero_size(pd, msg_len); -- if (msg == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n"); -- return ENOMEM; -- } -- - /* sysdb_username is a fully-qualified name which is used by pam_sss when - * prompting the user for the PIN and as login name if it wasn't set by - * the PAM caller but has to be determined based on the inserted -@@ -659,10 +744,12 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username, - * re_expression config option was set in a way that user@domain cannot be - * handled anymore some more logic has to be added here. But for the time - * being I think using sysdb_username is fine. */ -- memcpy(msg, username, user_len); -- memcpy(msg + user_len, token_name, slot_len); -- memcpy(msg + user_len + slot_len, module_name, module_len); -- memcpy(msg + user_len + slot_len + module_len, key_id, key_id_len); -+ -+ ret = pack_cert_data(pd, sysdb_username, cert_info, &msg, &msg_len); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "pack_cert_data failed.\n"); -+ return ret; -+ } - - ret = pam_add_response(pd, type, msg_len, msg); - talloc_free(msg); -@@ -674,7 +761,7 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username, - - if (strcmp(pd->service, "gdm-smartcard") == 0) { - env = talloc_asprintf(pd, "%s=%s", PKCS11_LOGIN_TOKEN_ENV_NAME, -- token_name); -+ sss_cai_get_token_name(cert_info)); - if (env == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); - return ENOMEM; -diff --git a/src/tests/cmocka/p11_nssdb_2certs/pkcs11.txt b/src/tests/cmocka/p11_nssdb_2certs/pkcs11.txt -new file mode 100644 -index 0000000000000000000000000000000000000000..73f5279c338dffe25ad2fad8c9cafae2f3c4cdfe ---- /dev/null -+++ b/src/tests/cmocka/p11_nssdb_2certs/pkcs11.txt -@@ -0,0 +1,4 @@ -+library= -+name=NSS Internal PKCS #11 Module -+parameters=configdir='sql:../src/tests/cmocka/p11_nssdb' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' -+NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30}) -diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c -index 351067eb664431cda159f73590de772920504380..7f0ed706512ffe0866c0e1fb7e6baa16bec942d8 100644 ---- a/src/tests/cmocka/test_pam_srv.c -+++ b/src/tests/cmocka/test_pam_srv.c -@@ -47,6 +47,9 @@ - #define NSS_DB_PATH TESTS_PATH - #define NSS_DB "sql:"NSS_DB_PATH - -+#define NSS_DB_PATH_2CERTS TESTS_PATH "_2certs" -+#define NSS_DB_2CERTS "sql:"NSS_DB_PATH_2CERTS -+ - #define TEST_TOKEN_NAME "SSSD Test Token" - #define TEST_MODULE_NAME "NSS-Internal" - #define TEST_KEY_ID "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7" -@@ -74,6 +77,28 @@ - "8Z+9gqZhCa7FEKJOPNR9RVtJs0qUUutMZrp1zpyx0GTmXQBA7LbgPxy8L68uymEQ" \ - "XyQBwOYRORlnfGyu+Yc9c3E0Wx8Tlznz0lqPR9g=" - -+#define TEST2_KEY_ID "C8D60E009EB195D01A7083EE1D5419251AA87C2C" -+#define TEST_TOKEN_2ND_CERT \ -+"MIIDazCCAlOgAwIBAgIBBzANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \ -+"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA1MjMx" \ -+"NDEzMDFaFw0xODA1MTMxNDEzMDFaMCUxEjAQBgNVBAoMCUlQQS5ERVZFTDEPMA0G" \ -+"A1UEAwwGSVBBIFJBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3abE" \ -+"8LmIc6QN16VVxsMlN/rrCOoZKyyJolSzpP4+K66t+KZUiW/1j1MZogjyYyD39U1F" \ -+"zpa2H+pID74XYrdiqP7sp+uE9/k2XOv/nN3FobXDt+fSINLDriCmxNhUZqpgo2uq" \ -+"Mmka+yx2iJZwkntEoJTcd3aynoa2Sa2ZZbkMBy5p6/pUQKwnD6scOwe6mUDppIBK" \ -+"+ZZRm+u/NDdIRFI5wfKLRR1r/ONaJA9nz1TxSEsgLsjG/1m+Zbb6lGG4pePIFkQ9" \ -+"Iotpi64obBh93oIxzQR29lBG/FMjQVHlPIbx+xuGx11Vtp5pAomgFz0HRrj0leI7" \ -+"bROE+jnC/VGPLQD2aQIDAQABo4GWMIGTMB8GA1UdIwQYMBaAFPci/0Km5D/L5z7Y" \ -+"qwEc7E1/GwgcMEEGCCsGAQUFBwEBBDUwMzAxBggrBgEFBQcwAYYlaHR0cDovL2lw" \ -+"YS1kZXZlbC5pcGEuZGV2ZWw6ODAvY2Evb2NzcDAOBgNVHQ8BAf8EBAMCBPAwHQYD" \ -+"VR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBg" \ -+"4Sppx2C3eXPJ4Pd9XElkQPOaBReXf1vV0uk/GlK+rG+aAqAkA2Lryx5PK/iAuzAU" \ -+"M6JUpELuQYgqugoCgBXMgsMlpAO/0C3CFq4ZH3KgIsRlRngKPrt6RG0UPMRD1CE2" \ -+"tSVkwUWvyK83lDiu2BbWDXyMyz5eZOlp7uHusf5BKvob8jEndHj1YzaNTmVSsDM5" \ -+"kiIwf8qgFhsO1HCq08PtAnbVHhqkcvnmIJN98eNWNfTKodDmFVbN8gB0wK+WB5ii" \ -+"WVOw7+3/zF1QgqnYX3t+kPLRryip/wvTZkzXWwMNj/W6UHgjNF/4gWGoBgCHu+u3" \ -+"EvjMmbVSrEkesibpGQS5" -+ - - static char CACHED_AUTH_TIMEOUT_STR[] = "4"; - static const int CACHED_AUTH_TIMEOUT = 4; -@@ -111,6 +136,13 @@ static errno_t setup_nss_db(void) - return ret; - } - -+ ret = mkdir(NSS_DB_PATH_2CERTS, 0775); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "Failed to create " NSS_DB_PATH_2CERTS ".\n"); -+ return ret; -+ } -+ - child_pid = fork(); - if (child_pid == 0) { /* child */ - ret = execlp("certutil", "certutil", "-N", "--empty-password", "-d", -@@ -127,6 +159,22 @@ static errno_t setup_nss_db(void) - return ret; - } - -+ child_pid = fork(); -+ if (child_pid == 0) { /* child */ -+ ret = execlp("certutil", "certutil", "-N", "--empty-password", "-d", -+ NSS_DB_2CERTS, NULL); -+ if (ret == -1) { -+ DEBUG(SSSDBG_FATAL_FAILURE, "execl() failed.\n"); -+ exit(-1); -+ } -+ } else if (child_pid > 0) { -+ wait(&status); -+ } else { -+ ret = errno; -+ DEBUG(SSSDBG_FATAL_FAILURE, "fork() failed\n"); -+ return ret; -+ } -+ - fp = fopen(NSS_DB_PATH"/pkcs11.txt", "w"); - if (fp == NULL) { - DEBUG(SSSDBG_FATAL_FAILURE, "fopen() failed.\n"); -@@ -148,6 +196,27 @@ static errno_t setup_nss_db(void) - return ret; - } - -+ fp = fopen(NSS_DB_PATH_2CERTS"/pkcs11.txt", "w"); -+ if (fp == NULL) { -+ DEBUG(SSSDBG_FATAL_FAILURE, "fopen() failed.\n"); -+ return ret; -+ } -+ ret = fprintf(fp, "library=libsoftokn3.so\nname=soft\n"); -+ if (ret < 0) { -+ DEBUG(SSSDBG_FATAL_FAILURE, "fprintf() failed.\n"); -+ return ret; -+ } -+ ret = fprintf(fp, "parameters=configdir='sql:%s/src/tests/cmocka/p11_nssdb_2certs' dbSlotDescription='SSSD Test Slot' dbTokenDescription='SSSD Test Token' secmod='secmod.db' flags=readOnly \n\n", ABS_SRC_DIR); -+ if (ret < 0) { -+ DEBUG(SSSDBG_FATAL_FAILURE, "fprintf() failed.\n"); -+ return ret; -+ } -+ ret = fclose(fp); -+ if (ret != 0) { -+ DEBUG(SSSDBG_FATAL_FAILURE, "fclose() failed.\n"); -+ return ret; -+ } -+ - return EOK; - } - -@@ -174,6 +243,26 @@ static void cleanup_nss_db(void) - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "Failed to remove " NSS_DB_PATH "\n"); - } -+ -+ ret = unlink(NSS_DB_PATH_2CERTS"/cert9.db"); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove cert9.db.\n"); -+ } -+ -+ ret = unlink(NSS_DB_PATH_2CERTS"/key4.db"); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove key4.db.\n"); -+ } -+ -+ ret = unlink(NSS_DB_PATH_2CERTS"/pkcs11.txt"); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove pkcs11.db.\n"); -+ } -+ -+ ret = rmdir(NSS_DB_PATH_2CERTS); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Failed to remove " NSS_DB_PATH "\n"); -+ } - } - - struct pam_ctx *mock_pctx(TALLOC_CTX *mem_ctx) -@@ -749,7 +838,8 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body, - } - - static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, -- enum response_type type, const char *name) -+ enum response_type type, const char *name, -+ const char *name2) - { - size_t rp = 0; - uint32_t val; -@@ -763,7 +853,11 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - if (name == NULL || *name == '\0') { - assert_int_equal(val, 1); - } else { -- assert_int_equal(val, 2); -+ if (name2 == NULL || *name2 == '\0') { -+ assert_int_equal(val, 2); -+ } else { -+ assert_int_equal(val, 3); -+ } - - SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); - assert_int_equal(val, SSS_PAM_DOMAIN_NAME); -@@ -801,6 +895,33 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - assert_string_equal(body + rp, TEST_KEY_ID); - rp += sizeof(TEST_KEY_ID); - -+ if (name2 != NULL && *name2 != '\0') { -+ SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); -+ assert_int_equal(val, type); -+ -+ SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); -+ assert_int_equal(val, (strlen(name) + 1 -+ + sizeof(TEST_TOKEN_NAME) -+ + sizeof(TEST_MODULE_NAME) -+ + sizeof(TEST2_KEY_ID))); -+ -+ assert_int_equal(*(body + rp + strlen(name)), 0); -+ assert_string_equal(body + rp, name); -+ rp += strlen(name) + 1; -+ -+ assert_int_equal(*(body + rp + sizeof(TEST_TOKEN_NAME) - 1), 0); -+ assert_string_equal(body + rp, TEST_TOKEN_NAME); -+ rp += sizeof(TEST_TOKEN_NAME); -+ -+ assert_int_equal(*(body + rp + sizeof(TEST_MODULE_NAME) - 1), 0); -+ assert_string_equal(body + rp, TEST_MODULE_NAME); -+ rp += sizeof(TEST_MODULE_NAME); -+ -+ assert_int_equal(*(body + rp + sizeof(TEST2_KEY_ID) - 1), 0); -+ assert_string_equal(body + rp, TEST2_KEY_ID); -+ rp += sizeof(TEST2_KEY_ID); -+ } -+ - assert_int_equal(rp, blen); - - return EOK; -@@ -809,7 +930,8 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - static int test_pam_cert_check(uint32_t status, uint8_t *body, size_t blen) - { - return test_pam_cert_check_ex(status, body, blen, -- SSS_PAM_CERT_INFO, "pamuser@"TEST_DOM_NAME); -+ SSS_PAM_CERT_INFO, "pamuser@"TEST_DOM_NAME, -+ NULL); - } - - static int test_pam_cert_check_with_hint(uint32_t status, uint8_t *body, -@@ -817,14 +939,22 @@ static int test_pam_cert_check_with_hint(uint32_t status, uint8_t *body, - { - return test_pam_cert_check_ex(status, body, blen, - SSS_PAM_CERT_INFO_WITH_HINT, -- "pamuser@"TEST_DOM_NAME); -+ "pamuser@"TEST_DOM_NAME, NULL); - } - - static int test_pam_cert_check_with_hint_no_user(uint32_t status, uint8_t *body, - size_t blen) - { - return test_pam_cert_check_ex(status, body, blen, -- SSS_PAM_CERT_INFO_WITH_HINT, ""); -+ SSS_PAM_CERT_INFO_WITH_HINT, "", NULL); -+} -+ -+static int test_pam_cert_check_2certs(uint32_t status, uint8_t *body, -+ size_t blen) -+{ -+ return test_pam_cert_check_ex(status, body, blen, -+ SSS_PAM_CERT_INFO, "pamuser@"TEST_DOM_NAME, -+ "pamuser@"TEST_DOM_NAME); - } - - static int test_pam_offline_chauthtok_check(uint32_t status, -@@ -1737,6 +1867,33 @@ static int test_lookup_by_cert_cb(void *pvt) - - return EOK; - } -+static int test_lookup_by_cert_cb_2nd_cert_same_user(void *pvt) -+{ -+ int ret; -+ struct sysdb_attrs *attrs; -+ unsigned char *der = NULL; -+ size_t der_size; -+ -+ test_lookup_by_cert_cb(pvt); -+ -+ attrs = sysdb_new_attrs(pam_test_ctx); -+ assert_non_null(attrs); -+ -+ der = sss_base64_decode(pam_test_ctx, TEST_TOKEN_2ND_CERT, &der_size); -+ assert_non_null(der); -+ -+ ret = sysdb_attrs_add_mem(attrs, SYSDB_USER_MAPPED_CERT, der, der_size); -+ talloc_free(der); -+ assert_int_equal(ret, EOK); -+ -+ ret = sysdb_set_user_attr(pam_test_ctx->tctx->dom, -+ pam_test_ctx->pam_user_fqdn, -+ attrs, -+ LDB_FLAG_MOD_ADD); -+ assert_int_equal(ret, EOK); -+ -+ return EOK; -+} - - static int test_lookup_by_cert_double_cb(void *pvt) - { -@@ -2094,6 +2251,51 @@ void test_pam_cert_auth_double_cert(void **state) - assert_int_equal(ret, EOK); - } - -+void test_pam_cert_preauth_2certs_one_mapping(void **state) -+{ -+ int ret; -+ -+ set_cert_auth_param(pam_test_ctx->pctx, NSS_DB_2CERTS); -+ -+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, -+ test_lookup_by_cert_cb, TEST_TOKEN_CERT, false); -+ -+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ -+ 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_2certs_two_mappings(void **state) -+{ -+ int ret; -+ -+ set_cert_auth_param(pam_test_ctx->pctx, NSS_DB_2CERTS); -+ -+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, -+ test_lookup_by_cert_cb_2nd_cert_same_user, -+ TEST_TOKEN_CERT, 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_2certs); -+ 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) - { - int ret; -@@ -2523,6 +2725,10 @@ int main(int argc, const char *argv[]) - pam_test_teardown), - cmocka_unit_test_setup_teardown(test_pam_cert_auth_double_cert, - pam_test_setup, pam_test_teardown), -+ cmocka_unit_test_setup_teardown(test_pam_cert_preauth_2certs_one_mapping, -+ pam_test_setup, pam_test_teardown), -+ cmocka_unit_test_setup_teardown(test_pam_cert_preauth_2certs_two_mappings, -+ pam_test_setup, pam_test_teardown), - #endif /* HAVE_NSS */ - - cmocka_unit_test_setup_teardown(test_filter_response, -diff --git a/src/tests/whitespace_test b/src/tests/whitespace_test -index 799e35358b1d5ae4b10c4405068fb507cb234b6f..f055ed4c255db4001194844f45a9df7cda774b38 100755 ---- a/src/tests/whitespace_test -+++ b/src/tests/whitespace_test -@@ -39,7 +39,7 @@ fi - declare found_file=false - while read file; do - [[ $file == "src/config/testconfigs/noparse.api.conf" ]] && continue -- [[ $file =~ ^src/tests/cmocka/p11_nssdb/.*db ]] && continue -+ [[ $file =~ ^src/tests/cmocka/p11_nssdb.*/.*db ]] && continue - test `tail -c 1 $ABS_TOP_SRCDIR/$file` && \ - echo "Missing new line at the eof: $file" && \ - found_file=true --- -2.13.6 - diff --git a/SOURCES/0037-SUDO-Fix-running-in-unprivileged-responder.patch b/SOURCES/0037-SUDO-Fix-running-in-unprivileged-responder.patch new file mode 100644 index 0000000..5ac4676 --- /dev/null +++ b/SOURCES/0037-SUDO-Fix-running-in-unprivileged-responder.patch @@ -0,0 +1,95 @@ +From 261ff6442294b11261c11262d2a6acf379803e36 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Tue, 24 Jul 2018 18:52:08 +0000 +Subject: [PATCH] SUDO: Fix running in unprivileged responder + +There are strict checks for private sockets which does not work with +unprivileged responder + +Resolves: +https://pagure.io/SSSD/sssd/issue/3778 + +Merges: https://pagure.io/SSSD/sssd/pull-request/3784 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 4900b8e59bdbb89fbc1c9718969aabe26f3db34a) + +DOWNSTREAM: +Resolves: rhbz#1607313 - When sssd is running as non-root user, the sudo pipe is created as sssd:sssd but then the private pipe ownership fails +--- + src/responder/sudo/sudosrv.c | 31 +++++++++++++++++++++++++++---- + 1 file changed, 27 insertions(+), 4 deletions(-) + +diff --git a/src/responder/sudo/sudosrv.c b/src/responder/sudo/sudosrv.c +index e87a24499c2d82fafaa8e1f9b386e44332394266..82315e0a8f7879595e02458a9aa79e7332b04734 100644 +--- a/src/responder/sudo/sudosrv.c ++++ b/src/responder/sudo/sudosrv.c +@@ -67,7 +67,8 @@ static void sudo_dp_reconnect_init(struct sbus_connection *conn, + + int sudo_process_init(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, +- struct confdb_ctx *cdb) ++ struct confdb_ctx *cdb, ++ int pipe_fd) + { + struct resp_ctx *rctx; + struct sss_cmd_table *sudo_cmds; +@@ -79,8 +80,8 @@ int sudo_process_init(TALLOC_CTX *mem_ctx, + sudo_cmds = get_sudo_cmds(); + ret = sss_process_init(mem_ctx, ev, cdb, + sudo_cmds, +- NULL, -1, /* No public socket */ +- SSS_SUDO_SOCKET_NAME, -1, /* Private socket only */ ++ SSS_SUDO_SOCKET_NAME, pipe_fd, /* custom permissions on socket */ ++ NULL, -1, /* No private socket */ + CONFDB_SUDO_CONF_ENTRY, + SSS_SUDO_SBUS_SERVICE_NAME, + SSS_SUDO_SBUS_SERVICE_VERSION, +@@ -182,6 +183,7 @@ int main(int argc, const char *argv[]) + char *opt_logger = NULL; + struct main_context *main_ctx; + int ret; ++ int pipe_fd = -1; + uid_t uid; + gid_t gid; + +@@ -219,6 +221,27 @@ int main(int argc, const char *argv[]) + + sss_set_logger(opt_logger); + ++ if (!is_socket_activated()) { ++ /* Create pipe file descriptors here with right ownerschip */ ++ ret = create_pipe_fd(SSS_SUDO_SOCKET_NAME, &pipe_fd, SSS_DFL_UMASK); ++ if (ret != EOK) { ++ DEBUG(SSSDBG_FATAL_FAILURE, ++ "create_pipe_fd failed [%d]: %s.\n", ++ ret, sss_strerror(ret)); ++ return 4; ++ } ++ ++ ret = chown(SSS_SUDO_SOCKET_NAME, uid, 0); ++ if (ret != 0) { ++ ret = errno; ++ close(pipe_fd); ++ DEBUG(SSSDBG_FATAL_FAILURE, ++ "create_pipe_fd failed [%d]: %s.\n", ++ ret, sss_strerror(ret)); ++ return 5; ++ } ++ } ++ + ret = server_setup("sssd[sudo]", 0, uid, gid, CONFDB_SUDO_CONF_ENTRY, + &main_ctx); + if (ret != EOK) { +@@ -234,7 +257,7 @@ int main(int argc, const char *argv[]) + + ret = sudo_process_init(main_ctx, + main_ctx->event_ctx, +- main_ctx->confdb_ctx); ++ main_ctx->confdb_ctx, pipe_fd); + if (ret != EOK) { + return 3; + } +-- +2.14.4 + diff --git a/SOURCES/0038-SUDO-Root-should-be-able-to-read-write-sssd-sudo-soc.patch b/SOURCES/0038-SUDO-Root-should-be-able-to-read-write-sssd-sudo-soc.patch new file mode 100644 index 0000000..607eabb --- /dev/null +++ b/SOURCES/0038-SUDO-Root-should-be-able-to-read-write-sssd-sudo-soc.patch @@ -0,0 +1,39 @@ +From 2708fb488277209a60a5daf5217502c029c196c1 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Tue, 24 Jul 2018 18:52:08 +0000 +Subject: [PATCH] SUDO: Root should be able to read/write sssd-sudo socket + +There is not any reason to require additional capabilities from root +when sssd is running as unprivileged user. + +Sudo UNIX socket is not a real private socket. It just cannot +be used by others. Just owner(sssd) and root should be able to use it. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3778 + +Merges: https://pagure.io/SSSD/sssd/pull-request/3784 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 21ea8204a0bd8ea4451f420713e909d3cfee34ef) +--- + src/sysv/systemd/sssd-sudo.socket.in | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/sysv/systemd/sssd-sudo.socket.in b/src/sysv/systemd/sssd-sudo.socket.in +index 96a8b0327ddb4d331c9b2e97ece3453f8f76872d..e94a2f6151e3d69edc304776b72a81db22762503 100644 +--- a/src/sysv/systemd/sssd-sudo.socket.in ++++ b/src/sysv/systemd/sssd-sudo.socket.in +@@ -10,8 +10,7 @@ Conflicts=shutdown.target + ExecStartPre=@libexecdir@/sssd/sssd_check_socket_activated_responders -r sudo + ListenStream=@pipepath@/sudo + SocketUser=@SSSD_USER@ +-SocketGroup=@SSSD_USER@ +-SocketMode=0600 ++SocketMode=0660 + + [Install] + WantedBy=sssd.service +-- +2.14.4 + diff --git a/SOURCES/0038-pam_sss-refactoring-use-struct-cert_auth_info.patch b/SOURCES/0038-pam_sss-refactoring-use-struct-cert_auth_info.patch deleted file mode 100644 index fc2b370..0000000 --- a/SOURCES/0038-pam_sss-refactoring-use-struct-cert_auth_info.patch +++ /dev/null @@ -1,680 +0,0 @@ -From cee84ed12721092bc40bc02dc66ce3efbb2bac74 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 16 Oct 2017 14:13:10 +0200 -Subject: [PATCH 38/46] pam_sss: refactoring, use struct cert_auth_info -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Similar as in the PAM responder this patch replaces the individual -certificate authentication related attributes by a struct which can be -used as a list. With the pam_sss can handle multiple SSS_PAM_CERT_INFO -message and place the data in individual list items. - -If multiple certificates are returned before prompting for the PIN a -dialog to select a certificate is shown to the users. If available a GDM -PAM extension is used to let the user choose from a list. All coded -needed at runtime to check if the extension is available and handle the -data is provided by GDM as macros. This means that there are no -additional run-time requirements. - -Related to https://pagure.io/SSSD/sssd/issue/3560 - -Reviewed-by: Fabiano Fidêncio -Tested-by: Scott Poore -(cherry picked from commit 122830e67472390b41edc73f0cfcd5c5705b726b) ---- - contrib/sssd.spec.in | 9 + - src/external/pam.m4 | 12 ++ - src/sss_client/pam_message.h | 8 +- - src/sss_client/pam_sss.c | 439 ++++++++++++++++++++++++++++++++++--------- - 4 files changed, 370 insertions(+), 98 deletions(-) - -diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in -index 1ee64d5a2a64635984260fceced779f4804e8b31..d9323bf1a2d84f4219f8ab11886e5ce87b401c15 100644 ---- a/contrib/sssd.spec.in -+++ b/contrib/sssd.spec.in -@@ -121,6 +121,12 @@ - %global with_kcm_option --without-kcm - %endif - -+%if (0%{?fedora} >= 27 || (0%{?rhel} >= 7 && 0%{?rhel7_minor} > 4)) -+ %global with_gdm_pam_extensions 1 -+%else -+ %global with_gdm_pam_extensions 0 -+%endif -+ - Name: @PACKAGE_NAME@ - Version: @PACKAGE_VERSION@ - Release: 0@PRERELEASE_VERSION@%{?dist} -@@ -233,6 +239,9 @@ BuildRequires: libuuid-devel - BuildRequires: jansson-devel - BuildRequires: libcurl-devel - %endif -+%if (0%{?with_gdm_pam_extensions} == 1) -+BuildRequires: gdm-devel -+%endif - - %description - Provides a set of daemons to manage access to remote directories and -diff --git a/src/external/pam.m4 b/src/external/pam.m4 -index 4776b6ae338409f0a2729dfc4cf5962463a40dfd..0dc7f19d0df6a4588cf893ecff6e518111462433 100644 ---- a/src/external/pam.m4 -+++ b/src/external/pam.m4 -@@ -27,3 +27,15 @@ AC_CHECK_FUNCS(pam_modutil_getlogin pam_vsyslog) - - dnl restore LIBS - LIBS="$save_LIBS" -+ -+PKG_CHECK_MODULES([GDM_PAM_EXTENSIONS], [gdm-pam-extensions], -+ [found_gdm_pam_extensions=yes], -+ [AC_MSG_NOTICE([gdm-pam-extensions were not found. gdm support -+for multiple certificates will not be build. -+])]) -+ -+AC_SUBST(GDM_PAM_EXTENSIONS_CFLAGS) -+ -+AS_IF([test x"$found_gdm_pam_extensions" = xyes], -+ [AC_DEFINE_UNQUOTED(HAVE_GDM_PAM_EXTENSIONS, 1, -+ [Build with gdm-pam-extensions support])]) -diff --git a/src/sss_client/pam_message.h b/src/sss_client/pam_message.h -index f215392f6879f01a0ca12abc8807bac5fc1f1cbb..11526a80a767ff5602b194d14765ff261e8f9707 100644 ---- a/src/sss_client/pam_message.h -+++ b/src/sss_client/pam_message.h -@@ -29,6 +29,8 @@ - - #include "sss_client/sss_cli.h" - -+struct cert_auth_info; -+ - struct pam_items { - const char *pam_service; - const char *pam_user; -@@ -59,11 +61,9 @@ struct pam_items { - char *first_factor; - bool password_prompting; - -- char *cert_user; -- char *token_name; -- char *module_name; -- char *key_id; - bool user_name_hint; -+ struct cert_auth_info *cert_list; -+ struct cert_auth_info *selected_cert; - }; - - int pack_message_v3(struct pam_items *pi, size_t *size, uint8_t **buffer); -diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c -index 303809b9ea05b5a8709c05ae230d5f289b57de31..c147d4b3d76443d69e27eb2da042f8eebd1ae6ab 100644 ---- a/src/sss_client/pam_sss.c -+++ b/src/sss_client/pam_sss.c -@@ -36,6 +36,10 @@ - #include - #include - -+#ifdef HAVE_GDM_PAM_EXTENSIONS -+#include -+#endif -+ - #include "sss_pam_compat.h" - #include "sss_pam_macros.h" - -@@ -43,6 +47,7 @@ - #include "pam_message.h" - #include "util/atomic_io.h" - #include "util/authtok-utils.h" -+#include "util/dlinklist.h" - - #include - #define _(STRING) dgettext (PACKAGE, STRING) -@@ -118,6 +123,40 @@ static void close_fd(pam_handle_t *pamh, void *ptr, int err) - sss_pam_close_fd(); - } - -+struct cert_auth_info { -+ char *cert_user; -+ char *cert; -+ char *token_name; -+ char *module_name; -+ char *key_id; -+ struct cert_auth_info *prev; -+ struct cert_auth_info *next; -+}; -+ -+static void free_cai(struct cert_auth_info *cai) -+{ -+ if (cai != NULL) { -+ free(cai->cert_user); -+ free(cai->cert); -+ free(cai->token_name); -+ free(cai->key_id); -+ free(cai); -+ } -+} -+ -+static void free_cert_list(struct cert_auth_info *list) -+{ -+ struct cert_auth_info *cai; -+ struct cert_auth_info *cai_next; -+ -+ if (list != NULL) { -+ DLIST_FOR_EACH_SAFE(cai, cai_next, list) { -+ DLIST_REMOVE(list, cai); -+ free_cai(cai); -+ } -+ } -+} -+ - static void overwrite_and_free_authtoks(struct pam_items *pi) - { - if (pi->pam_authtok != NULL) { -@@ -158,17 +197,9 @@ static void overwrite_and_free_pam_items(struct pam_items *pi) - free(pi->otp_challenge); - pi->otp_challenge = NULL; - -- free(pi->cert_user); -- pi->cert_user = NULL; -- -- free(pi->token_name); -- pi->token_name = NULL; -- -- free(pi->module_name); -- pi->module_name = NULL; -- -- free(pi->key_id); -- pi->key_id = NULL; -+ free_cert_list(pi->cert_list); -+ pi->cert_list = NULL; -+ pi->selected_cert = NULL; - } - - static int null_strcmp(const char *s1, const char *s2) { -@@ -821,6 +852,90 @@ static int eval_user_info_response(pam_handle_t *pamh, size_t buflen, - return ret; - } - -+static int parse_cert_info(struct pam_items *pi, uint8_t *buf, size_t len, -+ size_t *p, const char **cert_user) -+{ -+ struct cert_auth_info *cai = NULL; -+ size_t offset; -+ int ret; -+ -+ if (buf[*p + (len - 1)] != '\0') { -+ D(("cert info does not end with \\0.")); -+ return EINVAL; -+ } -+ -+ cai = calloc(1, sizeof(struct cert_auth_info)); -+ if (cai == NULL) { -+ return ENOMEM; -+ } -+ -+ cai->cert_user = strdup((char *) &buf[*p]); -+ if (cai->cert_user == NULL) { -+ D(("strdup failed")); -+ ret = ENOMEM; -+ goto done; -+ } -+ if (cert_user != NULL) { -+ *cert_user = cai->cert_user; -+ } -+ -+ offset = strlen(cai->cert_user) + 1; -+ if (offset >= len) { -+ D(("Cert message size mismatch")); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ cai->token_name = strdup((char *) &buf[*p + offset]); -+ if (cai->token_name == NULL) { -+ D(("strdup failed")); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ offset += strlen(cai->token_name) + 1; -+ if (offset >= len) { -+ D(("Cert message size mismatch")); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ cai->module_name = strdup((char *) &buf[*p + offset]); -+ if (cai->module_name == NULL) { -+ D(("strdup failed")); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ offset += strlen(cai->module_name) + 1; -+ if (offset >= len) { -+ D(("Cert message size mismatch")); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ cai->key_id = strdup((char *) &buf[*p + offset]); -+ if (cai->key_id == NULL) { -+ D(("strdup failed")); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ D(("cert user: [%s] token name: [%s] module: [%s] key id: [%s]", -+ cai->cert_user, cai->token_name, cai->module_name, -+ cai->key_id)); -+ -+ DLIST_ADD(pi->cert_list, cai); -+ ret = 0; -+ -+done: -+ if (ret != 0) { -+ free_cai(cai); -+ } -+ -+ return ret; -+} -+ - static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf, - struct pam_items *pi) - { -@@ -832,6 +947,7 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf, - int32_t len; - int32_t pam_status; - size_t offset; -+ const char *cert_user; - - if (buflen < (2*sizeof(int32_t))) { - D(("response buffer is too small")); -@@ -988,27 +1104,21 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf, - break; - } - -- free(pi->cert_user); -- pi->cert_user = strdup((char *) &buf[p]); -- if (pi->cert_user == NULL) { -- D(("strdup failed")); -- break; -- } -- -- if (type == SSS_PAM_CERT_INFO && *pi->cert_user == '\0') { -- D(("Invalid CERT message")); -- break; -- } -- - if (type == SSS_PAM_CERT_INFO_WITH_HINT) { - pi->user_name_hint = true; - } else { - pi->user_name_hint = false; - } - -+ ret = parse_cert_info(pi, buf, len, &p, &cert_user); -+ if (ret != 0) { -+ D(("Failed to parse cert info")); -+ break; -+ } -+ - if ((pi->pam_user == NULL || *(pi->pam_user) == '\0') -- && *pi->cert_user != '\0') { -- ret = pam_set_item(pamh, PAM_USER, pi->cert_user); -+ && *cert_user != '\0') { -+ ret = pam_set_item(pamh, PAM_USER, cert_user); - if (ret != PAM_SUCCESS) { - D(("Failed to set PAM_USER during " - "Smartcard authentication [%s]", -@@ -1027,59 +1137,6 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf, - - pi->pam_user_size = strlen(pi->pam_user) + 1; - } -- -- offset = strlen(pi->cert_user) + 1; -- if (offset >= len) { -- D(("Cert message size mismatch")); -- free(pi->cert_user); -- pi->cert_user = NULL; -- break; -- } -- free(pi->token_name); -- pi->token_name = strdup((char *) &buf[p + offset]); -- if (pi->token_name == NULL) { -- D(("strdup failed")); -- free(pi->cert_user); -- pi->cert_user = NULL; -- break; -- } -- -- offset += strlen(pi->token_name) + 1; -- if (offset >= len) { -- D(("Cert message size mismatch")); -- free(pi->cert_user); -- pi->cert_user = NULL; -- free(pi->token_name); -- pi->token_name = NULL; -- break; -- } -- free(pi->module_name); -- pi->module_name = strdup((char *) &buf[p + offset]); -- if (pi->module_name == NULL) { -- D(("strdup failed")); -- break; -- } -- -- offset += strlen(pi->module_name) + 1; -- if (offset >= len) { -- D(("Cert message size mismatch")); -- free(pi->cert_user); -- pi->cert_user = NULL; -- free(pi->token_name); -- pi->token_name = NULL; -- free(pi->module_name); -- pi->module_name = NULL; -- break; -- } -- free(pi->key_id); -- pi->key_id = strdup((char *) &buf[p + offset]); -- if (pi->key_id == NULL) { -- D(("strdup failed")); -- break; -- } -- D(("cert user: [%s] token name: [%s] module: [%s] key id: [%s]", -- pi->cert_user, pi->token_name, pi->module_name, -- pi->key_id)); - break; - case SSS_PASSWORD_PROMPTING: - D(("Password prompting available.")); -@@ -1175,10 +1232,8 @@ static int get_pam_items(pam_handle_t *pamh, uint32_t flags, - pi->otp_challenge = NULL; - pi->password_prompting = false; - -- pi->cert_user = NULL; -- pi->token_name = NULL; -- pi->module_name = NULL; -- pi->key_id = NULL; -+ pi->cert_list = NULL; -+ pi->selected_cert = NULL; - - return PAM_SUCCESS; - } -@@ -1484,6 +1539,184 @@ done: - - #define SC_PROMPT_FMT "PIN for %s" - -+#ifndef discard_const -+#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) -+#endif -+ -+#define CERT_SEL_PROMPT_FMT "Certificate: %s" -+#define SEL_TITLE discard_const("Please select a certificate") -+ -+static int prompt_multi_cert_gdm(pam_handle_t *pamh, struct pam_items *pi) -+{ -+#ifdef HAVE_GDM_PAM_EXTENSIONS -+ int ret; -+ size_t cert_count = 0; -+ size_t c; -+ const struct pam_conv *conv; -+ struct cert_auth_info *cai; -+ GdmPamExtensionChoiceListRequest *request = NULL; -+ GdmPamExtensionChoiceListResponse *response = NULL; -+ struct pam_message prompt_message; -+ const struct pam_message *prompt_messages[1]; -+ struct pam_response *reply = NULL; -+ char *prompt; -+ -+ if (!GDM_PAM_EXTENSION_SUPPORTED(GDM_PAM_EXTENSION_CHOICE_LIST)) { -+ return ENOTSUP; -+ } -+ -+ if (pi->cert_list == NULL) { -+ return EINVAL; -+ } -+ -+ DLIST_FOR_EACH(cai, pi->cert_list) { -+ cert_count++; -+ } -+ -+ ret = pam_get_item(pamh, PAM_CONV, (const void **)&conv); -+ if (ret != PAM_SUCCESS) { -+ ret = EIO; -+ return ret; -+ } -+ -+ request = calloc(1, GDM_PAM_EXTENSION_CHOICE_LIST_REQUEST_SIZE(cert_count)); -+ if (request == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ GDM_PAM_EXTENSION_CHOICE_LIST_REQUEST_INIT(request, SEL_TITLE, cert_count); -+ -+ c = 0; -+ DLIST_FOR_EACH(cai, pi->cert_list) { -+ ret = asprintf(&prompt, CERT_SEL_PROMPT_FMT, cai->key_id); -+ if (ret == -1) { -+ ret = ENOMEM; -+ goto done; -+ } -+ request->list.items[c].key = cai->key_id; -+ request->list.items[c++].text = prompt; -+ } -+ -+ GDM_PAM_EXTENSION_MESSAGE_TO_BINARY_PROMPT_MESSAGE(request, -+ &prompt_message); -+ prompt_messages[0] = &prompt_message; -+ -+ ret = conv->conv(1, prompt_messages, &reply, conv->appdata_ptr); -+ if (ret != PAM_SUCCESS) { -+ ret = EIO; -+ goto done; -+ } -+ -+ ret = EIO; -+ response = GDM_PAM_EXTENSION_REPLY_TO_CHOICE_LIST_RESPONSE(reply); -+ if (response->key == NULL) { -+ goto done; -+ } -+ -+ DLIST_FOR_EACH(cai, pi->cert_list) { -+ if (strcmp(response->key, cai->key_id) == 0) { -+ pam_info(pamh, "Certificate ‘%s’ selected", cai->key_id); -+ pi->selected_cert = cai; -+ ret = 0; -+ break; -+ } -+ } -+ -+done: -+ if (request != NULL) { -+ for (c = 0; c < cert_count; c++) { -+ free(discard_const(request->list.items[c++].text)); -+ } -+ free(request); -+ } -+ free(response); -+ -+ return ret; -+#else -+ return ENOTSUP; -+#endif -+} -+ -+#define TEXT_CERT_SEL_PROMPT_FMT "%s[%zu] Certificate: %s\n" -+#define TEXT_SEL_TITLE discard_const("Please select a certificate by typing " \ -+ "the corresponding number\n") -+static int prompt_multi_cert(pam_handle_t *pamh, struct pam_items *pi) -+{ -+ int ret; -+ size_t cert_count = 0; -+ size_t tries = 0; -+ long int resp = -1; -+ struct cert_auth_info *cai; -+ char *prompt; -+ char *tmp; -+ char *answer; -+ char *ep; -+ -+ /* First check if gdm extension is supported */ -+ ret = prompt_multi_cert_gdm(pamh, pi); -+ if (ret != ENOTSUP) { -+ return ret; -+ } -+ -+ if (pi->cert_list == NULL) { -+ return EINVAL; -+ } -+ -+ prompt = strdup(TEXT_SEL_TITLE); -+ if (prompt == NULL) { -+ return ENOMEM; -+ } -+ -+ DLIST_FOR_EACH(cai, pi->cert_list) { -+ cert_count++; -+ ret = asprintf(&tmp, TEXT_CERT_SEL_PROMPT_FMT, prompt, cert_count, -+ cai->key_id); -+ free(prompt); -+ if (ret == -1) { -+ return ENOMEM; -+ } -+ -+ prompt = tmp; -+ } -+ -+ do { -+ ret = do_pam_conversation(pamh, PAM_PROMPT_ECHO_ON, prompt, NULL, -+ &answer); -+ if (ret != PAM_SUCCESS) { -+ D(("do_pam_conversation failed.")); -+ break; -+ } -+ -+ errno = 0; -+ resp = strtol(answer, &ep, 10); -+ if (errno == 0 && *ep == '\0' && resp > 0 && resp <= cert_count) { -+ /* do not free answer ealier because ep is pointing to it */ -+ free(answer); -+ break; -+ } -+ free(answer); -+ resp = -1; -+ } while (++tries < 5); -+ free(prompt); -+ -+ pi->selected_cert = NULL; -+ ret = ENOENT; -+ if (resp > 0 && resp <= cert_count) { -+ cert_count = 0; -+ DLIST_FOR_EACH(cai, pi->cert_list) { -+ cert_count++; -+ if (resp == cert_count) { -+ pam_info(pamh, "Certificate ‘%s’ selected", cai->key_id); -+ pi->selected_cert = cai; -+ ret = 0; -+ break; -+ } -+ } -+ } -+ -+ return ret; -+} -+ - static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi) - { - int ret; -@@ -1495,19 +1728,20 @@ static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi) - const struct pam_message *mesg[2] = { NULL, NULL }; - struct pam_message m[2] = { { 0 }, { 0 } }; - struct pam_response *resp = NULL; -+ struct cert_auth_info *cai = pi->selected_cert; - -- if (pi->token_name == NULL || *pi->token_name == '\0') { -+ if (cai == NULL || cai->token_name == NULL || *cai->token_name == '\0') { - return EINVAL; - } - -- size = sizeof(SC_PROMPT_FMT) + strlen(pi->token_name); -+ size = sizeof(SC_PROMPT_FMT) + strlen(cai->token_name); - prompt = malloc(size); - if (prompt == NULL) { - D(("malloc failed.")); - return ENOMEM; - } - -- ret = snprintf(prompt, size, SC_PROMPT_FMT, pi->token_name); -+ ret = snprintf(prompt, size, SC_PROMPT_FMT, cai->token_name); - if (ret < 0 || ret >= size) { - D(("snprintf failed.")); - free(prompt); -@@ -1604,9 +1838,9 @@ static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi) - pi->pam_authtok_size=0; - } else { - -- ret = sss_auth_pack_sc_blob(answer, 0, pi->token_name, 0, -- pi->module_name, 0, -- pi->key_id, 0, -+ ret = sss_auth_pack_sc_blob(answer, 0, cai->token_name, 0, -+ cai->module_name, 0, -+ cai->key_id, 0, - NULL, 0, &needed_size); - if (ret != EAGAIN) { - D(("sss_auth_pack_sc_blob failed.")); -@@ -1621,9 +1855,9 @@ static int prompt_sc_pin(pam_handle_t *pamh, struct pam_items *pi) - goto done; - } - -- ret = sss_auth_pack_sc_blob(answer, 0, pi->token_name, 0, -- pi->module_name, 0, -- pi->key_id, 0, -+ ret = sss_auth_pack_sc_blob(answer, 0, cai->token_name, 0, -+ cai->module_name, 0, -+ cai->key_id, 0, - (uint8_t *) pi->pam_authtok, needed_size, - &needed_size); - if (ret != EOK) { -@@ -1786,7 +2020,17 @@ static int get_authtok_for_authentication(pam_handle_t *pamh, - ret = prompt_2fa(pamh, pi, _("First Factor: "), - _("Second Factor: ")); - } -- } else if (pi->token_name != NULL && *(pi->token_name) != '\0') { -+ } else if (pi->cert_list != NULL) { -+ if (pi->cert_list->next == NULL) { -+ /* Only one certificate */ -+ pi->selected_cert = pi->cert_list; -+ } else { -+ ret = prompt_multi_cert(pamh, pi); -+ if (ret != 0) { -+ D(("Failed to select certificate")); -+ return PAM_AUTHTOK_ERR; -+ } -+ } - ret = prompt_sc_pin(pamh, pi); - } else { - ret = prompt_password(pamh, pi, _("Password: ")); -@@ -1905,14 +2149,21 @@ static int check_login_token_name(pam_handle_t *pamh, struct pam_items *pi, - char *prompt = NULL; - size_t size; - char *answer = NULL; -+ /* TODO: check multiple cert case */ -+ struct cert_auth_info *cai = pi->cert_list; -+ -+ if (cai == NULL) { -+ D(("No certificate information available")); -+ return EINVAL; -+ } - - login_token_name = getenv("PKCS11_LOGIN_TOKEN_NAME"); - if (login_token_name == NULL) { - return PAM_SUCCESS; - } - -- while (pi->token_name == NULL -- || strcmp(login_token_name, pi->token_name) != 0) { -+ while (cai->token_name == NULL -+ || strcmp(login_token_name, cai->token_name) != 0) { - size = sizeof(SC_ENTER_FMT) + strlen(login_token_name); - prompt = malloc(size); - if (prompt == NULL) { --- -2.13.6 - diff --git a/SOURCES/0039-p11_child-use-options-to-select-certificate-for-auth.patch b/SOURCES/0039-p11_child-use-options-to-select-certificate-for-auth.patch deleted file mode 100644 index 4b476fc..0000000 --- a/SOURCES/0039-p11_child-use-options-to-select-certificate-for-auth.patch +++ /dev/null @@ -1,609 +0,0 @@ -From e857005c207e514c487ba75daf20ca4be5321c38 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 27 Oct 2017 10:13:36 +0200 -Subject: [PATCH 39/46] p11_child: use options to select certificate for - authentication -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -New options are added to p11_child to select a specific certificate -during authentication. - -The related unit tests are updated by adding the needed attributes to -the requests. The was not necessary before because although the -attribute were already send by pam_sss they were not used in the PAM -responder but only forwarded to the back where they were used by the -PKINIT code to select the expected certificate. - -Related to https://pagure.io/SSSD/sssd/issue/3560 - -Reviewed-by: Fabiano Fidêncio -Tested-by: Scott Poore -(cherry picked from commit 0a8024af282b271ad2185f68703d9f4e766d2bdc) ---- - src/p11_child/p11_child_nss.c | 213 ++++++++++++++++++++++++++-------------- - src/responder/pam/pamsrv_p11.c | 30 +++++- - src/tests/cmocka/test_pam_srv.c | 64 ++++++++---- - 3 files changed, 210 insertions(+), 97 deletions(-) - -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index 50bde2f4f91f6c00260b0db383d0962112686ebc..c676375cf7f6677a1d7f38f09b9bb5fd820d60c5 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -67,12 +67,34 @@ static char *password_passthrough(PK11SlotInfo *slot, PRBool retry, void *arg) - return PL_strdup((char *)arg); - } - -+static char *get_key_id_str(PK11SlotInfo *slot, CERTCertificate *cert) -+{ -+ SECItem *key_id = NULL; -+ char *key_id_str = NULL; - -+ key_id = PK11_GetLowLevelKeyIDForCert(slot, cert, NULL); -+ if (key_id == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "PK11_GetLowLevelKeyIDForCert failed [%d].\n", -+ PR_GetError()); -+ return NULL; -+ } - --int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, -+ key_id_str = CERT_Hexify(key_id, PR_FALSE); -+ SECITEM_FreeItem(key_id, PR_TRUE); -+ if (key_id_str == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n", PR_GetError()); -+ return NULL; -+ } -+ -+ return key_id_str; -+} -+ -+int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - enum op_mode mode, const char *pin, - struct cert_verify_opts *cert_verify_opts, -- char **_multi) -+ const char *module_name_in, const char *token_name_in, -+ const char *key_id_in, char **_multi) - { - int ret; - SECStatus rv; -@@ -153,42 +175,31 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - mod_list_item->module->dllName); - } - -- if (slot_name_in != NULL) { -- slot = PK11_FindSlotByName(slot_name_in); -- if (slot == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "PK11_FindSlotByName failed for [%s]: [%d].\n", -- slot_name_in, PR_GetError()); -- return EIO; -- } -- } else { -- -- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, -- NULL); -- if (list == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "PK11_GetAllTokens failed.\n"); -- return EIO; -- } -+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_TRUE, -+ NULL); -+ if (list == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "PK11_GetAllTokens failed.\n"); -+ return EIO; -+ } - -- for (le = list->head; le; le = le->next) { -- CK_SLOT_INFO slInfo; -+ for (le = list->head; le; le = le->next) { -+ CK_SLOT_INFO slInfo; - -- slInfo.flags = 0; -- rv = PK11_GetSlotInfo(le->slot, &slInfo); -- DEBUG(SSSDBG_TRACE_ALL, -- "Description [%s] Manufacturer [%s] flags [%lu].\n", -- slInfo.slotDescription, slInfo.manufacturerID, slInfo.flags); -- if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) { -- slot = PK11_ReferenceSlot(le->slot); -- break; -- } -- } -- PK11_FreeSlotList(list); -- if (slot == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "No removable slots found.\n"); -- return EIO; -+ slInfo.flags = 0; -+ rv = PK11_GetSlotInfo(le->slot, &slInfo); -+ DEBUG(SSSDBG_TRACE_ALL, -+ "Description [%s] Manufacturer [%s] flags [%lu].\n", -+ slInfo.slotDescription, slInfo.manufacturerID, slInfo.flags); -+ if (rv == SECSuccess && (slInfo.flags & CKF_REMOVABLE_DEVICE)) { -+ slot = PK11_ReferenceSlot(le->slot); -+ break; - } - } -- -+ PK11_FreeSlotList(list); -+ if (slot == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "No removable slots found.\n"); -+ return EIO; -+ } - - slot_id = PK11_GetSlotID(slot); - module_id = PK11_GetModuleID(slot); -@@ -317,24 +328,60 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - for (cert_list_node = CERT_LIST_HEAD(cert_list); - !CERT_LIST_END(cert_list_node, cert_list); - cert_list_node = CERT_LIST_NEXT(cert_list_node)) { -- if (cert_list_node->cert) { -- DEBUG(SSSDBG_TRACE_ALL, "found cert[%s][%s]\n", -- cert_list_node->cert->nickname, -- cert_list_node->cert->subjectName); -+ if (cert_list_node->cert == NULL) { -+ DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n"); -+ continue; -+ } - -- if (cert_verify_opts->do_verification) { -- rv = CERT_VerifyCertificateNow(handle, cert_list_node->cert, -- PR_TRUE, -- certificateUsageSSLClient, -- NULL, NULL); -- if (rv != SECSuccess) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Certificate [%s][%s] not valid [%d], skipping.\n", -- cert_list_node->cert->nickname, -- cert_list_node->cert->subjectName, PR_GetError()); -- continue; -- } -+ DEBUG(SSSDBG_TRACE_ALL, -+ "found cert[%s][%s]\n", -+ cert_list_node->cert->nickname, -+ cert_list_node->cert->subjectName); -+ -+ if (cert_verify_opts->do_verification) { -+ rv = CERT_VerifyCertificateNow(handle, cert_list_node->cert, -+ PR_TRUE, -+ certificateUsageSSLClient, -+ NULL, NULL); -+ if (rv != SECSuccess) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Certificate [%s][%s] not valid [%d], skipping.\n", -+ cert_list_node->cert->nickname, -+ cert_list_node->cert->subjectName, PR_GetError()); -+ continue; - } -+ } -+ -+ if (key_id_in != NULL) { -+ PORT_Free(key_id_str); -+ key_id_str = NULL; -+ key_id_str = get_key_id_str(slot, cert_list_node->cert); -+ } -+ /* Check if we found the certificates we needed for authentication or -+ * the requested ones for pre-auth. For authentication all attributes -+ * must be given and match, for pre-auth only the given ones must -+ * match. */ -+ DEBUG(SSSDBG_TRACE_ALL, "%s %s %s %s %s %s.\n", -+ module_name_in, module_name, token_name_in, token_name, -+ key_id_in, key_id_str); -+ if ((mode == OP_AUTH -+ && module_name_in != NULL -+ && token_name_in != NULL -+ && key_id_in != NULL -+ && key_id_str != NULL -+ && strcmp(key_id_in, key_id_str) == 0 -+ && strcmp(token_name_in, token_name) == 0 -+ && strcmp(module_name_in, module_name) == 0) -+ || (mode == OP_PREAUTH -+ && (module_name_in == NULL -+ || (module_name_in != NULL -+ && strcmp(module_name_in, module_name) == 0)) -+ && (token_name_in == NULL -+ || (token_name_in != NULL -+ && strcmp(token_name_in, token_name) == 0)) -+ && (key_id_in == NULL -+ || (key_id_in != NULL && key_id_str != NULL -+ && strcmp(key_id_in, key_id_str) == 0)))) { - - rv = CERT_AddCertToListTail(valid_certs, cert_list_node->cert); - if (rv != SECSuccess) { -@@ -343,15 +390,6 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - ret = EIO; - goto done; - } -- -- if (found_cert == NULL) { -- found_cert = cert_list_node->cert; -- } else { -- DEBUG(SSSDBG_TRACE_ALL, "More than one certificate found, " \ -- "using just the first one.\n"); -- } -- } else { -- DEBUG(SSSDBG_TRACE_ALL, "--- empty cert list node ---\n"); - } - } - -@@ -367,7 +405,7 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - } - } - -- if (found_cert == NULL) { -+ if (CERT_LIST_EMPTY(valid_certs)) { - DEBUG(SSSDBG_TRACE_ALL, "No certificate found.\n"); - *_multi = NULL; - ret = EOK; -@@ -375,6 +413,23 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - } - - if (mode == OP_AUTH) { -+ cert_list_node = CERT_LIST_HEAD(valid_certs); -+ if (!CERT_LIST_END(CERT_LIST_NEXT(cert_list_node), valid_certs)) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "More than one certificate found for authentication, " -+ "aborting!\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ found_cert = cert_list_node->cert; -+ if (found_cert == NULL) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "No certificate found for authentication, aborting!\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ - rv = PK11_GenerateRandom(random_value, sizeof(random_value)); - if (rv != SECSuccess) { - DEBUG(SSSDBG_OP_FAILURE, -@@ -449,21 +504,10 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, const char *slot_name_in, - - found_cert = cert_list_node->cert; - -- SECITEM_FreeItem(key_id, PR_TRUE); - PORT_Free(key_id_str); -- key_id = PK11_GetLowLevelKeyIDForCert(slot, found_cert, NULL); -- if (key_id == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, -- "PK11_GetLowLevelKeyIDForCert failed [%d].\n", -- PR_GetError()); -- ret = EINVAL; -- goto done; -- } -- -- key_id_str = CERT_Hexify(key_id, PR_FALSE); -+ key_id_str = get_key_id_str(slot, found_cert); - if (key_id_str == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "get_key_id_str [%d].\n", PR_GetError()); - ret = ENOMEM; - goto done; - } -@@ -576,11 +620,13 @@ int main(int argc, const char *argv[]) - enum op_mode mode = OP_NONE; - enum pin_mode pin_mode = PIN_NONE; - char *pin = NULL; -- char *slot_name_in = NULL; - char *nss_db = NULL; - struct cert_verify_opts *cert_verify_opts; - char *verify_opts = NULL; - char *multi = NULL; -+ char *module_name = NULL; -+ char *token_name = NULL; -+ char *key_id = NULL; - - struct poptOption long_options[] = { - POPT_AUTOHELP -@@ -605,6 +651,12 @@ int main(int argc, const char *argv[]) - NULL}, - {"nssdb", 0, POPT_ARG_STRING, &nss_db, 0, _("NSS DB to use"), - NULL}, -+ {"module_name", 0, POPT_ARG_STRING, &module_name, 0, -+ _("Module name for authentication"), NULL}, -+ {"token_name", 0, POPT_ARG_STRING, &token_name, 0, -+ _("Token name for authentication"), NULL}, -+ {"key_id", 0, POPT_ARG_STRING, &key_id, 0, -+ _("Key ID for authentication"), NULL}, - POPT_TABLEEND - }; - -@@ -730,6 +782,15 @@ int main(int argc, const char *argv[]) - } - talloc_steal(main_ctx, debug_prg_name); - -+ if (mode == OP_AUTH && (module_name == NULL || token_name == NULL -+ || key_id == NULL)) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "--module_name, --token_name and --key_id must be for " -+ "authentication"); -+ ret = EINVAL; -+ goto fail; -+ } -+ - ret = parse_cert_verify_opts(main_ctx, verify_opts, &cert_verify_opts); - if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse verifiy option.\n"); -@@ -744,8 +805,8 @@ int main(int argc, const char *argv[]) - } - } - -- ret = do_work(main_ctx, nss_db, slot_name_in, mode, pin, cert_verify_opts, -- &multi); -+ ret = do_work(main_ctx, nss_db, mode, pin, cert_verify_opts, module_name, -+ token_name, key_id, &multi); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "do_work failed.\n"); - goto fail; -diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c -index 57c8e1e464f4262f2d78f869c52ca48bd469d90a..4d5572164763ed0b3a842019f820680a4dc2dfdc 100644 ---- a/src/responder/pam/pamsrv_p11.c -+++ b/src/responder/pam/pamsrv_p11.c -@@ -399,10 +399,13 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - struct timeval tv; - int pipefd_to_child[2] = PIPE_INIT; - int pipefd_from_child[2] = PIPE_INIT; -- const char *extra_args[7] = { NULL }; -+ const char *extra_args[13] = { NULL }; - uint8_t *write_buf = NULL; - size_t write_buf_len = 0; - size_t arg_c; -+ const char *module_name = NULL; -+ const char *token_name = NULL; -+ const char *key_id = NULL; - - req = tevent_req_create(mem_ctx, &state, struct pam_check_cert_state); - if (req == NULL) { -@@ -423,6 +426,30 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - extra_args[arg_c++] = verify_opts; - extra_args[arg_c++] = "--verify"; - } -+ -+ if (sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_SC_PIN -+ || sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_SC_KEYPAD) { -+ ret = sss_authtok_get_sc(pd->authtok, NULL, NULL, &token_name, NULL, -+ &module_name, NULL, &key_id, NULL); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_sc failed.\n"); -+ goto done; -+ } -+ -+ if (module_name != NULL && *module_name != '\0') { -+ extra_args[arg_c++] = module_name; -+ extra_args[arg_c++] = "--module_name"; -+ } -+ if (token_name != NULL && *token_name != '\0') { -+ extra_args[arg_c++] = token_name; -+ extra_args[arg_c++] = "--token_name"; -+ } -+ if (key_id != NULL && *key_id != '\0') { -+ extra_args[arg_c++] = key_id; -+ extra_args[arg_c++] = "--key_id"; -+ } -+ } -+ - if (pd->cmd == SSS_PAM_AUTHENTICATE) { - extra_args[arg_c++] = "--auth"; - switch (sss_authtok_get_type(pd->authtok)) { -@@ -437,6 +464,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - ret = EINVAL; - goto done; - } -+ - } else if (pd->cmd == SSS_PAM_PREAUTH) { - extra_args[arg_c++] = "--pre"; - } else { -diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c -index 7f0ed706512ffe0866c0e1fb7e6baa16bec942d8..5c1f621ccead75717d1721714d953d7d4d415d7b 100644 ---- a/src/tests/cmocka/test_pam_srv.c -+++ b/src/tests/cmocka/test_pam_srv.c -@@ -687,7 +687,9 @@ static void mock_input_pam(TALLOC_CTX *mem_ctx, - } - - static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name, -- const char *pin, const char *service, -+ const char *pin, const char *token_name, -+ const char *module_name, const char *key_id, -+ const char *service, - acct_cb_t acct_cb, const char *cert, - bool only_one_provider_call) - { -@@ -697,6 +699,7 @@ static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name, - struct pam_items pi = { 0 }; - int ret; - bool already_mocked = false; -+ size_t needed_size; - - if (name != NULL) { - pi.pam_user = name; -@@ -707,9 +710,21 @@ static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name, - } - - if (pin != NULL) { -- pi.pam_authtok = discard_const(pin); -- pi.pam_authtok_size = strlen(pi.pam_authtok) + 1; -+ ret = sss_auth_pack_sc_blob(pin, 0, token_name, 0, module_name, 0, -+ key_id, 0, NULL, 0, &needed_size); -+ assert_int_equal(ret, EAGAIN); -+ -+ pi.pam_authtok = malloc(needed_size); -+ assert_non_null(pi.pam_authtok); -+ -+ ret = sss_auth_pack_sc_blob(pin, 0, token_name, 0, module_name, 0, -+ key_id, 0, -+ (uint8_t *)pi.pam_authtok, needed_size, -+ &needed_size); -+ assert_int_equal(ret, EOK); -+ - pi.pam_authtok_type = SSS_AUTHTOK_TYPE_SC_PIN; -+ pi.pam_authtok_size = needed_size; - } - - pi.pam_service = service == NULL ? "login" : service; -@@ -724,6 +739,7 @@ static void mock_input_pam_cert(TALLOC_CTX *mem_ctx, const char *name, - pi.cli_pid = 12345; - - ret = pack_message_v3(&pi, &buf_size, &m_buf); -+ free(pi.pam_authtok); - assert_int_equal(ret, 0); - - buf = talloc_memdup(mem_ctx, m_buf, buf_size); -@@ -1732,7 +1748,8 @@ void test_pam_preauth_no_logon_name(void **state) - { - int ret; - -- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, false); -+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -+ NULL, false); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); - will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -@@ -1824,7 +1841,8 @@ void test_pam_preauth_cert_nocert(void **state) - - set_cert_auth_param(pam_test_ctx->pctx, "/no/path"); - -- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, false); -+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL, -+ NULL, NULL, false); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); - will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -@@ -1962,7 +1980,7 @@ void test_pam_preauth_cert_nomatch(void **state) - - set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); - -- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, -+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL, - test_lookup_by_cert_cb, NULL, false); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); -@@ -1984,7 +2002,7 @@ void test_pam_preauth_cert_match(void **state) - - set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); - -- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, -+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL, - test_lookup_by_cert_cb, TEST_TOKEN_CERT, false); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); -@@ -2007,8 +2025,9 @@ void test_pam_preauth_cert_match_gdm_smartcard(void **state) - - set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); - -- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, "gdm-smartcard", -- test_lookup_by_cert_cb, TEST_TOKEN_CERT, false); -+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, -+ "gdm-smartcard", test_lookup_by_cert_cb, -+ TEST_TOKEN_CERT, false); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); - will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -@@ -2029,7 +2048,7 @@ void test_pam_preauth_cert_match_wrong_user(void **state) - - set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); - -- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, -+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL, - test_lookup_by_cert_wrong_user_cb, - TEST_TOKEN_CERT, false); - -@@ -2061,7 +2080,7 @@ void test_pam_preauth_cert_no_logon_name(void **state) - * Additionally sss_parse_inp_recv() must be mocked because the cache - * request will be done with the username found by the certificate - * lookup. */ -- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, -+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL, - test_lookup_by_cert_cb, TEST_TOKEN_CERT, false); - mock_account_recv_simple(); - mock_parse_inp("pamuser", NULL, EOK); -@@ -2090,7 +2109,7 @@ void test_pam_preauth_cert_no_logon_name_with_hint(void **state) - * Since user name hint is enabled we do not have to search the user - * during pre-auth and there is no need for an extra mocked response as in - * test_pam_preauth_cert_no_logon_name. */ -- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, -+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL, - test_lookup_by_cert_cb, TEST_TOKEN_CERT, false); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); -@@ -2112,7 +2131,7 @@ void test_pam_preauth_cert_no_logon_name_double_cert(void **state) - - set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); - -- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, -+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL, - test_lookup_by_cert_double_cb, TEST_TOKEN_CERT, false); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); -@@ -2135,7 +2154,7 @@ void test_pam_preauth_cert_no_logon_name_double_cert_with_hint(void **state) - set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); - pam_test_ctx->rctx->domains->user_name_hint = true; - -- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, -+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL, - test_lookup_by_cert_double_cb, TEST_TOKEN_CERT, false); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); -@@ -2157,7 +2176,8 @@ void test_pam_preauth_no_cert_no_logon_name(void **state) - - set_cert_auth_param(pam_test_ctx->pctx, "/no/path"); - -- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, false); -+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -+ NULL, false); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); - will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -@@ -2178,7 +2198,7 @@ void test_pam_preauth_cert_no_logon_name_no_match(void **state) - - set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); - -- mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, -+ mock_input_pam_cert(pam_test_ctx, NULL, NULL, NULL, NULL, NULL, NULL, - test_lookup_by_cert_cb, NULL, false); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); -@@ -2206,7 +2226,9 @@ void test_pam_cert_auth(void **state) - * is looked up. Since the first mocked reply already adds the certificate - * to the user entry the lookup by certificate will already find the user - * in the cache and no second request to the backend is needed. */ -- mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", NULL, -+ mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", "SSSD Test Token", -+ "NSS-Internal", -+ "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7", NULL, - test_lookup_by_cert_cb, TEST_TOKEN_CERT, true); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); -@@ -2232,7 +2254,9 @@ void test_pam_cert_auth_double_cert(void **state) - - set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); - -- mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", NULL, -+ mock_input_pam_cert(pam_test_ctx, "pamuser", "123456", "SSSD Test Token", -+ "NSS-Internal", -+ "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7", NULL, - test_lookup_by_cert_double_cb, TEST_TOKEN_CERT, true); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); -@@ -2257,7 +2281,7 @@ void test_pam_cert_preauth_2certs_one_mapping(void **state) - - set_cert_auth_param(pam_test_ctx->pctx, NSS_DB_2CERTS); - -- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, -+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL, - test_lookup_by_cert_cb, TEST_TOKEN_CERT, false); - - will_return(__wrap_sss_packet_get_cmd, SSS_PAM_PREAUTH); -@@ -2279,7 +2303,7 @@ void test_pam_cert_preauth_2certs_two_mappings(void **state) - - set_cert_auth_param(pam_test_ctx->pctx, NSS_DB_2CERTS); - -- mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, -+ mock_input_pam_cert(pam_test_ctx, "pamuser", NULL, NULL, NULL, NULL, NULL, - test_lookup_by_cert_cb_2nd_cert_same_user, - TEST_TOKEN_CERT, false); - --- -2.13.6 - diff --git a/SOURCES/0039-sdap-respect-passwordGracelimit.patch b/SOURCES/0039-sdap-respect-passwordGracelimit.patch new file mode 100644 index 0000000..4150d92 --- /dev/null +++ b/SOURCES/0039-sdap-respect-passwordGracelimit.patch @@ -0,0 +1,93 @@ +From bfafa12ae83bcdec53bb306f68eff9e6acfbb4a6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= +Date: Fri, 20 Jul 2018 12:15:18 +0200 +Subject: [PATCH] sdap: respect passwordGracelimit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since recent changes in 389-ds two response controls are end when +passwordGracelimit is set and about to expire: +- [1.3.6.1.4.1.42.2.27.8.5.1] for the GraceLimit itself +- [2.16.840.1.113730.3.4.4] for the PasswordExpired + +Whenever the former is returned and the GraceLimit is still valid, we +shouldn't report the latter to the users. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3597 + +Signed-off-by: Fabiano Fidêncio + +Reviewed-by: Jakub Hrozek +(cherry picked from commit 954bf82b60b7cfd93b865a6618f155d042b15729) + +DOWNSTREAM: +Resolves: rhbz#1522928 - sssd doesn't allow user with expired password +to login when PasswordgraceLimit set +--- + src/providers/ldap/sdap_async_connection.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c +index a8d4262b52c4b2d2810450d68794f00558ea5c2d..8aacd6705a1f82be8c14f97996786ac9b47396d5 100644 +--- a/src/providers/ldap/sdap_async_connection.c ++++ b/src/providers/ldap/sdap_async_connection.c +@@ -734,6 +734,7 @@ static void simple_bind_done(struct sdap_op *op, + ber_int_t pp_expire; + LDAPPasswordPolicyError pp_error; + int result = LDAP_OTHER; ++ bool on_grace_login_limit = false; + + if (error) { + tevent_req_error(req, error); +@@ -772,6 +773,7 @@ static void simple_bind_done(struct sdap_op *op, + DEBUG(SSSDBG_TRACE_INTERNAL, + "Server returned control [%s].\n", + response_controls[c]->ldctl_oid); ++ + if (strcmp(response_controls[c]->ldctl_oid, + LDAP_CONTROL_PASSWORDPOLICYRESPONSE) == 0) { + lret = ldap_parse_passwordpolicy_control(state->sh->ldap, +@@ -799,13 +801,26 @@ static void simple_bind_done(struct sdap_op *op, + state->ppolicy->grace = pp_grace; + state->ppolicy->expire = pp_expire; + if (result == LDAP_SUCCESS) { +- ++ /* We have to set the on_grace_login_limit as when going ++ * through the response controls 389-ds may return both ++ * an warning and an error (and the order is not ensured) ++ * for the GraceLimit: ++ * - [1.3.6.1.4.1.42.2.27.8.5.1] for the GraceLimit itself ++ * - [2.16.840.1.113730.3.4.4] for the PasswordExpired ++ * ++ * So, in order to avoid bulldozing the GraceLimit, let's ++ * set it to true when pp_grace >= 0 and, in the end of ++ * this function, just return EOK when LDAP returns the ++ * PasswordExpired error but the GraceLimit is still valid. ++ */ ++ on_grace_login_limit = false; + if (pp_error == PP_changeAfterReset) { + DEBUG(SSSDBG_TRACE_LIBS, + "Password was reset. " + "User must set a new password.\n"); + ret = ERR_PASSWORD_EXPIRED; + } else if (pp_grace >= 0) { ++ on_grace_login_limit = true; + DEBUG(SSSDBG_TRACE_LIBS, + "Password expired. " + "[%d] grace logins remaining.\n", +@@ -875,6 +890,10 @@ static void simple_bind_done(struct sdap_op *op, + ret = ERR_AUTH_FAILED; + } + ++ if (ret == ERR_PASSWORD_EXPIRED && on_grace_login_limit) { ++ ret = EOK; ++ } ++ + done: + ldap_controls_free(response_controls); + ldap_memfree(errmsg); +-- +2.14.4 + diff --git a/SOURCES/0040-MC-Remove-check-if-record-is-in-the-mapped-address-s.patch b/SOURCES/0040-MC-Remove-check-if-record-is-in-the-mapped-address-s.patch new file mode 100644 index 0000000..5e9d331 --- /dev/null +++ b/SOURCES/0040-MC-Remove-check-if-record-is-in-the-mapped-address-s.patch @@ -0,0 +1,93 @@ +From 64085ac9dbc95bc7b227f24a9a8ec78952c68227 Mon Sep 17 00:00:00 2001 +From: Sumit Bose +Date: Wed, 11 Jul 2018 22:18:41 +0200 +Subject: [PATCH] MC: Remove check if record is in the mapped address space +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There is a check in the memory cache code that checks if a record pointer +points to the mmapped region . But since some time ago, we return not +a pointer to the mmapped region itself, but a copy to avoid issues with +invalidating an entry while the same entry is being returned. + +In most cases, the check is correct, simply because of how memory is laid +out on Linux, but in some cases the check was failing and causing a high +load of SSSD. + +Signed-off-by: Jakub Hrozek + +Resolves: +https://pagure.io/SSSD/sssd/issue/3776 + +Reviewed-by: Michal Židek +(cherry picked from commit f1c2d4139b6107ee3e9bec0cbe5bf8c2ea8428b2) + +DOWNSTREAM: +Resolves: rhbz#1586127 - Spurious check in the sssd nss memcache can cause the memory cache to be skipped +--- + src/sss_client/nss_mc_group.c | 4 +--- + src/sss_client/nss_mc_initgr.c | 5 +---- + src/sss_client/nss_mc_passwd.c | 4 +--- + 3 files changed, 3 insertions(+), 10 deletions(-) + +diff --git a/src/sss_client/nss_mc_group.c b/src/sss_client/nss_mc_group.c +index 6a2336b6116f198adea94f9eda9d9632f9fc8268..3371e0ffc274cd55dad4e7cdb74456f9f4b92d8b 100644 +--- a/src/sss_client/nss_mc_group.c ++++ b/src/sss_client/nss_mc_group.c +@@ -152,12 +152,10 @@ errno_t sss_nss_mc_getgrnam(const char *name, size_t name_len, + /* Integrity check + * - data->name cannot point outside strings + * - all strings must be within copy of record +- * - record must not end outside data table + * - rec_name is a zero-terminated string */ + if (data->name < strs_offset + || data->name >= strs_offset + data->strs_len +- || data->strs_len > rec->len +- || (uint8_t *) rec + rec->len > gr_mc_ctx.data_table + data_size) { ++ || data->strs_len > rec->len) { + ret = ENOENT; + goto done; + } +diff --git a/src/sss_client/nss_mc_initgr.c b/src/sss_client/nss_mc_initgr.c +index 5a8c661c7e15a085e9662297f62a6a84e70b669e..331930cef357d17c74892f67d5743ebc6a818631 100644 +--- a/src/sss_client/nss_mc_initgr.c ++++ b/src/sss_client/nss_mc_initgr.c +@@ -133,15 +133,12 @@ errno_t sss_nss_mc_initgroups_dyn(const char *name, size_t name_len, + /* Integrity check + * - data->name cannot point outside all strings or data + * - all data must be within copy of record +- * - size of record must be lower that data table size + * - data->strs cannot point outside strings + * - rec_name is a zero-terminated string */ + if (data->name < data_offset + || data->name >= data_offset + data->data_len + || data->strs_len > data->data_len +- || data->data_len > rec->len +- || (uint8_t *) rec + rec->len +- > initgr_mc_ctx.data_table + data_size) { ++ || data->data_len > rec->len) { + ret = ENOENT; + goto done; + } +diff --git a/src/sss_client/nss_mc_passwd.c b/src/sss_client/nss_mc_passwd.c +index 3c62481778788173227f8a241953e421316e248d..ac44b711d8614ac0daa841a7a9dd5894f1a1eb08 100644 +--- a/src/sss_client/nss_mc_passwd.c ++++ b/src/sss_client/nss_mc_passwd.c +@@ -145,12 +145,10 @@ errno_t sss_nss_mc_getpwnam(const char *name, size_t name_len, + /* Integrity check + * - data->name cannot point outside strings + * - all strings must be within copy of record +- * - record must not end outside data table + * - rec_name is a zero-terminated string */ + if (data->name < strs_offset + || data->name >= strs_offset + data->strs_len +- || data->strs_len > rec->len +- || (uint8_t *) rec + rec->len > pw_mc_ctx.data_table + data_size) { ++ || data->strs_len > rec->len) { + ret = ENOENT; + goto done; + } +-- +2.14.4 + diff --git a/SOURCES/0040-pam-add-prompt-string-for-certificate-authentication.patch b/SOURCES/0040-pam-add-prompt-string-for-certificate-authentication.patch deleted file mode 100644 index 8d94ce2..0000000 --- a/SOURCES/0040-pam-add-prompt-string-for-certificate-authentication.patch +++ /dev/null @@ -1,337 +0,0 @@ -From 4f09838b50cc771d52c7b00cc47fb3362d8ecda2 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 30 Oct 2017 08:03:42 +0100 -Subject: [PATCH 40/46] pam: add prompt string for certificate authentication -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -A new certificate attribute is added which contains a string which is -used in the certificate selection list displayed to the user. The -Subject-DN of the certificate is used here because it is present in all -certificate and in general differs for certificate with different usage. -libsss_certmap is used to extract the subject-DN from the certificate -and convert it into a string. - -Related to https://pagure.io/SSSD/sssd/issue/3560 - -Reviewed-by: Fabiano Fidêncio -Tested-by: Scott Poore -(cherry picked from commit 06c2300353faf3983e38fecb1d6afe1f6cc8fe32) ---- - Makefile.am | 2 ++ - src/responder/pam/pamsrv_p11.c | 65 ++++++++++++++++++++++++++++++++++++++++- - src/sss_client/pam_sss.c | 31 ++++++++++++++++---- - src/tests/cmocka/test_pam_srv.c | 23 +++++++++++++-- - 4 files changed, 111 insertions(+), 10 deletions(-) - -diff --git a/Makefile.am b/Makefile.am -index 4ed872a532daf9b934537cc5f64ce77778121e2a..16bcb4efc028b05c1196249245f4f3091b9366af 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1400,6 +1400,7 @@ sssd_pam_LDADD = \ - $(SELINUX_LIBS) \ - $(PAM_LIBS) \ - $(SYSTEMD_DAEMON_LIBS) \ -+ libsss_certmap.la \ - $(SSSD_INTERNAL_LTLIBS) \ - $(NULL) - -@@ -2423,6 +2424,7 @@ pam_srv_tests_LDADD = \ - $(SYSTEMD_DAEMON_LIBS) \ - libsss_test_common.la \ - libsss_idmap.la \ -+ libsss_certmap.la \ - $(NULL) - - EXTRA_responder_get_domains_tests_DEPENDENCIES = \ -diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c -index 4d5572164763ed0b3a842019f820680a4dc2dfdc..5a3eeff0ec977829a9ad8c80b4fc6b2e06857097 100644 ---- a/src/responder/pam/pamsrv_p11.c -+++ b/src/responder/pam/pamsrv_p11.c -@@ -26,6 +26,8 @@ - #include "util/child_common.h" - #include "util/strtonum.h" - #include "responder/pam/pamsrv.h" -+#include "lib/certmap/sss_certmap.h" -+#include "util/crypto/sss_crypto.h" - - - #ifndef SSSD_LIBEXEC_PATH -@@ -683,6 +685,54 @@ errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - return EOK; - } - -+static char *get_cert_prompt(TALLOC_CTX *mem_ctx, const char *cert) -+{ -+ int ret; -+ struct sss_certmap_ctx *ctx = NULL; -+ unsigned char *der = NULL; -+ size_t der_size; -+ char *prompt = NULL; -+ char *filter = NULL; -+ char **domains = NULL; -+ -+ ret = sss_certmap_init(mem_ctx, NULL, NULL, &ctx); -+ if (ret != 0) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_init failed.\n"); -+ return NULL; -+ } -+ -+ ret = sss_certmap_add_rule(ctx, 10, "KRB5:.*", -+ "LDAP:{subject_dn!nss}", NULL); -+ if (ret != 0) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_add_rule failed.\n"); -+ goto done; -+ } -+ -+ der = sss_base64_decode(mem_ctx, cert, &der_size); -+ if (der == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n"); -+ goto done; -+ } -+ -+ ret = sss_certmap_get_search_filter(ctx, der, der_size, &filter, &domains); -+ if (ret != 0) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_get_search_filter failed.\n"); -+ goto done; -+ } -+ -+ prompt = talloc_strdup(mem_ctx, filter); -+ if (prompt == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); -+ } -+ -+done: -+ sss_certmap_free_filter_and_domains(filter, domains); -+ sss_certmap_free_ctx(ctx); -+ talloc_free(der); -+ -+ return prompt; -+} -+ - static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username, - struct cert_auth_info *cert_info, - uint8_t **_msg, size_t *_msg_len) -@@ -692,16 +742,24 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username, - const char *token_name; - const char *module_name; - const char *key_id; -+ char *prompt; - size_t user_len; - size_t token_len; - size_t module_len; - size_t key_id_len; -+ size_t prompt_len; - const char *username = ""; - - if (sysdb_username != NULL) { - username = sysdb_username; - } - -+ prompt = get_cert_prompt(mem_ctx, sss_cai_get_cert(cert_info)); -+ if (prompt == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "get_cert_prompt failed.\n"); -+ return EIO; -+ } -+ - token_name = sss_cai_get_token_name(cert_info); - module_name = sss_cai_get_module_name(cert_info); - key_id = sss_cai_get_key_id(cert_info); -@@ -710,10 +768,12 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username, - token_len = strlen(token_name) + 1; - module_len = strlen(module_name) + 1; - key_id_len = strlen(key_id) + 1; -- msg_len = user_len + token_len + module_len + key_id_len; -+ prompt_len = strlen(prompt) + 1; -+ msg_len = user_len + token_len + module_len + key_id_len + prompt_len; - - msg = talloc_zero_size(mem_ctx, msg_len); - if (msg == NULL) { -+ talloc_free(prompt); - DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n"); - return ENOMEM; - } -@@ -722,6 +782,9 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username, - memcpy(msg + user_len, token_name, token_len); - memcpy(msg + user_len + token_len, module_name, module_len); - memcpy(msg + user_len + token_len + module_len, key_id, key_id_len); -+ memcpy(msg + user_len + token_len + module_len + key_id_len, -+ prompt, prompt_len); -+ talloc_free(prompt); - - if (_msg != NULL) { - *_msg = msg; -diff --git a/src/sss_client/pam_sss.c b/src/sss_client/pam_sss.c -index c147d4b3d76443d69e27eb2da042f8eebd1ae6ab..1dc51ea0536a92a63ec2f4d97f65dbb02604dbb3 100644 ---- a/src/sss_client/pam_sss.c -+++ b/src/sss_client/pam_sss.c -@@ -129,6 +129,7 @@ struct cert_auth_info { - char *token_name; - char *module_name; - char *key_id; -+ char *prompt_str; - struct cert_auth_info *prev; - struct cert_auth_info *next; - }; -@@ -140,6 +141,7 @@ static void free_cai(struct cert_auth_info *cai) - free(cai->cert); - free(cai->token_name); - free(cai->key_id); -+ free(cai->prompt_str); - free(cai); - } - } -@@ -921,9 +923,25 @@ static int parse_cert_info(struct pam_items *pi, uint8_t *buf, size_t len, - goto done; - } - -- D(("cert user: [%s] token name: [%s] module: [%s] key id: [%s]", -+ offset += strlen(cai->key_id) + 1; -+ if (offset >= len) { -+ D(("Cert message size mismatch")); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ cai->prompt_str = strdup((char *) &buf[*p + offset]); -+ if (cai->prompt_str == NULL) { -+ D(("strdup failed")); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ -+ D(("cert user: [%s] token name: [%s] module: [%s] key id: [%s] " -+ "prompt: [%s]", - cai->cert_user, cai->token_name, cai->module_name, -- cai->key_id)); -+ cai->key_id, cai->prompt_str)); - - DLIST_ADD(pi->cert_list, cai); - ret = 0; -@@ -1543,7 +1561,7 @@ done: - #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) - #endif - --#define CERT_SEL_PROMPT_FMT "Certificate: %s" -+#define CERT_SEL_PROMPT_FMT "%s" - #define SEL_TITLE discard_const("Please select a certificate") - - static int prompt_multi_cert_gdm(pam_handle_t *pamh, struct pam_items *pi) -@@ -1588,7 +1606,7 @@ static int prompt_multi_cert_gdm(pam_handle_t *pamh, struct pam_items *pi) - - c = 0; - DLIST_FOR_EACH(cai, pi->cert_list) { -- ret = asprintf(&prompt, CERT_SEL_PROMPT_FMT, cai->key_id); -+ ret = asprintf(&prompt, CERT_SEL_PROMPT_FMT, cai->prompt_str); - if (ret == -1) { - ret = ENOMEM; - goto done; -@@ -1637,9 +1655,10 @@ done: - #endif - } - --#define TEXT_CERT_SEL_PROMPT_FMT "%s[%zu] Certificate: %s\n" -+#define TEXT_CERT_SEL_PROMPT_FMT "%s\n[%zu]:\n%s\n" - #define TEXT_SEL_TITLE discard_const("Please select a certificate by typing " \ - "the corresponding number\n") -+ - static int prompt_multi_cert(pam_handle_t *pamh, struct pam_items *pi) - { - int ret; -@@ -1670,7 +1689,7 @@ static int prompt_multi_cert(pam_handle_t *pamh, struct pam_items *pi) - DLIST_FOR_EACH(cai, pi->cert_list) { - cert_count++; - ret = asprintf(&tmp, TEXT_CERT_SEL_PROMPT_FMT, prompt, cert_count, -- cai->key_id); -+ cai->prompt_str); - free(prompt); - if (ret == -1) { - return ENOMEM; -diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c -index 5c1f621ccead75717d1721714d953d7d4d415d7b..50d3ed005468375ff02c60bebd1c61047ca1c6d4 100644 ---- a/src/tests/cmocka/test_pam_srv.c -+++ b/src/tests/cmocka/test_pam_srv.c -@@ -53,6 +53,7 @@ - #define TEST_TOKEN_NAME "SSSD Test Token" - #define TEST_MODULE_NAME "NSS-Internal" - #define TEST_KEY_ID "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7" -+#define TEST_SUBJECT_DN "CN=ipa-devel.ipa.devel,O=IPA.DEVEL" - #define TEST_TOKEN_CERT \ - "MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \ - "REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA1MjMx" \ -@@ -78,6 +79,7 @@ - "XyQBwOYRORlnfGyu+Yc9c3E0Wx8Tlznz0lqPR9g=" - - #define TEST2_KEY_ID "C8D60E009EB195D01A7083EE1D5419251AA87C2C" -+#define TEST2_SUBJECT_DN "CN=IPA RA,O=IPA.DEVEL" - #define TEST_TOKEN_2ND_CERT \ - "MIIDazCCAlOgAwIBAgIBBzANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \ - "REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA1MjMx" \ -@@ -831,7 +833,8 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body, - assert_int_equal(val, (sizeof("pamuser@"TEST_DOM_NAME) - + sizeof(TEST_TOKEN_NAME) - + sizeof(TEST_MODULE_NAME) -- + sizeof(TEST_KEY_ID))); -+ + sizeof(TEST_KEY_ID) -+ + sizeof(TEST_SUBJECT_DN))); - - assert_int_equal(*(body + rp + sizeof("pamuser@"TEST_DOM_NAME) - 1), 0); - assert_string_equal(body + rp, "pamuser@"TEST_DOM_NAME); -@@ -849,6 +852,10 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body, - assert_string_equal(body + rp, TEST_KEY_ID); - rp += sizeof(TEST_KEY_ID); - -+ assert_int_equal(*(body + rp + sizeof(TEST_SUBJECT_DN) - 1), 0); -+ assert_string_equal(body + rp, TEST_SUBJECT_DN); -+ rp += sizeof(TEST_SUBJECT_DN); -+ - assert_int_equal(rp, blen); - return EOK; - } -@@ -893,7 +900,8 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - assert_int_equal(val, (strlen(name) + 1 - + sizeof(TEST_TOKEN_NAME) - + sizeof(TEST_MODULE_NAME) -- + sizeof(TEST_KEY_ID))); -+ + sizeof(TEST_KEY_ID) -+ + sizeof(TEST_SUBJECT_DN))); - - assert_int_equal(*(body + rp + strlen(name)), 0); - assert_string_equal(body + rp, name); -@@ -911,6 +919,10 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - assert_string_equal(body + rp, TEST_KEY_ID); - rp += sizeof(TEST_KEY_ID); - -+ assert_int_equal(*(body + rp + sizeof(TEST_SUBJECT_DN) - 1), 0); -+ assert_string_equal(body + rp, TEST_SUBJECT_DN); -+ rp += sizeof(TEST_SUBJECT_DN); -+ - if (name2 != NULL && *name2 != '\0') { - SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); - assert_int_equal(val, type); -@@ -919,7 +931,8 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - assert_int_equal(val, (strlen(name) + 1 - + sizeof(TEST_TOKEN_NAME) - + sizeof(TEST_MODULE_NAME) -- + sizeof(TEST2_KEY_ID))); -+ + sizeof(TEST2_KEY_ID) -+ + sizeof(TEST2_SUBJECT_DN))); - - assert_int_equal(*(body + rp + strlen(name)), 0); - assert_string_equal(body + rp, name); -@@ -936,6 +949,10 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - assert_int_equal(*(body + rp + sizeof(TEST2_KEY_ID) - 1), 0); - assert_string_equal(body + rp, TEST2_KEY_ID); - rp += sizeof(TEST2_KEY_ID); -+ -+ assert_int_equal(*(body + rp + sizeof(TEST2_SUBJECT_DN) - 1), 0); -+ assert_string_equal(body + rp, TEST2_SUBJECT_DN); -+ rp += sizeof(TEST2_SUBJECT_DN); - } - - assert_int_equal(rp, blen); --- -2.13.6 - diff --git a/SOURCES/0041-PAM-allow-missing-logon_name-during-certificate-auth.patch b/SOURCES/0041-PAM-allow-missing-logon_name-during-certificate-auth.patch deleted file mode 100644 index 669c063..0000000 --- a/SOURCES/0041-PAM-allow-missing-logon_name-during-certificate-auth.patch +++ /dev/null @@ -1,256 +0,0 @@ -From f6e57537cbeaf6e3f313e700f08e0022a32a7d6c Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 30 Oct 2017 17:11:56 +0100 -Subject: [PATCH 41/46] PAM: allow missing logon_name during certificate - authentication -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If only one certificate is available and the logon_name is the user is -not given the PAM responder already tried to find the name during the -pre-auth step. With multiple certificates this might cause useless extra -effort and the name should be determined after the certificate is -selected in the authentication step. This might currently only happen -with GDM because all other PAM clients will prompt for the user name -unconditionally. - -New unit tests are added to cover this new case. - -Related to https://pagure.io/SSSD/sssd/issue/3560 - -Reviewed-by: Fabiano Fidêncio -Tested-by: Scott Poore -(cherry picked from commit fd6f4047b58686bd4057c9859c3c804a77b136d8) ---- - src/responder/pam/pamsrv_cmd.c | 63 ++++++++++++++++++++++++++----- - src/tests/cmocka/test_pam_srv.c | 82 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 135 insertions(+), 10 deletions(-) - -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index 8b2c086e206796ad4c977495be957c56b3255e7f..caf6c99489b8378d2e850473191223709920cd79 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -1151,6 +1151,7 @@ static errno_t pam_forwarder_parse_data(struct cli_ctx *cctx, struct pam_data *p - size_t blen; - errno_t ret; - uint32_t terminator; -+ const char *key_id; - - prctx = talloc_get_type(cctx->protocol_ctx, struct cli_protocol); - -@@ -1191,9 +1192,33 @@ static errno_t pam_forwarder_parse_data(struct cli_ctx *cctx, struct pam_data *p - pd->logon_name, - &pd->domain, &pd->user); - } else { -- /* Only SSS_PAM_PREAUTH request may have a missing name, e.g. if the -- * name is determined with the help of a certificate */ -- if (pd->cmd == SSS_PAM_PREAUTH -+ /* SSS_PAM_PREAUTH request may have a missing name, e.g. if the -+ * name is determined with the help of a certificate. During -+ * SSS_PAM_AUTHENTICATE at least a key ID is needed to identify the -+ * selected certificate. */ -+ if (pd->cmd == SSS_PAM_AUTHENTICATE -+ && may_do_cert_auth(talloc_get_type(cctx->rctx->pvt_ctx, -+ struct pam_ctx), pd) -+ && (sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_SC_PIN -+ || sss_authtok_get_type(pd->authtok) -+ == SSS_AUTHTOK_TYPE_SC_KEYPAD)) { -+ ret = sss_authtok_get_sc(pd->authtok, NULL, NULL, NULL, NULL, NULL, -+ NULL, &key_id, NULL); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_sc failed.\n"); -+ goto done; -+ } -+ -+ if (key_id == NULL || *key_id == '\0') { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Missing logon and Smartcard key ID during " -+ "authentication.\n"); -+ ret = ERR_NO_CREDS; -+ goto done; -+ } -+ -+ ret = EOK; -+ } else if (pd->cmd == SSS_PAM_PREAUTH - && may_do_cert_auth(talloc_get_type(cctx->rctx->pvt_ctx, - struct pam_ctx), pd)) { - ret = EOK; -@@ -1375,9 +1400,12 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd) - /* Determine what domain type to contact */ - preq->req_dom_type = get_domain_request_type(preq, pctx); - -- /* try backend first for authentication before doing local Smartcard -- * authentication */ -- if (pd->cmd != SSS_PAM_AUTHENTICATE && may_do_cert_auth(pctx, pd)) { -+ /* Try backend first for authentication before doing local Smartcard -+ * authentication if a logon name is available. Otherwise try to derive -+ * the logon name from the certificate first. */ -+ if ((pd->cmd != SSS_PAM_AUTHENTICATE -+ || (pd->cmd == SSS_PAM_AUTHENTICATE && pd->logon_name == NULL)) -+ && may_do_cert_auth(pctx, pd)) { - ret = check_cert(cctx, cctx->ev, pctx, preq, pd); - /* Finish here */ - goto done; -@@ -1577,9 +1605,10 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - } else { - - if (preq->pd->logon_name == NULL) { -- if (preq->pd->cmd != SSS_PAM_PREAUTH) { -+ if (preq->pd->cmd != SSS_PAM_PREAUTH -+ && preq->pd->cmd != SSS_PAM_AUTHENTICATE) { - DEBUG(SSSDBG_CRIT_FAILURE, -- "Missing logon name only allowed during pre-auth.\n"); -+ "Missing logon name only allowed during (pre-)auth.\n"); - ret = ENOENT; - goto done; - } -@@ -1641,7 +1670,8 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - } - } - -- if (preq->cctx->rctx->domains->user_name_hint) { -+ if (preq->cctx->rctx->domains->user_name_hint -+ && preq->pd->cmd == SSS_PAM_PREAUTH) { - ret = add_pam_cert_response(preq->pd, cert_user, - preq->cert_list, - SSS_PAM_CERT_INFO_WITH_HINT); -@@ -1664,6 +1694,20 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req) - goto done; - } - -+ /* If logon_name was not given during authentication add a -+ * SSS_PAM_CERT_INFO message to send the name to the caller. */ -+ if (preq->pd->cmd == SSS_PAM_AUTHENTICATE -+ && preq->pd->logon_name == NULL) { -+ ret = add_pam_cert_response(preq->pd, cert_user, -+ preq->cert_list, -+ SSS_PAM_CERT_INFO); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "add_pam_cert_response failed.\n"); -+ preq->pd->pam_status = PAM_AUTHINFO_UNAVAIL; -+ goto done; -+ } -+ } -+ - /* cert_user will be returned to the PAM client as user name, so - * we can use it here already e.g. to set in initgroups timeout */ - preq->pd->logon_name = talloc_strdup(preq->pd, cert_user); -@@ -2039,7 +2083,6 @@ static void pam_dom_forwarder(struct pam_auth_req *preq) - "the backend.\n"); - } - -- /* FIXME: use the right cert info */ - ret = add_pam_cert_response(preq->pd, cert_user, - preq->current_cert, - SSS_PAM_CERT_INFO); -diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c -index 50d3ed005468375ff02c60bebd1c61047ca1c6d4..b6845320ca41d6933280aa2836a3d984dacfcc5e 100644 ---- a/src/tests/cmocka/test_pam_srv.c -+++ b/src/tests/cmocka/test_pam_srv.c -@@ -967,6 +967,16 @@ static int test_pam_cert_check(uint32_t status, uint8_t *body, size_t blen) - NULL); - } - -+static int test_pam_cert_check_auth_success(uint32_t status, uint8_t *body, -+ size_t blen) -+{ -+ assert_int_equal(pam_test_ctx->exp_pam_status, PAM_BAD_ITEM); -+ pam_test_ctx->exp_pam_status = PAM_SUCCESS; -+ return test_pam_cert_check_ex(status, body, blen, -+ SSS_PAM_CERT_INFO, "pamuser@"TEST_DOM_NAME, -+ NULL); -+} -+ - static int test_pam_cert_check_with_hint(uint32_t status, uint8_t *body, - size_t blen) - { -@@ -2265,6 +2275,74 @@ void test_pam_cert_auth(void **state) - assert_int_equal(ret, EOK); - } - -+void test_pam_cert_auth_no_logon_name(void **state) -+{ -+ int ret; -+ -+ set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); -+ -+ /* Here the last option must be set to true because the backend is only -+ * connected once. During authentication the backend is connected first to -+ * see if it can handle Smartcard authentication, but before that the user -+ * is looked up. Since the first mocked reply already adds the certificate -+ * to the user entry the lookup by certificate will already find the user -+ * in the cache and no second request to the backend is needed. */ -+ mock_input_pam_cert(pam_test_ctx, NULL, "123456", "SSSD Test Token", -+ "NSS-Internal", -+ "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7", NULL, -+ test_lookup_by_cert_cb, TEST_TOKEN_CERT, true); -+ -+ mock_account_recv_simple(); -+ mock_parse_inp("pamuser", NULL, EOK); -+ -+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ -+ /* Assume backend cannot handle Smartcard credentials */ -+ pam_test_ctx->exp_pam_status = PAM_BAD_ITEM; -+ -+ set_cmd_cb(test_pam_cert_check_auth_success); -+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, -+ pam_test_ctx->pam_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(pam_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+} -+ -+void test_pam_cert_auth_no_logon_name_no_key_id(void **state) -+{ -+ int ret; -+ -+ set_cert_auth_param(pam_test_ctx->pctx, NSS_DB); -+ -+ /* Here the last option must be set to true because the backend is only -+ * connected once. During authentication the backend is connected first to -+ * see if it can handle Smartcard authentication, but before that the user -+ * is looked up. Since the first mocked reply already adds the certificate -+ * to the user entry the lookup by certificate will already find the user -+ * in the cache and no second request to the backend is needed. */ -+ mock_input_pam_cert(pam_test_ctx, NULL, "123456", "SSSD Test Token", -+ "NSS-Internal", NULL, NULL, -+ NULL, NULL, false); -+ -+ will_return(__wrap_sss_packet_get_cmd, SSS_PAM_AUTHENTICATE); -+ will_return(__wrap_sss_packet_get_body, WRAP_CALL_REAL); -+ -+ /* Assume backend cannot handle Smartcard credentials */ -+ pam_test_ctx->exp_pam_status = PAM_BAD_ITEM; -+ -+ set_cmd_cb(test_pam_creds_insufficient_check); -+ ret = sss_cmd_execute(pam_test_ctx->cctx, SSS_PAM_AUTHENTICATE, -+ pam_test_ctx->pam_cmds); -+ assert_int_equal(ret, EOK); -+ -+ /* Wait until the test finishes with EOK */ -+ ret = test_ev_loop(pam_test_ctx->tctx); -+ assert_int_equal(ret, EOK); -+} -+ - void test_pam_cert_auth_double_cert(void **state) - { - int ret; -@@ -2770,6 +2848,10 @@ 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_no_logon_name, -+ pam_test_setup, pam_test_teardown), -+ cmocka_unit_test_setup_teardown(test_pam_cert_auth_no_logon_name_no_key_id, -+ pam_test_setup, pam_test_teardown), - #endif /* HAVE_NSS */ - - cmocka_unit_test_setup_teardown(test_filter_response, --- -2.13.6 - diff --git a/SOURCES/0041-Revert-CRYPTO-Suppress-warning-Wstringop-truncation.patch b/SOURCES/0041-Revert-CRYPTO-Suppress-warning-Wstringop-truncation.patch new file mode 100644 index 0000000..83f3206 --- /dev/null +++ b/SOURCES/0041-Revert-CRYPTO-Suppress-warning-Wstringop-truncation.patch @@ -0,0 +1,54 @@ +From 61227cf82d01ee42300ad7054bfd683536e15acb Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michal=20=C5=BDidek?= +Date: Fri, 27 Jul 2018 11:37:20 +0200 +Subject: [PATCH] Revert "CRYPTO: Suppress warning Wstringop-truncation" + +This reverts commit 2951a9a84bd85f384213a3e071ffc167907df2d7. + +The original use stpncpy was correct. Changing it to memcpy +changed the resulting hash. This resulted in users from +local domain to not be able to authenticate (offline +authentication was also probably broken) if their hash was +created before this change. + +https://pagure.io/SSSD/sssd/issue/3791 + +Reviewed-by: Jakub Hrozek + +DOWNSTREAM: +Resolves: rhbz#1602781 - Local users failed to login with same password +after upgrading to RHEL7.6 +--- + src/util/crypto/libcrypto/crypto_sha512crypt.c | 2 +- + src/util/crypto/nss/nss_sha512crypt.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/util/crypto/libcrypto/crypto_sha512crypt.c b/src/util/crypto/libcrypto/crypto_sha512crypt.c +index 5861f34b9325f7552491a07e8b85fe35ca5ae607..b074eee555fafac6e486bfdf9efb9ddf4964a990 100644 +--- a/src/util/crypto/libcrypto/crypto_sha512crypt.c ++++ b/src/util/crypto/libcrypto/crypto_sha512crypt.c +@@ -277,7 +277,7 @@ static int sha512_crypt_r(const char *key, + goto done; + } + +- cp = memcpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); ++ cp = stpncpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); + buflen -= SALT_PREF_SIZE; + + if (rounds_custom) { +diff --git a/src/util/crypto/nss/nss_sha512crypt.c b/src/util/crypto/nss/nss_sha512crypt.c +index 709cf51961bb7069ddebf3d636aa29b020756f0a..2f1624e6396c40f539a4e2034ab545cad8f05434 100644 +--- a/src/util/crypto/nss/nss_sha512crypt.c ++++ b/src/util/crypto/nss/nss_sha512crypt.c +@@ -267,7 +267,7 @@ static int sha512_crypt_r(const char *key, + goto done; + } + +- cp = memcpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); ++ cp = stpncpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); + buflen -= SALT_PREF_SIZE; + + if (rounds_custom) { +-- +2.14.4 + diff --git a/SOURCES/0042-Revert-Revert-CRYPTO-Suppress-warning-Wstringop-trun.patch b/SOURCES/0042-Revert-Revert-CRYPTO-Suppress-warning-Wstringop-trun.patch new file mode 100644 index 0000000..c9e72ef --- /dev/null +++ b/SOURCES/0042-Revert-Revert-CRYPTO-Suppress-warning-Wstringop-trun.patch @@ -0,0 +1,52 @@ +From 503172f46360b33170063b3bf75047990c644ed5 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Tue, 31 Jul 2018 20:43:37 +0000 +Subject: [PATCH] Revert "Revert "CRYPTO: Suppress warning + Wstringop-truncation"" + +This reverts commit bb20d5160faed5e0076887ac4a83e550be15a8b2. + +The patch introduced compile time warning +src/util/crypto/libcrypto/crypto_sha512crypt.c:280:10: error: 'stpncpy' + output truncated before terminating nul copying 3 bytes from a string + of the same length [-Werror=stringop-truncation] + cp = stpncpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Merges: https://pagure.io/SSSD/sssd/pull-request/3792 + +Reviewed-by: Jakub Hrozek +--- + src/util/crypto/libcrypto/crypto_sha512crypt.c | 2 +- + src/util/crypto/nss/nss_sha512crypt.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/util/crypto/libcrypto/crypto_sha512crypt.c b/src/util/crypto/libcrypto/crypto_sha512crypt.c +index b074eee555fafac6e486bfdf9efb9ddf4964a990..5861f34b9325f7552491a07e8b85fe35ca5ae607 100644 +--- a/src/util/crypto/libcrypto/crypto_sha512crypt.c ++++ b/src/util/crypto/libcrypto/crypto_sha512crypt.c +@@ -277,7 +277,7 @@ static int sha512_crypt_r(const char *key, + goto done; + } + +- cp = stpncpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); ++ cp = memcpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); + buflen -= SALT_PREF_SIZE; + + if (rounds_custom) { +diff --git a/src/util/crypto/nss/nss_sha512crypt.c b/src/util/crypto/nss/nss_sha512crypt.c +index 2f1624e6396c40f539a4e2034ab545cad8f05434..709cf51961bb7069ddebf3d636aa29b020756f0a 100644 +--- a/src/util/crypto/nss/nss_sha512crypt.c ++++ b/src/util/crypto/nss/nss_sha512crypt.c +@@ -267,7 +267,7 @@ static int sha512_crypt_r(const char *key, + goto done; + } + +- cp = stpncpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); ++ cp = memcpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); + buflen -= SALT_PREF_SIZE; + + if (rounds_custom) { +-- +2.14.4 + diff --git a/SOURCES/0042-p11_child-add-descriptions-for-error-codes-to-debug-.patch b/SOURCES/0042-p11_child-add-descriptions-for-error-codes-to-debug-.patch deleted file mode 100644 index 37350b5..0000000 --- a/SOURCES/0042-p11_child-add-descriptions-for-error-codes-to-debug-.patch +++ /dev/null @@ -1,276 +0,0 @@ -From aa476a78b67a60d4ca2433091268a7790b4d62f7 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 30 Oct 2017 10:22:33 +0100 -Subject: [PATCH 42/46] p11_child: add descriptions for error codes to debug - messages -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Additionally to the NSS erro code a text message describing the error is -added. This will help to see why p11_child ignores specific -certificates. For example it would be more obvious why the certificate -is not valid (expired, missing CA cert, failed OCSP etc). - -Related to https://pagure.io/SSSD/sssd/issue/3560 - -Reviewed-by: Fabiano Fidêncio -Tested-by: Scott Poore -(cherry picked from commit 08d1f8c0d6eece6a48201d7f8824b282eac3458d) ---- - src/p11_child/p11_child_nss.c | 91 ++++++++++++++++++++++++------------------- - 1 file changed, 50 insertions(+), 41 deletions(-) - -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index c676375cf7f6677a1d7f38f09b9bb5fd820d60c5..5f289688e41f4ea610292b907036e05cf95eb29d 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -75,15 +75,16 @@ static char *get_key_id_str(PK11SlotInfo *slot, CERTCertificate *cert) - key_id = PK11_GetLowLevelKeyIDForCert(slot, cert, NULL); - if (key_id == NULL) { - DEBUG(SSSDBG_OP_FAILURE, -- "PK11_GetLowLevelKeyIDForCert failed [%d].\n", -- PR_GetError()); -+ "PK11_GetLowLevelKeyIDForCert failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return NULL; - } - - key_id_str = CERT_Hexify(key_id, PR_FALSE); - SECITEM_FreeItem(key_id, PR_TRUE); - if (key_id_str == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d].\n", PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "CERT_Hexify failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return NULL; - } - -@@ -138,8 +139,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - - nss_ctx = NSS_InitContext(nss_db, "", "", SECMOD_DB, ¶meters, flags); - if (nss_ctx == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "NSS_InitContext failed [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "NSS_InitContext failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return EIO; - } - -@@ -232,8 +233,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - if (pin != NULL) { - rv = PK11_Authenticate(slot, PR_FALSE, discard_const(pin)); - if (rv != SECSuccess) { -- DEBUG(SSSDBG_OP_FAILURE, "PK11_Authenticate failed: [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "PK11_Authenticate failed: [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return EIO; - } - } else { -@@ -246,8 +247,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - - cert_list = PK11_ListCertsInSlot(slot); - if (cert_list == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "PK11_ListCertsInSlot failed: [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "PK11_ListCertsInSlot failed: [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return EIO; - } - -@@ -265,31 +266,33 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - - rv = CERT_FilterCertListByUsage(cert_list, certUsageSSLClient, PR_FALSE); - if (rv != SECSuccess) { -- DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListByUsage failed: [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListByUsage failed: [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return EIO; - } - - rv = CERT_FilterCertListForUserCerts(cert_list); - if (rv != SECSuccess) { -- DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListForUserCerts failed: [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, -+ "CERT_FilterCertListForUserCerts failed: [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return EIO; - } - - - handle = CERT_GetDefaultCertDB(); - if (handle == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "CERT_GetDefaultCertDB failed: [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "CERT_GetDefaultCertDB failed: [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return EIO; - } - - if (cert_verify_opts->do_ocsp) { - rv = CERT_EnableOCSPChecking(handle); - if (rv != SECSuccess) { -- DEBUG(SSSDBG_OP_FAILURE, "CERT_EnableOCSPChecking failed: [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, -+ "CERT_EnableOCSPChecking failed: [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return EIO; - } - -@@ -300,16 +303,16 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - cert_verify_opts->ocsp_default_responder_signing_cert); - if (rv != SECSuccess) { - DEBUG(SSSDBG_OP_FAILURE, -- "CERT_SetOCSPDefaultResponder failed: [%d].\n", -- PR_GetError()); -+ "CERT_SetOCSPDefaultResponder failed: [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return EIO; - } - - rv = CERT_EnableOCSPDefaultResponder(handle); - if (rv != SECSuccess) { - DEBUG(SSSDBG_OP_FAILURE, -- "CERT_EnableOCSPDefaultResponder failed: [%d].\n", -- PR_GetError()); -+ "CERT_EnableOCSPDefaultResponder failed: [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return EIO; - } - } -@@ -318,8 +321,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - found_cert = NULL; - valid_certs = CERT_NewCertList(); - if (valid_certs == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "CERT_NewCertList failed [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "CERT_NewCertList failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - ret = ENOMEM; - goto done; - } -@@ -345,9 +348,10 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - NULL, NULL); - if (rv != SECSuccess) { - DEBUG(SSSDBG_OP_FAILURE, -- "Certificate [%s][%s] not valid [%d], skipping.\n", -+ "Certificate [%s][%s] not valid [%d][%s], skipping.\n", - cert_list_node->cert->nickname, -- cert_list_node->cert->subjectName, PR_GetError()); -+ cert_list_node->cert->subjectName, -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - continue; - } - } -@@ -386,7 +390,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - rv = CERT_AddCertToListTail(valid_certs, cert_list_node->cert); - if (rv != SECSuccess) { - DEBUG(SSSDBG_OP_FAILURE, -- "CERT_AddCertToListTail failed [%d].\n", PR_GetError()); -+ "CERT_AddCertToListTail failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - ret = EIO; - goto done; - } -@@ -400,8 +405,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - rv = CERT_DisableOCSPDefaultResponder(handle); - if (rv != SECSuccess) { - DEBUG(SSSDBG_OP_FAILURE, -- "CERT_DisableOCSPDefaultResponder failed: [%d].\n", -- PR_GetError()); -+ "CERT_DisableOCSPDefaultResponder failed: [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - } - } - -@@ -433,15 +438,17 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - rv = PK11_GenerateRandom(random_value, sizeof(random_value)); - if (rv != SECSuccess) { - DEBUG(SSSDBG_OP_FAILURE, -- "PK11_GenerateRandom failed [%d].\n", PR_GetError()); -+ "PK11_GenerateRandom failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - return EIO; - } - - priv_key = PK11_FindPrivateKeyFromCert(slot, found_cert, NULL); - if (priv_key == NULL) { - DEBUG(SSSDBG_OP_FAILURE, -- "PK11_FindPrivateKeyFromCert failed [%d]." \ -- "Maybe pin is missing.\n", PR_GetError()); -+ "PK11_FindPrivateKeyFromCert failed [%d][%s]." -+ "Maybe pin is missing.\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - ret = EIO; - goto done; - } -@@ -451,8 +458,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - if (algtag == SEC_OID_UNKNOWN) { - SECKEY_DestroyPrivateKey(priv_key); - DEBUG(SSSDBG_OP_FAILURE, -- "SEC_GetSignatureAlgorithmOidTag failed [%d].\n", -- PR_GetError()); -+ "SEC_GetSignatureAlgorithmOidTag failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - ret = EIO; - goto done; - } -@@ -462,8 +469,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - priv_key, algtag); - SECKEY_DestroyPrivateKey(priv_key); - if (rv != SECSuccess) { -- DEBUG(SSSDBG_OP_FAILURE, "SEC_SignData failed [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "SEC_SignData failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - ret = EIO; - goto done; - } -@@ -471,7 +478,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - pub_key = CERT_ExtractPublicKey(found_cert); - if (pub_key == NULL) { - DEBUG(SSSDBG_OP_FAILURE, -- "CERT_ExtractPublicKey failed [%d].\n", PR_GetError()); -+ "CERT_ExtractPublicKey failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - ret = EIO; - goto done; - } -@@ -481,8 +489,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - NULL); - SECKEY_DestroyPublicKey(pub_key); - if (rv != SECSuccess) { -- DEBUG(SSSDBG_OP_FAILURE, "VFY_VerifyData failed [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "VFY_VerifyData failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - ret = EACCES; - goto done; - } -@@ -507,7 +515,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - PORT_Free(key_id_str); - key_id_str = get_key_id_str(slot, found_cert); - if (key_id_str == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "get_key_id_str [%d].\n", PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "get_key_id_str [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - ret = ENOMEM; - goto done; - } -@@ -562,8 +571,8 @@ done: - - rv = NSS_ShutdownContext(nss_ctx); - if (rv != SECSuccess) { -- DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d].\n", -- PR_GetError()); -+ DEBUG(SSSDBG_OP_FAILURE, "NSS_ShutdownContext failed [%d][%s].\n", -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); - } - - return ret; --- -2.13.6 - diff --git a/SOURCES/0043-CRYPTO-Save-prefix-in-s3crypt_sha512.patch b/SOURCES/0043-CRYPTO-Save-prefix-in-s3crypt_sha512.patch new file mode 100644 index 0000000..fea39ee --- /dev/null +++ b/SOURCES/0043-CRYPTO-Save-prefix-in-s3crypt_sha512.patch @@ -0,0 +1,48 @@ +From 62cfc6d28b770f56fcb103eeed32e961d3531f3d Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Tue, 31 Jul 2018 20:44:06 +0000 +Subject: [PATCH] CRYPTO: Save prefix in s3crypt_sha512 + +Since commit 2951a9a84bd85f384213a3e071ffc167907df2d7 where we switched from +stpncpy to memcpy the salt prefix "$6$" is not stored at all. +This broke offline authentication if someone upgraded from old version +that stored the prefix to one that doesn't store it. + +Resolves: +https://pagure.io/SSSD/sssd/issue/3791 + +Merges: https://pagure.io/SSSD/sssd/pull-request/3792 + +Reviewed-by: Jakub Hrozek +--- + src/util/crypto/libcrypto/crypto_sha512crypt.c | 1 + + src/util/crypto/nss/nss_sha512crypt.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/src/util/crypto/libcrypto/crypto_sha512crypt.c b/src/util/crypto/libcrypto/crypto_sha512crypt.c +index 5861f34b9325f7552491a07e8b85fe35ca5ae607..2275ccd96212b28984e47c128ba2acb233b865d0 100644 +--- a/src/util/crypto/libcrypto/crypto_sha512crypt.c ++++ b/src/util/crypto/libcrypto/crypto_sha512crypt.c +@@ -278,6 +278,7 @@ static int sha512_crypt_r(const char *key, + } + + cp = memcpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); ++ cp += SALT_PREF_SIZE; + buflen -= SALT_PREF_SIZE; + + if (rounds_custom) { +diff --git a/src/util/crypto/nss/nss_sha512crypt.c b/src/util/crypto/nss/nss_sha512crypt.c +index 709cf51961bb7069ddebf3d636aa29b020756f0a..4d0594d9f21f0fe4228037901c6792625bd4f7c6 100644 +--- a/src/util/crypto/nss/nss_sha512crypt.c ++++ b/src/util/crypto/nss/nss_sha512crypt.c +@@ -268,6 +268,7 @@ static int sha512_crypt_r(const char *key, + } + + cp = memcpy(buffer, sha512_salt_prefix, SALT_PREF_SIZE); ++ cp += SALT_PREF_SIZE; + buflen -= SALT_PREF_SIZE; + + if (rounds_custom) { +-- +2.14.4 + diff --git a/SOURCES/0043-pam-filter-certificates-in-the-responder-not-in-the-.patch b/SOURCES/0043-pam-filter-certificates-in-the-responder-not-in-the-.patch deleted file mode 100644 index ac52d99..0000000 --- a/SOURCES/0043-pam-filter-certificates-in-the-responder-not-in-the-.patch +++ /dev/null @@ -1,357 +0,0 @@ -From 69c820abacd963a3699fc9ea84a17bb99f9eaf3a Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 6 Nov 2017 15:26:38 +0100 -Subject: [PATCH 43/46] pam: filter certificates in the responder not in the - child -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With the new selection option and the handling of multiple certificates -in the PAM responder it is not needed anymore to filter the certificates -in p11_child but the matching rules can be applied by the PAM responder -directly. - -Related to https://pagure.io/SSSD/sssd/issue/3560 - -Reviewed-by: Fabiano Fidêncio -Tested-by: Scott Poore -(cherry picked from commit 177ab84f0e336b75289a3ac0b2df25bd5ab5198b) ---- - src/p11_child/p11_child_nss.c | 18 +----- - src/responder/pam/pamsrv.h | 6 ++ - src/responder/pam/pamsrv_cmd.c | 10 ++- - src/responder/pam/pamsrv_p11.c | 135 +++++++++++++++++++++++++++++++++++++++- - src/tests/cmocka/test_pam_srv.c | 3 + - 5 files changed, 152 insertions(+), 20 deletions(-) - -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index 5f289688e41f4ea610292b907036e05cf95eb29d..e59aba0d1561f58206252f7251ecd88315836b1b 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -264,22 +264,6 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - } - } - -- rv = CERT_FilterCertListByUsage(cert_list, certUsageSSLClient, PR_FALSE); -- if (rv != SECSuccess) { -- DEBUG(SSSDBG_OP_FAILURE, "CERT_FilterCertListByUsage failed: [%d][%s].\n", -- PR_GetError(), PORT_ErrorToString(PR_GetError())); -- return EIO; -- } -- -- rv = CERT_FilterCertListForUserCerts(cert_list); -- if (rv != SECSuccess) { -- DEBUG(SSSDBG_OP_FAILURE, -- "CERT_FilterCertListForUserCerts failed: [%d][%s].\n", -- PR_GetError(), PORT_ErrorToString(PR_GetError())); -- return EIO; -- } -- -- - handle = CERT_GetDefaultCertDB(); - if (handle == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "CERT_GetDefaultCertDB failed: [%d][%s].\n", -@@ -344,7 +328,7 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - if (cert_verify_opts->do_verification) { - rv = CERT_VerifyCertificateNow(handle, cert_list_node->cert, - PR_TRUE, -- certificateUsageSSLClient, -+ certificateUsageCheckAllUsages, - NULL, NULL); - if (rv != SECSuccess) { - DEBUG(SSSDBG_OP_FAILURE, -diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h -index f15f7f19f1f38626288416c9f2038371c6f58b47..0bc229212844602ed461d1c7db48bf51ac2e2194 100644 ---- a/src/responder/pam/pamsrv.h -+++ b/src/responder/pam/pamsrv.h -@@ -27,6 +27,7 @@ - #include "sbus/sssd_dbus.h" - #include "responder/common/responder.h" - #include "responder/common/cache_req/cache_req.h" -+#include "lib/certmap/sss_certmap.h" - - struct pam_auth_req; - -@@ -49,6 +50,7 @@ struct pam_ctx { - bool cert_auth; - int p11_child_debug_fd; - char *nss_db; -+ struct sss_certmap_ctx *sss_certmap_ctx; - }; - - struct pam_auth_dp_req { -@@ -104,6 +106,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - const char *nss_db, - time_t timeout, - const char *verify_opts, -+ struct sss_certmap_ctx *sss_certmap_ctx, - struct pam_data *pd); - errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct cert_auth_info **cert_list); -@@ -114,6 +117,9 @@ errno_t add_pam_cert_response(struct pam_data *pd, const char *sysdb_username, - - bool may_do_cert_auth(struct pam_ctx *pctx, struct pam_data *pd); - -+errno_t p11_refresh_certmap_ctx(struct pam_ctx *pctx, -+ struct certmap_info **certmap_list); -+ - errno_t - pam_set_last_online_auth_with_curr_token(struct sss_domain_info *domain, - const char *username, -diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c -index caf6c99489b8378d2e850473191223709920cd79..0e76c9e772f1775635677f35b870e9613b2faf64 100644 ---- a/src/responder/pam/pamsrv_cmd.c -+++ b/src/responder/pam/pamsrv_cmd.c -@@ -1336,7 +1336,8 @@ static errno_t check_cert(TALLOC_CTX *mctx, - - req = pam_check_cert_send(mctx, ev, pctx->p11_child_debug_fd, - pctx->nss_db, p11_child_timeout, -- cert_verification_opts, pd); -+ cert_verification_opts, pctx->sss_certmap_ctx, -+ pd); - if (req == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "pam_check_cert_send failed.\n"); - return ENOMEM; -@@ -1749,6 +1750,13 @@ static void pam_forwarder_cb(struct tevent_req *req) - goto done; - } - -+ ret = p11_refresh_certmap_ctx(pctx, pctx->rctx->domains->certmaps); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "p11_refresh_certmap_ctx failed, " -+ "certificate matching might not work as expected"); -+ } -+ - pd = preq->pd; - - ret = pam_forwarder_parse_data(cctx, pd); -diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c -index 5a3eeff0ec977829a9ad8c80b4fc6b2e06857097..ec52c5ae7163d41144fe082643a201b766a1e201 100644 ---- a/src/responder/pam/pamsrv_p11.c -+++ b/src/responder/pam/pamsrv_p11.c -@@ -36,6 +36,7 @@ - - #define P11_CHILD_LOG_FILE "p11_child" - #define P11_CHILD_PATH SSSD_LIBEXEC_PATH"/p11_child" -+#define CERT_AUTH_DEFAULT_MATCHING_RULE "KRB5:clientAuth" - - struct cert_auth_info { - char *cert; -@@ -116,8 +117,110 @@ void sss_cai_check_users(struct cert_auth_info **list, size_t *_cert_count, - return; - } - -+struct priv_sss_debug { -+ int level; -+}; -+ -+static void ext_debug(void *private, const char *file, long line, -+ const char *function, const char *format, ...) -+{ -+ va_list ap; -+ struct priv_sss_debug *data = private; -+ int level = SSSDBG_OP_FAILURE; -+ -+ if (data != NULL) { -+ level = data->level; -+ } -+ -+ if (DEBUG_IS_SET(level)) { -+ va_start(ap, format); -+ sss_vdebug_fn(file, line, function, level, APPEND_LINE_FEED, -+ format, ap); -+ va_end(ap); -+ } -+} -+ -+errno_t p11_refresh_certmap_ctx(struct pam_ctx *pctx, -+ struct certmap_info **certmap_list) -+{ -+ int ret; -+ struct sss_certmap_ctx *sss_certmap_ctx = NULL; -+ size_t c; -+ -+ ret = sss_certmap_init(pctx, ext_debug, NULL, &sss_certmap_ctx); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_init failed.\n"); -+ goto done; -+ } -+ -+ if (certmap_list == NULL || *certmap_list == NULL) { -+ /* Try to add default matching rule */ -+ ret = sss_certmap_add_rule(sss_certmap_ctx, SSS_CERTMAP_MIN_PRIO, -+ CERT_AUTH_DEFAULT_MATCHING_RULE, NULL, NULL); -+ if (ret != 0) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to add default matching rule.\n"); -+ } -+ -+ goto done; -+ } -+ -+ for (c = 0; certmap_list[c] != NULL; c++) { -+ DEBUG(SSSDBG_TRACE_ALL, -+ "Trying to add rule [%s][%d][%s][%s].\n", -+ certmap_list[c]->name, certmap_list[c]->priority, -+ certmap_list[c]->match_rule, certmap_list[c]->map_rule); -+ -+ ret = sss_certmap_add_rule(sss_certmap_ctx, certmap_list[c]->priority, -+ certmap_list[c]->match_rule, -+ certmap_list[c]->map_rule, -+ certmap_list[c]->domains); -+ if (ret != 0) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "sss_certmap_add_rule failed for rule [%s] " -+ "with error [%d][%s], skipping. " -+ "Please check for typos and if rule syntax is supported.\n", -+ certmap_list[c]->name, ret, sss_strerror(ret)); -+ continue; -+ } -+ } -+ -+ ret = EOK; -+ -+done: -+ if (ret == EOK) { -+ sss_certmap_free_ctx(pctx->sss_certmap_ctx); -+ pctx->sss_certmap_ctx = sss_certmap_ctx; -+ } else { -+ sss_certmap_free_ctx(sss_certmap_ctx); -+ } -+ -+ return ret; -+} -+ - errno_t p11_child_init(struct pam_ctx *pctx) - { -+ int ret; -+ struct certmap_info **certmaps; -+ bool user_name_hint; -+ struct sss_domain_info *dom = pctx->rctx->domains; -+ -+ ret = sysdb_get_certmap(dom, dom->sysdb, &certmaps, &user_name_hint); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_get_certmap failed.\n"); -+ return ret; -+ } -+ -+ dom->user_name_hint = user_name_hint; -+ talloc_free(dom->certmaps); -+ dom->certmaps = certmaps; -+ -+ ret = p11_refresh_certmap_ctx(pctx, dom->certmaps); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "p11_refresh_certmap_ctx failed.\n"); -+ return ret; -+ } -+ - return child_debug_init(P11_CHILD_LOG_FILE, &pctx->p11_child_debug_fd); - } - -@@ -214,6 +317,7 @@ static errno_t get_p11_child_write_buffer(TALLOC_CTX *mem_ctx, - - static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, - ssize_t buf_len, -+ struct sss_certmap_ctx *sss_certmap_ctx, - struct cert_auth_info **_cert_list) - { - int ret; -@@ -222,6 +326,8 @@ static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, - uint8_t *pn; - struct cert_auth_info *cert_list = NULL; - struct cert_auth_info *cert_auth_info; -+ unsigned char *der = NULL; -+ size_t der_size; - - if (buf_len < 0) { - DEBUG(SSSDBG_CRIT_FAILURE, -@@ -347,7 +453,22 @@ static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, - } - DEBUG(SSSDBG_TRACE_ALL, "Found cert [%s].\n", cert_auth_info->cert); - -- DLIST_ADD(cert_list, cert_auth_info); -+ der = sss_base64_decode(tmp_ctx, cert_auth_info->cert, &der_size); -+ if (der == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n"); -+ ret = EIO; -+ goto done; -+ } -+ -+ ret = sss_certmap_match_cert(sss_certmap_ctx, der, der_size); -+ if (ret == 0) { -+ DLIST_ADD(cert_list, cert_auth_info); -+ } else { -+ DEBUG(SSSDBG_TRACE_LIBS, -+ "Cert [%s] does not match matching rules and is ignored.\n", -+ cert_auth_info->cert); -+ talloc_free(cert_auth_info); -+ } - - p = ++pn; - } while ((pn - buf) < buf_len); -@@ -373,6 +494,7 @@ struct pam_check_cert_state { - struct sss_child_ctx_old *child_ctx; - struct tevent_timer *timeout_handler; - struct tevent_context *ev; -+ struct sss_certmap_ctx *sss_certmap_ctx; - - struct child_io_fds *io; - -@@ -391,6 +513,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - const char *nss_db, - time_t timeout, - const char *verify_opts, -+ struct sss_certmap_ctx *sss_certmap_ctx, - struct pam_data *pd) - { - errno_t ret; -@@ -420,6 +543,12 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - goto done; - } - -+ if (sss_certmap_ctx == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing certificate matching context.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ - /* extra_args are added in revers order */ - arg_c = 0; - extra_args[arg_c++] = nss_db; -@@ -476,6 +605,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx, - } - - state->ev = ev; -+ state->sss_certmap_ctx = sss_certmap_ctx; - state->child_status = EFAULT; - state->io = talloc(state, struct child_io_fds); - if (state->io == NULL) { -@@ -639,7 +769,8 @@ static void p11_child_done(struct tevent_req *subreq) - - PIPE_FD_CLOSE(state->io->read_from_child_fd); - -- ret = parse_p11_child_response(state, buf, buf_len, &state->cert_list); -+ ret = parse_p11_child_response(state, buf, buf_len, state->sss_certmap_ctx, -+ &state->cert_list); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "parse_p11_child_response failed.\n"); - tevent_req_error(req, ret); -diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c -index b6845320ca41d6933280aa2836a3d984dacfcc5e..bccf9972dacbb414076904a783772198620fd73c 100644 ---- a/src/tests/cmocka/test_pam_srv.c -+++ b/src/tests/cmocka/test_pam_srv.c -@@ -287,6 +287,9 @@ struct pam_ctx *mock_pctx(TALLOC_CTX *mem_ctx) - return NULL; - } - -+ ret = p11_refresh_certmap_ctx(pctx, NULL); -+ assert_int_equal(ret, 0); -+ - return pctx; - } - --- -2.13.6 - diff --git a/SOURCES/0044-PAM-add-certificate-s-label-to-the-selection-prompt.patch b/SOURCES/0044-PAM-add-certificate-s-label-to-the-selection-prompt.patch deleted file mode 100644 index 4ec3f7b..0000000 --- a/SOURCES/0044-PAM-add-certificate-s-label-to-the-selection-prompt.patch +++ /dev/null @@ -1,274 +0,0 @@ -From 35790511fd43b0c33f3b410b20a31e007b3e5d20 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 7 Nov 2017 09:52:56 +0100 -Subject: [PATCH 44/46] PAM: add certificate's label to the selection prompt -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some types of Smartcards contain multiple certificate with the same -subject-DN for different usages. To make it easier to choose between -them in case the matching rules allow more than one of them for -authentication the label assigned to the certificate on the Smartcard is -shown in the selection prompt as well. - -Related to https://pagure.io/SSSD/sssd/issue/3560 - -Reviewed-by: Fabiano Fidêncio -Tested-by: Scott Poore -(cherry picked from commit 57cefea8305a57c1c0491afb739813b7f17d5a25) ---- - src/p11_child/p11_child_nss.c | 18 ++++++++++++++---- - src/responder/pam/pamsrv.h | 1 + - src/responder/pam/pamsrv_p11.c | 41 +++++++++++++++++++++++++++++++++++++---- - src/tests/cmocka/test_pam_srv.c | 28 ++++++++++++++-------------- - 4 files changed, 66 insertions(+), 22 deletions(-) - -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index e59aba0d1561f58206252f7251ecd88315836b1b..21c508eb1b1b68b3606d0a5eed36573b01f27a19 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -130,7 +130,7 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - CERTCertificate *found_cert = NULL; - PK11SlotList *list = NULL; - PK11SlotListElement *le; -- SECItem *key_id = NULL; -+ const char *label; - char *key_id_str = NULL; - CERTCertList *valid_certs = NULL; - char *cert_b64 = NULL; -@@ -505,6 +505,17 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - goto done; - } - -+ /* The NSS nickname is typically token_name:label, so the label starts -+ * after the ':'. */ -+ if (found_cert->nickname != NULL) { -+ if ((label = strchr(found_cert->nickname, ':')) == NULL) { -+ label = found_cert->nickname; -+ } else { -+ label++; -+ } -+ } else { -+ label = "- no label found -"; -+ } - talloc_free(cert_b64); - cert_b64 = sss_base64_encode(mem_ctx, found_cert->derCert.data, - found_cert->derCert.len); -@@ -517,9 +528,9 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n", - key_id_str); - -- multi = talloc_asprintf_append(multi, "%s\n%s\n%s\n%s\n", -+ multi = talloc_asprintf_append(multi, "%s\n%s\n%s\n%s\n%s\n", - token_name, module_name, key_id_str, -- cert_b64); -+ label, cert_b64); - } - *_multi = multi; - -@@ -546,7 +557,6 @@ done: - CERT_DestroyCertList(cert_list); - } - -- SECITEM_FreeItem(key_id, PR_TRUE); - PORT_Free(key_id_str); - - PORT_Free(signed_random_value.data); -diff --git a/src/responder/pam/pamsrv.h b/src/responder/pam/pamsrv.h -index 0bc229212844602ed461d1c7db48bf51ac2e2194..dfd982178446d6327e09afc652018886c08fd88a 100644 ---- a/src/responder/pam/pamsrv.h -+++ b/src/responder/pam/pamsrv.h -@@ -93,6 +93,7 @@ const char *sss_cai_get_cert(struct cert_auth_info *i); - const char *sss_cai_get_token_name(struct cert_auth_info *i); - const char *sss_cai_get_module_name(struct cert_auth_info *i); - const char *sss_cai_get_key_id(struct cert_auth_info *i); -+const char *sss_cai_get_label(struct cert_auth_info *i); - struct cert_auth_info *sss_cai_get_next(struct cert_auth_info *i); - struct ldb_result *sss_cai_get_cert_user_objs(struct cert_auth_info *i); - void sss_cai_set_cert_user_objs(struct cert_auth_info *i, -diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c -index ec52c5ae7163d41144fe082643a201b766a1e201..fa2435543ea305f7cdb1e18753525beb373eaf4c 100644 ---- a/src/responder/pam/pamsrv_p11.c -+++ b/src/responder/pam/pamsrv_p11.c -@@ -43,6 +43,7 @@ struct cert_auth_info { - char *token_name; - char *module_name; - char *key_id; -+ char *label; - struct ldb_result *cert_user_objs; - struct cert_auth_info *prev; - struct cert_auth_info *next; -@@ -68,6 +69,11 @@ const char *sss_cai_get_key_id(struct cert_auth_info *i) - return i != NULL ? i->key_id : NULL; - } - -+const char *sss_cai_get_label(struct cert_auth_info *i) -+{ -+ return i != NULL ? i->label : NULL; -+} -+ - struct cert_auth_info *sss_cai_get_next(struct cert_auth_info *i) - { - return i != NULL ? i->next : NULL; -@@ -439,6 +445,31 @@ static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf, - } - - if (pn == p) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Missing label in p11_child response.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ cert_auth_info->label = talloc_strndup(cert_auth_info, (char *) p, -+ (pn - p)); -+ if (cert_auth_info->label == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strndup failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ DEBUG(SSSDBG_TRACE_ALL, "Found label [%s].\n", cert_auth_info->label); -+ -+ p = ++pn; -+ pn = memchr(p, '\n', buf_len - (p - buf)); -+ if (pn == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Missing new-line in p11_child response.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ if (pn == p) { - DEBUG(SSSDBG_OP_FAILURE, "Missing cert in p11_child response.\n"); - ret = EINVAL; - goto done; -@@ -816,7 +847,8 @@ errno_t pam_check_cert_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - return EOK; - } - --static char *get_cert_prompt(TALLOC_CTX *mem_ctx, const char *cert) -+static char *get_cert_prompt(TALLOC_CTX *mem_ctx, -+ struct cert_auth_info *cert_info) - { - int ret; - struct sss_certmap_ctx *ctx = NULL; -@@ -839,7 +871,7 @@ static char *get_cert_prompt(TALLOC_CTX *mem_ctx, const char *cert) - goto done; - } - -- der = sss_base64_decode(mem_ctx, cert, &der_size); -+ der = sss_base64_decode(mem_ctx, sss_cai_get_cert(cert_info), &der_size); - if (der == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n"); - goto done; -@@ -851,7 +883,8 @@ static char *get_cert_prompt(TALLOC_CTX *mem_ctx, const char *cert) - goto done; - } - -- prompt = talloc_strdup(mem_ctx, filter); -+ prompt = talloc_asprintf(mem_ctx, "%s\n%s", sss_cai_get_label(cert_info), -+ filter); - if (prompt == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); - } -@@ -885,7 +918,7 @@ static errno_t pack_cert_data(TALLOC_CTX *mem_ctx, const char *sysdb_username, - username = sysdb_username; - } - -- prompt = get_cert_prompt(mem_ctx, sss_cai_get_cert(cert_info)); -+ prompt = get_cert_prompt(mem_ctx, cert_info); - if (prompt == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "get_cert_prompt failed.\n"); - return EIO; -diff --git a/src/tests/cmocka/test_pam_srv.c b/src/tests/cmocka/test_pam_srv.c -index bccf9972dacbb414076904a783772198620fd73c..4752648796ab4c863706780a2f470853cddbcc11 100644 ---- a/src/tests/cmocka/test_pam_srv.c -+++ b/src/tests/cmocka/test_pam_srv.c -@@ -53,7 +53,7 @@ - #define TEST_TOKEN_NAME "SSSD Test Token" - #define TEST_MODULE_NAME "NSS-Internal" - #define TEST_KEY_ID "A5EF7DEE625CA5996C8D1BA7D036708161FD49E7" --#define TEST_SUBJECT_DN "CN=ipa-devel.ipa.devel,O=IPA.DEVEL" -+#define TEST_PROMPT "Server-Cert\nCN=ipa-devel.ipa.devel,O=IPA.DEVEL" - #define TEST_TOKEN_CERT \ - "MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \ - "REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA1MjMx" \ -@@ -79,7 +79,7 @@ - "XyQBwOYRORlnfGyu+Yc9c3E0Wx8Tlznz0lqPR9g=" - - #define TEST2_KEY_ID "C8D60E009EB195D01A7083EE1D5419251AA87C2C" --#define TEST2_SUBJECT_DN "CN=IPA RA,O=IPA.DEVEL" -+#define TEST2_PROMPT "ipaCert\nCN=IPA RA,O=IPA.DEVEL" - #define TEST_TOKEN_2ND_CERT \ - "MIIDazCCAlOgAwIBAgIBBzANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \ - "REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNjA1MjMx" \ -@@ -837,7 +837,7 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body, - + sizeof(TEST_TOKEN_NAME) - + sizeof(TEST_MODULE_NAME) - + sizeof(TEST_KEY_ID) -- + sizeof(TEST_SUBJECT_DN))); -+ + sizeof(TEST_PROMPT))); - - assert_int_equal(*(body + rp + sizeof("pamuser@"TEST_DOM_NAME) - 1), 0); - assert_string_equal(body + rp, "pamuser@"TEST_DOM_NAME); -@@ -855,9 +855,9 @@ static int test_pam_cert_check_gdm_smartcard(uint32_t status, uint8_t *body, - assert_string_equal(body + rp, TEST_KEY_ID); - rp += sizeof(TEST_KEY_ID); - -- assert_int_equal(*(body + rp + sizeof(TEST_SUBJECT_DN) - 1), 0); -- assert_string_equal(body + rp, TEST_SUBJECT_DN); -- rp += sizeof(TEST_SUBJECT_DN); -+ assert_int_equal(*(body + rp + sizeof(TEST_PROMPT) - 1), 0); -+ assert_string_equal(body + rp, TEST_PROMPT); -+ rp += sizeof(TEST_PROMPT); - - assert_int_equal(rp, blen); - return EOK; -@@ -904,7 +904,7 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - + sizeof(TEST_TOKEN_NAME) - + sizeof(TEST_MODULE_NAME) - + sizeof(TEST_KEY_ID) -- + sizeof(TEST_SUBJECT_DN))); -+ + sizeof(TEST_PROMPT))); - - assert_int_equal(*(body + rp + strlen(name)), 0); - assert_string_equal(body + rp, name); -@@ -922,9 +922,9 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - assert_string_equal(body + rp, TEST_KEY_ID); - rp += sizeof(TEST_KEY_ID); - -- assert_int_equal(*(body + rp + sizeof(TEST_SUBJECT_DN) - 1), 0); -- assert_string_equal(body + rp, TEST_SUBJECT_DN); -- rp += sizeof(TEST_SUBJECT_DN); -+ assert_int_equal(*(body + rp + sizeof(TEST_PROMPT) - 1), 0); -+ assert_string_equal(body + rp, TEST_PROMPT); -+ rp += sizeof(TEST_PROMPT); - - if (name2 != NULL && *name2 != '\0') { - SAFEALIGN_COPY_UINT32(&val, body + rp, &rp); -@@ -935,7 +935,7 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - + sizeof(TEST_TOKEN_NAME) - + sizeof(TEST_MODULE_NAME) - + sizeof(TEST2_KEY_ID) -- + sizeof(TEST2_SUBJECT_DN))); -+ + sizeof(TEST2_PROMPT))); - - assert_int_equal(*(body + rp + strlen(name)), 0); - assert_string_equal(body + rp, name); -@@ -953,9 +953,9 @@ static int test_pam_cert_check_ex(uint32_t status, uint8_t *body, size_t blen, - assert_string_equal(body + rp, TEST2_KEY_ID); - rp += sizeof(TEST2_KEY_ID); - -- assert_int_equal(*(body + rp + sizeof(TEST2_SUBJECT_DN) - 1), 0); -- assert_string_equal(body + rp, TEST2_SUBJECT_DN); -- rp += sizeof(TEST2_SUBJECT_DN); -+ assert_int_equal(*(body + rp + sizeof(TEST2_PROMPT) - 1), 0); -+ assert_string_equal(body + rp, TEST2_PROMPT); -+ rp += sizeof(TEST2_PROMPT); - } - - assert_int_equal(rp, blen); --- -2.13.6 - diff --git a/SOURCES/0044-crypto-tests-Add-unit-test-for-s3crypt_sha512.patch b/SOURCES/0044-crypto-tests-Add-unit-test-for-s3crypt_sha512.patch new file mode 100644 index 0000000..b88bc1a --- /dev/null +++ b/SOURCES/0044-crypto-tests-Add-unit-test-for-s3crypt_sha512.patch @@ -0,0 +1,68 @@ +From f0d437220d5c76f6b09dee5c5744397549fc3813 Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Tue, 31 Jul 2018 20:44:16 +0000 +Subject: [PATCH] crypto-tests: Add unit test for s3crypt_sha512 + +Resolves: +https://pagure.io/SSSD/sssd/issue/3791 + +Merges: https://pagure.io/SSSD/sssd/pull-request/3792 + +Reviewed-by: Jakub Hrozek +--- + src/tests/crypto-tests.c | 32 ++++++++++++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + +diff --git a/src/tests/crypto-tests.c b/src/tests/crypto-tests.c +index 2e826a41b3c1302b87c7136cc37b7c4df02a0584..6f5e22a878ad9e40b73b23915d08395b3f6f2e3d 100644 +--- a/src/tests/crypto-tests.c ++++ b/src/tests/crypto-tests.c +@@ -201,6 +201,37 @@ START_TEST(test_sss_encrypt_decrypt) + } + END_TEST + ++START_TEST(test_s3crypt_sha512) ++{ ++ int ret; ++ char *salt; ++ char *userhash; ++ char *comphash; ++ const char *password = "password123"; ++ const char *expected_hash = "$6$tU67Q/9h3tm5WJ.U$aL9gjCfiSZQewHTI6A4/MHCVWrMCiJZ.gNXEIw6HO39XGbg.s2nTyGlYXeoQyQtDll3XSbIZN41fJEC3v7ELy0"; ++ ++ test_ctx = talloc_new(NULL); ++ fail_if(test_ctx == NULL); ++ ++ ret = s3crypt_gen_salt(test_ctx, &salt); ++ fail_if(ret != 0); ++ ++ ret = s3crypt_sha512(test_ctx, password, salt, &userhash); ++ fail_if(ret != 0); ++ ++ ret = s3crypt_sha512(test_ctx, password, userhash, &comphash); ++ fail_if(ret != 0); ++ ck_assert_str_eq(userhash, comphash); ++ talloc_free(comphash); ++ ++ ret = s3crypt_sha512(test_ctx, password, expected_hash, &comphash); ++ fail_if(ret != 0); ++ ck_assert_str_eq(expected_hash, comphash); ++ ++ talloc_free(test_ctx); ++} ++END_TEST ++ + Suite *crypto_suite(void) + { + Suite *s = suite_create("sss_crypto"); +@@ -216,6 +247,7 @@ Suite *crypto_suite(void) + tcase_add_test(tc, test_base64_encode); + tcase_add_test(tc, test_base64_decode); + tcase_add_test(tc, test_sss_encrypt_decrypt); ++ tcase_add_test(tc, test_s3crypt_sha512); + /* Add all test cases to the test suite */ + suite_add_tcase(s, tc); + +-- +2.14.4 + diff --git a/SOURCES/0045-SSS_CERT-Close-file-descriptors-after-executing-p11_.patch b/SOURCES/0045-SSS_CERT-Close-file-descriptors-after-executing-p11_.patch new file mode 100644 index 0000000..8eb4a97 --- /dev/null +++ b/SOURCES/0045-SSS_CERT-Close-file-descriptors-after-executing-p11_.patch @@ -0,0 +1,44 @@ +From a195869e527df27451bee8b68108abd005976b2d Mon Sep 17 00:00:00 2001 +From: Lukas Slebodnik +Date: Tue, 31 Jul 2018 21:03:38 +0000 +Subject: [PATCH] SSS_CERT: Close file descriptors after executing p11_child + +We can call cert_to_ssh_key_step from cert_to_ssh_key_done and thus +p11_child can be executed more time. We created pipes for each call +but destructor for state->io can close just last one. + +It's better to manually close pipes with macro PIPE_FD_CLOSE. +that macro set file descriptor to -1 and destructor will not try +to close them 2nd time. Destructor will cover just edge cases. + +Merges: https://pagure.io/SSSD/sssd/pull-request/3793 + +Resolves: +https://pagure.io/SSSD/sssd/issue/3794 + +Reviewed-by: Jakub Hrozek +(cherry picked from commit a76f96ac143128c11bdb975293d667aca861cd91) + +DOWNSTREAM: +Resolves: rhbz#1610667 - sssd_ssh leaks file descriptors when more than one certificate is converted into an SSH key +--- + src/util/cert/cert_common_p11_child.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/util/cert/cert_common_p11_child.c b/src/util/cert/cert_common_p11_child.c +index 17e97eeeeb1956ca6d2bbf048445117029b10dde..aacdb5c475274234fd18d5eca23ee5f9c9288c3e 100644 +--- a/src/util/cert/cert_common_p11_child.c ++++ b/src/util/cert/cert_common_p11_child.c +@@ -255,6 +255,9 @@ static void cert_to_ssh_key_done(int child_status, + int ret; + bool valid = false; + ++ PIPE_FD_CLOSE(state->io->read_from_child_fd); ++ PIPE_FD_CLOSE(state->io->write_to_child_fd); ++ + if (WIFEXITED(child_status)) { + if (WEXITSTATUS(child_status) != 0) { + DEBUG(SSSDBG_OP_FAILURE, +-- +2.17.1 + diff --git a/SOURCES/0045-SYSDB-Remove-code-causing-a-covscan-warning.patch b/SOURCES/0045-SYSDB-Remove-code-causing-a-covscan-warning.patch deleted file mode 100644 index c2e1d8c..0000000 --- a/SOURCES/0045-SYSDB-Remove-code-causing-a-covscan-warning.patch +++ /dev/null @@ -1,128 +0,0 @@ -From 075f45980ea004201b2d13a3ecfe3bfb1478046d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= -Date: Mon, 13 Nov 2017 08:29:53 +0100 -Subject: [PATCH 45/46] SYSDB: Remove code causing a covscan warning -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There's no reason to check for both ret != EOK and sanitized == NULL, as -the second should never ever happen. - -This check is causing a clang warning in our code: - - Defect type: CLANG_WARNING - 1. sssd-1.16.0/src/db/sysdb_ops.c:4223:9: warning: Dereference of undefined pointer value - # if (res->count > 1) { - # ^~~~~~~~~~ - 4. sssd-1.16.0/src/db/sysdb_ops.c:4199:5: note: 'res' declared without an initial value - # struct ldb_result *res; - # ^~~~~~~~~~~~~~~~~~~~~~ - 7. sssd-1.16.0/src/db/sysdb_ops.c:4202:9: note: Assuming 'sid_str' is non-null - # if (!sid_str) return EINVAL; - # ^~~~~~~~ - 10. sssd-1.16.0/src/db/sysdb_ops.c:4202:5: note: Taking false branch - # if (!sid_str) return EINVAL; - # ^ - 13. sssd-1.16.0/src/db/sysdb_ops.c:4205:9: note: Assuming 'tmp_ctx' is non-null - # if (!tmp_ctx) { - # ^~~~~~~~ - 16. sssd-1.16.0/src/db/sysdb_ops.c:4205:5: note: Taking false branch - # if (!tmp_ctx) { - # ^ - 19. sssd-1.16.0/src/db/sysdb_ops.c:4209:11: note: Calling 'sysdb_search_object_by_sid' - # ret = sysdb_search_object_by_sid(tmp_ctx, domain, sid_str, NULL, &res); - # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 22. sssd-1.16.0/src/db/sysdb_ops.c:4960:12: note: Calling 'sysdb_search_object_by_str_attr' - # return sysdb_search_object_by_str_attr(mem_ctx, domain, SYSDB_SID_FILTER, - # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 25. sssd-1.16.0/src/db/sysdb_ops.c:4872:5: note: Taking false branch - # if (str == NULL) { - # ^ - 28. sssd-1.16.0/src/db/sysdb_ops.c:4877:9: note: Assuming 'ret' is equal to 0 - # if (ret != EOK || sanitized == NULL) { - # ^~~~~~~~~~ - 31. sssd-1.16.0/src/db/sysdb_ops.c:4877:9: note: Left side of '||' is false - 32. sssd-1.16.0/src/db/sysdb_ops.c:4877:23: note: Assuming 'sanitized' is equal to null - # if (ret != EOK || sanitized == NULL) { - # ^~~~~~~~~~~~~~~~~ - 35. sssd-1.16.0/src/db/sysdb_ops.c:4877:5: note: Taking true branch - # if (ret != EOK || sanitized == NULL) { - # ^ - 38. sssd-1.16.0/src/db/sysdb_ops.c:4878:9: note: Left side of '||' is false - # DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize failed.\n"); - # ^ - 41. sssd-1.16.0/src/util/debug.h:123:9: note: expanded from macro 'DEBUG' - # if (DEBUG_IS_SET(__debug_macro_level)) { \ - # ^ - 44. sssd-1.16.0/src/util/debug.h:135:30: note: expanded from macro 'DEBUG_IS_SET' - # #define DEBUG_IS_SET(level) (debug_level & (level) || \ - # ^ - 47. sssd-1.16.0/src/db/sysdb_ops.c:4878:9: note: Assuming 'debug_level' is not equal to 0 - # DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize failed.\n"); - # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 50. sssd-1.16.0/src/util/debug.h:123:9: note: expanded from macro 'DEBUG' - # if (DEBUG_IS_SET(__debug_macro_level)) { \ - # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 53. sssd-1.16.0/src/util/debug.h:136:30: note: expanded from macro 'DEBUG_IS_SET' - # (debug_level == SSSDBG_UNRESOLVED && \ - # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 56. sssd-1.16.0/src/db/sysdb_ops.c:4878:9: note: Left side of '&&' is false - 57. sssd-1.16.0/src/util/debug.h:123:9: note: expanded from macro 'DEBUG' - # if (DEBUG_IS_SET(__debug_macro_level)) { \ - # ^ - 60. sssd-1.16.0/src/util/debug.h:136:63: note: expanded from macro 'DEBUG_IS_SET' - # (debug_level == SSSDBG_UNRESOLVED && \ - # ^ - 63. sssd-1.16.0/src/db/sysdb_ops.c:4878:9: note: Loop condition is false. Exiting loop - 64. sssd-1.16.0/src/util/debug.h:121:35: note: expanded from macro 'DEBUG' - # #define DEBUG(level, format, ...) do { \ - # ^ - 67. sssd-1.16.0/src/db/sysdb_ops.c:4879:9: note: Control jumps to line 4892 - # goto done; - # ^ - 70. sssd-1.16.0/src/db/sysdb_ops.c:4960:12: note: Returning from 'sysdb_search_object_by_str_attr' - # return sysdb_search_object_by_str_attr(mem_ctx, domain, SYSDB_SID_FILTER, - # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 73. sssd-1.16.0/src/db/sysdb_ops.c:4209:11: note: Returning from 'sysdb_search_object_by_sid' - # ret = sysdb_search_object_by_sid(tmp_ctx, domain, sid_str, NULL, &res); - # ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 76. sssd-1.16.0/src/db/sysdb_ops.c:4211:5: note: Taking false branch - # if (ret == ENOENT) { - # ^ - 79. sssd-1.16.0/src/db/sysdb_ops.c:4217:12: note: Taking false branch - # } else if (ret != EOK) { - # ^ - 82. sssd-1.16.0/src/db/sysdb_ops.c:4223:9: note: Dereference of undefined pointer value - # if (res->count > 1) { - # ^~~~~~~~~~ - # 4221| } - # 4222| - # 4223|-> if (res->count > 1) { - # 4224| DEBUG(SSSDBG_FATAL_FAILURE, "getbysid call returned more than one " \ - # 4225| "result !?!\n"); - -Signed-off-by: Fabiano Fidêncio - -Reviewed-by: Pavel Březina -(cherry picked from commit b739b3e767c053bb3a7e6651514896b30502d838) ---- - src/db/sysdb_ops.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c -index 2f8e36c6c9a2c2cefe4af5fb78957763304d989a..635c7db51f516e2217c93016409499e49289004c 100644 ---- a/src/db/sysdb_ops.c -+++ b/src/db/sysdb_ops.c -@@ -4874,7 +4874,7 @@ static errno_t sysdb_search_object_by_str_attr(TALLOC_CTX *mem_ctx, - } - - ret = sss_filter_sanitize(NULL, str, &sanitized); -- if (ret != EOK || sanitized == NULL) { -+ if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sss_filter_sanitize failed.\n"); - goto done; - } --- -2.13.6 - diff --git a/SOURCES/0046-SELINUX-Also-call-is_selinux_enabled-as-a-check-for-.patch b/SOURCES/0046-SELINUX-Also-call-is_selinux_enabled-as-a-check-for-.patch new file mode 100644 index 0000000..7665629 --- /dev/null +++ b/SOURCES/0046-SELINUX-Also-call-is_selinux_enabled-as-a-check-for-.patch @@ -0,0 +1,60 @@ +From 663fdd3897c5da1a54fcb51613bd71660ef9b19a Mon Sep 17 00:00:00 2001 +From: Jakub Hrozek +Date: Wed, 20 Jun 2018 22:02:57 +0200 +Subject: [PATCH] SELINUX: Also call is_selinux_enabled as a check for selinux + child +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Resolves: +https://pagure.io/SSSD/sssd/issue/3796 + +The SSSD selinux management routines were only checking if SELinux is +managed on the system. If it is managed, the code tries to proceed and +set the login context, otherwise an error is returned which SSSD handles +gracefully. + +But this is not enough, in some cases SELinux might be disabled, but +managed and in these cases SSSD was returning strange errors, which +might have prevented login with selinux provider in effect. + +We got this hint form the RH SELinux maintainer: +""" +libsemanage is for managing SELinux infrastructure. generally if there's +/etc/selinux/config where libsemanage can read SELINUXTYPE and SELinux +module store - /etc/selinux//active (or +/var/lib/selinux//active) - is available, libsemanage can +manage it even when SELinux is disabled. + +I'm not sure if selinux_child doesn any is_selinux_enabled() checks but +it could help to avoid such situations. +""" + +Reviewed-by: Fabiano Fidêncio +(cherry picked from commit 1e81d040c75b2b15cab48fb7df1041138747e6c3) + +DOWNSTREAM: +Resolves: rhbz#1583360 - The IPA selinux provider can return an error if SELinux is completely disabled +--- + src/util/sss_semanage.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c +index 7b0eef22330db8df6ab8f46da5fb76c68f6adabc..bcce57b603bd1c4d5c6465dbb5cc7a3fbe72412d 100644 +--- a/src/util/sss_semanage.c ++++ b/src/util/sss_semanage.c +@@ -82,6 +82,10 @@ static int sss_is_selinux_managed(semanage_handle_t *handle) + return EINVAL; + } + ++ if (!is_selinux_enabled()) { ++ return ERR_SELINUX_NOT_MANAGED; ++ } ++ + ret = semanage_is_managed(handle); + if (ret == 0) { + DEBUG(SSSDBG_TRACE_FUNC, "SELinux policy not managed via libsemanage\n"); +-- +2.17.1 + diff --git a/SOURCES/0046-SYSDB-Better-debugging-for-email-conflicts.patch b/SOURCES/0046-SYSDB-Better-debugging-for-email-conflicts.patch deleted file mode 100644 index 283ef2a..0000000 --- a/SOURCES/0046-SYSDB-Better-debugging-for-email-conflicts.patch +++ /dev/null @@ -1,94 +0,0 @@ -From de3b178ada423c10c8f14194a64c299ad96e7bf1 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michal=20=C5=BDidek?= -Date: Thu, 26 Oct 2017 18:38:42 +0200 -Subject: [PATCH 46/46] SYSDB: Better debugging for email conflicts -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add DEBUG message when conflicts in FQ names or emails -are detected. - -Also improve man page to hint on how to work around issue -with conflicting emails. - -Note: We store emails in two different attributes in sysdb: -- SYSDB_USER_EMAIL -- SYSDB_NAME_ALIAS - this one is lowercased and used in getpwnam - searches. - -Resolves: -https://fedorahosted.org/sssd/ticket/3293 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 39d6a3be119b050b0690152b6b443117c8617b1c) ---- - src/db/sysdb_ops.c | 4 +++- - src/db/sysdb_search.c | 15 +++++++++++++++ - src/man/sssd-ldap.5.xml | 9 +++++++++ - 3 files changed, 27 insertions(+), 1 deletion(-) - -diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c -index 635c7db51f516e2217c93016409499e49289004c..1539c41c93e7d6ebd1e544abbb1707df5578cd72 100644 ---- a/src/db/sysdb_ops.c -+++ b/src/db/sysdb_ops.c -@@ -640,7 +640,9 @@ int sysdb_search_user_by_upn_res(TALLOC_CTX *mem_ctx, - goto done; - } else if (res->count > 1) { - DEBUG(SSSDBG_OP_FAILURE, -- "Search for upn [%s] returns more than one result.\n", upn); -+ "Search for upn [%s] returns more than one result. One of the " -+ "possible reasons can be that several users share the same " -+ "email address.\n", upn); - ret = EINVAL; - goto done; - } -diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c -index f488442afcc6eef114437a7110722759f86fe19e..8083966900429b268a3b984f1cad3d47d1099198 100644 ---- a/src/db/sysdb_search.c -+++ b/src/db/sysdb_search.c -@@ -218,6 +218,21 @@ int sysdb_getpwnam(TALLOC_CTX *mem_ctx, - goto done; - } - -+ if (res->count > 1) { -+ /* We expected either 0 or 1 result for search with -+ * SYSDB_PWNAM_FILTER, but we got more. This error -+ * is handled individually depending on what function -+ * called sysdb_getpwnam, so we just print a message -+ * here and let the caller decide what error code to -+ * propagate based on res->count > 1. */ -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Search for [%s] returned multiple results. It can be an email " -+ "address shared among multiple users or an email address of a " -+ "user that conflicts with another user's fully qualified name. " -+ "SSSD will not be able to handle those users properly.\n", -+ sanitized_name); -+ } -+ - /* Merge in the timestamps from the fast ts db */ - ret = sysdb_merge_res_ts_attrs(domain->sysdb, res, attrs); - if (ret != EOK) { -diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml -index d38bac3607d294c53ea692130a6b93ced9b0ab82..de596f0da62be9eb61b880b6e1d4a0f33689e25a 100644 ---- a/src/man/sssd-ldap.5.xml -+++ b/src/man/sssd-ldap.5.xml -@@ -878,6 +878,15 @@ - address of the user. - - -+ Note: If an email address of a user conflicts with -+ an email address or fully qualified name of another -+ user, then SSSD will not be able to serve those -+ users properly. If for some reason several users -+ need to share the same email address then set -+ this option to a nonexistent attribute name in -+ order to disable user lookup/login by email. -+ -+ - Default: mail - - --- -2.13.6 - diff --git a/SOURCES/0047-NSS-Use-enum_ctx-as-memory_context-in-_setnetgrent_s.patch b/SOURCES/0047-NSS-Use-enum_ctx-as-memory_context-in-_setnetgrent_s.patch deleted file mode 100644 index 28b8715..0000000 --- a/SOURCES/0047-NSS-Use-enum_ctx-as-memory_context-in-_setnetgrent_s.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 3b4479b63ae812c1ef355c1c697caddd882b1b8f Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 6 Nov 2017 17:03:19 +0100 -Subject: [PATCH 47/47] NSS: Use enum_ctx as memory_context in - _setnetgrent_set_timeout() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -We've noticed some crashes that happened because enum_ctx is already -freed, but the timeout handler is still called. In order to avoid that, -let's remove the timeout handler when enum_ctx is freed at other places. - -Resolves: https://pagure.io/SSSD/sssd/issue/3523 - -Signed-off-by: Fabiano Fidêncio - -Reviewed-by: Pavel Březina -(cherry picked from commit f6a1cef87abdd983d6b5349cd341c9a249826577) ---- - src/responder/nss/nss_enum.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/responder/nss/nss_enum.c b/src/responder/nss/nss_enum.c -index aa7d8428f37e943a6b5904495c40ad4b8011b767..da844fbced529f606a3e98669fb7b95e0696ce00 100644 ---- a/src/responder/nss/nss_enum.c -+++ b/src/responder/nss/nss_enum.c -@@ -283,7 +283,7 @@ nss_setnetgrent_set_timeout(struct tevent_context *ev, - timeout = enum_ctx->result[0]->domain->netgroup_timeout; - - tv = tevent_timeval_current_ofs(timeout, 0); -- te = tevent_add_timer(ev, nss_ctx, tv, nss_setnetgrent_timeout, enum_ctx); -+ te = tevent_add_timer(ev, enum_ctx, tv, nss_setnetgrent_timeout, enum_ctx); - if (te == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, - "Could not set up life timer for enumeration object.\n"); --- -2.13.6 - diff --git a/SOURCES/0048-TOOLS-Add-a-new-sssctl-command-access-report.patch b/SOURCES/0048-TOOLS-Add-a-new-sssctl-command-access-report.patch deleted file mode 100644 index 5788df9..0000000 --- a/SOURCES/0048-TOOLS-Add-a-new-sssctl-command-access-report.patch +++ /dev/null @@ -1,504 +0,0 @@ -From 73a04a5c53c0e7701aa7753fd459ffbea52e28b8 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 23 Oct 2017 18:08:12 +0200 -Subject: [PATCH 48/57] TOOLS: Add a new sssctl command access-report -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Resolves: -https://pagure.io/SSSD/sssd/issue/2840 - -Reviewed-by: Pavel Březina -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 3ee8659bc6a77a78bc6c61b9650a36bd18ea95c8) ---- - Makefile.am | 1 + - src/tools/sssctl/sssctl.c | 1 + - src/tools/sssctl/sssctl.h | 5 + - src/tools/sssctl/sssctl_access_report.c | 435 ++++++++++++++++++++++++++++++++ - 4 files changed, 442 insertions(+) - create mode 100644 src/tools/sssctl/sssctl_access_report.c - -diff --git a/Makefile.am b/Makefile.am -index 16bcb4efc028b05c1196249245f4f3091b9366af..5917bd904054055a259eb69217282e4fb914c700 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -1754,6 +1754,7 @@ sssctl_SOURCES = \ - src/tools/sssctl/sssctl_sifp.c \ - src/tools/sssctl/sssctl_config.c \ - src/tools/sssctl/sssctl_user_checks.c \ -+ src/tools/sssctl/sssctl_access_report.c \ - $(SSSD_TOOLS_OBJ) \ - $(NULL) - sssctl_LDADD = \ -diff --git a/src/tools/sssctl/sssctl.c b/src/tools/sssctl/sssctl.c -index 1e061c00d2238bf34adff4183e560dc127dd62c7..eee2d613966a5dda81627d2e225bfdc9bade4041 100644 ---- a/src/tools/sssctl/sssctl.c -+++ b/src/tools/sssctl/sssctl.c -@@ -264,6 +264,7 @@ int main(int argc, const char **argv) - SSS_TOOL_COMMAND("domain-list", "List available domains", 0, sssctl_domain_list), - SSS_TOOL_COMMAND("domain-status", "Print information about domain", 0, sssctl_domain_status), - SSS_TOOL_COMMAND("user-checks", "Print information about a user and check authentication", 0, sssctl_user_checks), -+ SSS_TOOL_COMMAND("access-report", "Generate access report for a domain", 0, sssctl_access_report), - SSS_TOOL_DELIMITER("Information about cached content:"), - SSS_TOOL_COMMAND("user-show", "Information about cached user", 0, sssctl_user_show), - SSS_TOOL_COMMAND("group-show", "Information about cached group", 0, sssctl_group_show), -diff --git a/src/tools/sssctl/sssctl.h b/src/tools/sssctl/sssctl.h -index 22ca5d41e2c084e64b58bc5aa066414b002e7e8b..70fc19eff07317c264978a1ecb9159ae3acdfced 100644 ---- a/src/tools/sssctl/sssctl.h -+++ b/src/tools/sssctl/sssctl.h -@@ -133,4 +133,9 @@ errno_t sssctl_config_check(struct sss_cmdline *cmdline, - errno_t sssctl_user_checks(struct sss_cmdline *cmdline, - struct sss_tool_ctx *tool_ctx, - void *pvt); -+ -+errno_t sssctl_access_report(struct sss_cmdline *cmdline, -+ struct sss_tool_ctx *tool_ctx, -+ void *pvt); -+ - #endif /* _SSSCTL_H_ */ -diff --git a/src/tools/sssctl/sssctl_access_report.c b/src/tools/sssctl/sssctl_access_report.c -new file mode 100644 -index 0000000000000000000000000000000000000000..11172329817b4dedaca480ab8a4537149853c330 ---- /dev/null -+++ b/src/tools/sssctl/sssctl_access_report.c -@@ -0,0 +1,435 @@ -+/* -+ Copyright (C) 2017 Red Hat -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU Lesser General Public License as published by -+ the Free Software Foundation; either version 3 of the License, or -+ (at your option) any later version. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU Lesser General Public License for more details. -+ -+ You should have received a copy of the GNU Lesser General Public License -+ along with this program. If not, see . -+*/ -+ -+#include -+ -+#include "util/util.h" -+#include "tools/common/sss_tools.h" -+#include "tools/sssctl/sssctl.h" -+ -+/* -+ * We're searching the cache directly.. -+ */ -+#include "providers/ipa/ipa_hbac_private.h" -+#include "providers/ipa/ipa_rules_common.h" -+ -+#ifdef HAVE_SECURITY_PAM_MISC_H -+# include -+#elif defined(HAVE_SECURITY_OPENPAM_H) -+# include -+#endif -+ -+#ifdef HAVE_SECURITY_PAM_MISC_H -+static struct pam_conv conv = { -+ misc_conv, -+ NULL -+}; -+#elif defined(HAVE_SECURITY_OPENPAM_H) -+static struct pam_conv conv = { -+ openpam_ttyconv, -+ NULL -+}; -+#else -+# error "Missing text based pam conversation function" -+#endif -+ -+#ifndef DEFAULT_SERVICE -+#define DEFAULT_SERVICE "system-auth" -+#endif /* DEFAULT_SERVICE */ -+ -+#ifndef DEFAULT_USER -+#define DEFAULT_USER "admin" -+#endif /* DEFAULT_USER */ -+ -+typedef errno_t (*sssctl_dom_access_reporter_fn)(struct sss_tool_ctx *tool_ctx, -+ const char *user, -+ const char *service, -+ struct sss_domain_info *domain); -+ -+static errno_t run_pam_acct(struct sss_tool_ctx *tool_ctx, -+ const char *user, -+ const char *service, -+ struct sss_domain_info *domain) -+{ -+ errno_t ret; -+ pam_handle_t *pamh; -+ -+ ret = pam_start(service, user, &conv, &pamh); -+ if (ret != PAM_SUCCESS) { -+ ERROR("pam_start failed: %s\n", pam_strerror(pamh, ret)); -+ return EIO; -+ } -+ -+ ret = pam_acct_mgmt(pamh, 0); -+ pam_end(pamh, ret); -+ return ret; -+} -+ -+static errno_t get_rdn_value(TALLOC_CTX *mem_ctx, -+ struct sss_domain_info *dom, -+ const char *dn_attr, -+ const char **_rdn_value) -+{ -+ errno_t ret; -+ TALLOC_CTX *tmp_ctx; -+ struct ldb_dn *dn = NULL; -+ const struct ldb_val *rdn_val; -+ const char *rdn_str; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ return ENOMEM; -+ } -+ -+ dn = ldb_dn_new(tmp_ctx, sysdb_ctx_get_ldb(dom->sysdb), dn_attr); -+ if (dn == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ rdn_val = ldb_dn_get_rdn_val(dn); -+ if (rdn_val == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "No RDN value?\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ rdn_str = talloc_strndup(tmp_ctx, -+ (const char *)rdn_val->data, -+ rdn_val->length); -+ if (rdn_str == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = EOK; -+ *_rdn_value = talloc_steal(mem_ctx, rdn_str); -+done: -+ talloc_zfree(tmp_ctx); -+ return ret; -+} -+ -+static errno_t is_member_group(struct sss_domain_info *dom, -+ const char *dn_attr, -+ const char *group_rdn, -+ bool *_is_group) -+{ -+ const char *comp_name; -+ const struct ldb_val *comp_val; -+ TALLOC_CTX *tmp_ctx; -+ bool is_group = false; -+ errno_t ret; -+ struct ldb_dn *dn = NULL; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ return ENOMEM; -+ } -+ -+ dn = ldb_dn_new(tmp_ctx, sysdb_ctx_get_ldb(dom->sysdb), dn_attr); -+ if (dn == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ comp_name = ldb_dn_get_component_name(dn, 1); -+ comp_val = ldb_dn_get_component_val(dn, 1); -+ if (strcasecmp("cn", comp_name) == 0 -+ && strncasecmp(group_rdn, -+ (const char *) comp_val->data, -+ comp_val->length) == 0) { -+ is_group = true; -+ } -+ -+ ret = EOK; -+done: -+ *_is_group = is_group; -+ talloc_zfree(tmp_ctx); -+ return ret; -+} -+ -+static void print_category(struct sss_domain_info *domain, -+ struct ldb_message *rule_msg, -+ const char *category_attr_name, -+ const char *category_label) -+{ -+ struct ldb_message_element *category_attr; -+ -+ category_attr = ldb_msg_find_element(rule_msg, category_attr_name); -+ if (category_attr == NULL) { -+ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot find %s\n", category_attr_name); -+ return; -+ } -+ -+ if (category_attr->num_values > 0) { -+ PRINT("\t%s: ", category_label); -+ for (unsigned i = 0; i < category_attr->num_values; i++) { -+ PRINT("%s%s", -+ i > 0 ? ", " : "", -+ (const char *) category_attr->values[i].data); -+ } -+ PRINT("\n"); -+ } -+} -+ -+static void print_member_attr(struct sss_domain_info *domain, -+ struct ldb_message *rule_msg, -+ const char *member_attr_name, -+ const char *group_rdn, -+ const char *object_label, -+ const char *group_label) -+{ -+ errno_t ret; -+ TALLOC_CTX *tmp_ctx = NULL; -+ const char **member_names = NULL; -+ size_t name_count = 0; -+ const char **member_group_names = NULL; -+ size_t group_count = 0; -+ struct ldb_message_element *member_attr = NULL; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ return; -+ } -+ -+ member_attr = ldb_msg_find_element(rule_msg, member_attr_name); -+ if (member_attr == NULL) { -+ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot find %s\n", member_attr_name); -+ goto done; -+ } -+ -+ member_names = talloc_zero_array(tmp_ctx, -+ const char *, -+ member_attr->num_values + 1); -+ member_group_names = talloc_zero_array(tmp_ctx, -+ const char *, -+ member_attr->num_values + 1); -+ if (member_names == NULL || member_group_names == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "OOM?\n"); -+ goto done; -+ } -+ -+ for (size_t i = 0; i < member_attr->num_values; i++) { -+ bool is_group; -+ const char *rdn_string; -+ const char *dn_attr; -+ -+ dn_attr = (const char *) member_attr->values[i].data; -+ -+ ret = is_member_group(domain, dn_attr, group_rdn, &is_group); -+ if (ret != EOK) { -+ continue; -+ } -+ -+ ret = get_rdn_value(tmp_ctx, domain, dn_attr, &rdn_string); -+ if (ret != EOK) { -+ continue; -+ } -+ -+ if (is_group == false) { -+ member_names[name_count] = talloc_steal(member_names, -+ rdn_string); -+ if (member_names[name_count] == NULL) { -+ goto done; -+ } -+ name_count++; -+ } else { -+ member_group_names[group_count] = talloc_strdup(member_group_names, -+ rdn_string); -+ if (member_group_names[group_count] == NULL) { -+ goto done; -+ } -+ group_count++; -+ } -+ } -+ -+ if (member_names[0] != NULL) { -+ PRINT("\t%s: ", object_label); -+ for (int i = 0; member_names[i]; i++) { -+ PRINT("%s%s", i > 0 ? ", " : "", member_names[i]); -+ } -+ PRINT("\n"); -+ } -+ -+ if (member_group_names[0] != NULL) { -+ PRINT("\t%s: ", group_label); -+ for (int i = 0; member_group_names[i]; i++) { -+ PRINT("%s%s", i > 0 ? ", " : "", member_group_names[i]); -+ } -+ PRINT("\n"); -+ } -+ -+done: -+ talloc_free(tmp_ctx); -+} -+ -+static void print_ipa_hbac_rule(struct sss_domain_info *domain, -+ struct ldb_message *rule_msg) -+{ -+ struct ldb_message_element *el; -+ -+ el = ldb_msg_find_element(rule_msg, IPA_CN); -+ if (el == NULL || el->num_values < 1) { -+ DEBUG(SSSDBG_MINOR_FAILURE, "A rule with no name\n"); -+ return; -+ } -+ -+ PRINT("Rule name: %1$s\n", el->values[0].data); -+ -+ print_member_attr(domain, -+ rule_msg, -+ IPA_MEMBER_USER, -+ "groups", -+ _("Member users"), -+ _("Member groups")); -+ print_category(domain, -+ rule_msg, -+ IPA_USER_CATEGORY, -+ _("User category")); -+ -+ print_member_attr(domain, -+ rule_msg, -+ IPA_MEMBER_SERVICE, -+ "hbacservicegroups", -+ _("Member services"), -+ _("Member service groups")); -+ print_category(domain, -+ rule_msg, -+ IPA_SERVICE_CATEGORY, -+ _("Service category")); -+ -+ PRINT("\n"); -+} -+ -+static errno_t sssctl_ipa_access_report(struct sss_tool_ctx *tool_ctx, -+ const char *user, -+ const char *service, -+ struct sss_domain_info *domain) -+{ -+ TALLOC_CTX *tmp_ctx = NULL; -+ const char *filter = NULL; -+ errno_t ret; -+ const char *attrs[] = { -+ OBJECTCLASS, -+ IPA_CN, -+ IPA_MEMBER_USER, -+ IPA_USER_CATEGORY, -+ IPA_MEMBER_SERVICE, -+ IPA_SERVICE_CATEGORY, -+ IPA_MEMBER_HOST, -+ IPA_HOST_CATEGORY, -+ NULL, -+ }; -+ size_t rule_count; -+ struct ldb_message **msgs = NULL; -+ -+ /* Run the pam account phase to make sure the rules are fetched by SSSD */ -+ ret = run_pam_acct(tool_ctx, user, service, domain); -+ if (ret != PAM_SUCCESS && ret != PAM_PERM_DENIED) { -+ ERROR("Cannot run the PAM account phase, reporting stale rules\n"); -+ /* Non-fatal */ -+ } -+ -+ tmp_ctx = talloc_new(tool_ctx); -+ if (tmp_ctx == NULL) { -+ return ENOMEM; -+ } -+ -+ filter = talloc_asprintf(tmp_ctx, "(objectClass=%s)", IPA_HBAC_RULE); -+ if (filter == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = sysdb_search_custom(tmp_ctx, domain, filter, -+ HBAC_RULES_SUBDIR, attrs, -+ &rule_count, &msgs); -+ if (ret != EOK && ret != ENOENT) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up HBAC rules\n"); -+ goto done; -+ } -+ -+ if (ret == ENOENT) { -+ PRINT("No cached rules. All users will be denied access\n"); -+ ret = EOK; -+ goto done; -+ } -+ -+ PRINT("%1$zu rules cached\n\n", rule_count); -+ -+ for (size_t i = 0; i < rule_count; i++) { -+ print_ipa_hbac_rule(domain, msgs[i]); -+ } -+ -+ ret = EOK; -+done: -+ talloc_zfree(tmp_ctx); -+ return ret; -+} -+ -+sssctl_dom_access_reporter_fn get_report_fn(const char *provider) -+{ -+ if (strcmp(provider, "ipa") == 0) { -+ return sssctl_ipa_access_report; -+ } -+ -+ return NULL; -+} -+ -+errno_t sssctl_access_report(struct sss_cmdline *cmdline, -+ struct sss_tool_ctx *tool_ctx, -+ void *pvt) -+{ -+ errno_t ret; -+ const char *domname = NULL; -+ sssctl_dom_access_reporter_fn reporter; -+ struct sss_domain_info *dom; -+ const char *user = DEFAULT_USER; -+ const char *service = DEFAULT_SERVICE; -+ -+ /* Parse command line. */ -+ struct poptOption options[] = { -+ { "user", 'u', POPT_ARG_STRING, &user, 0, -+ _("PAM user, default: " DEFAULT_USER), NULL }, -+ { "service", 's', POPT_ARG_STRING, &service, 0, -+ _("PAM service, default: " DEFAULT_SERVICE), NULL }, -+ POPT_TABLEEND -+ }; -+ -+ ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL, -+ NULL, NULL, "DOMAIN", _("Specify domain name."), -+ &domname, NULL); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse command arguments\n"); -+ return ret; -+ } -+ -+ dom = find_domain_by_name(tool_ctx->domains, domname, true); -+ if (dom == NULL) { -+ ERROR("Cannot find domain %1$s\n", domname); -+ return ERR_DOMAIN_NOT_FOUND; -+ } -+ -+ reporter = get_report_fn(dom->provider); -+ if (reporter == NULL) { -+ ERROR("Access report not implemented for domains of type %1$s\n", -+ dom->provider); -+ return ret; -+ } -+ -+ return reporter(tool_ctx, user, service, dom); -+} --- -2.14.3 - diff --git a/SOURCES/0049-dp-use-void-to-express-empty-output-argument-list.patch b/SOURCES/0049-dp-use-void-to-express-empty-output-argument-list.patch deleted file mode 100644 index 8d23c72..0000000 --- a/SOURCES/0049-dp-use-void-to-express-empty-output-argument-list.patch +++ /dev/null @@ -1,50 +0,0 @@ -From ae4435d84bae06c592d7bed16ce7aa2b07823be9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Thu, 2 Nov 2017 14:58:05 +0100 -Subject: [PATCH 49/57] dp: use void * to express empty output argument list -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Since we cannot use plain void type is function definition. - -Related: -https://pagure.io/SSSD/sssd/issue/2840 - -Reviewed-by: Jakub Hrozek -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 6211a202301e6f61d46cdb2bf0be332a70c7fdea) ---- - src/providers/data_provider/dp_private.h | 2 +- - src/providers/data_provider/dp_request_reply.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/providers/data_provider/dp_private.h b/src/providers/data_provider/dp_private.h -index 2e71a373fdc8886fccb23bfb8283dc5bc341b1b0..028070f7f1866854c145a148e44c2cb108d2fc58 100644 ---- a/src/providers/data_provider/dp_private.h -+++ b/src/providers/data_provider/dp_private.h -@@ -136,7 +136,7 @@ typedef void (*dp_req_reply_fn)(const char *req_name, - - void dp_req_reply_default(const char *req_name, - struct sbus_request *sbus_req, -- void *data); -+ void **data); - - /* Data provider request table. */ - -diff --git a/src/providers/data_provider/dp_request_reply.c b/src/providers/data_provider/dp_request_reply.c -index 27d9654bad76a099b004846463f035bf2e6d1243..34440fda7f28f0026d63af1af9958dcea3c6aaec 100644 ---- a/src/providers/data_provider/dp_request_reply.c -+++ b/src/providers/data_provider/dp_request_reply.c -@@ -31,7 +31,7 @@ - - void dp_req_reply_default(const char *req_name, - struct sbus_request *sbus_req, -- void *data) -+ void **data) - { - DP_REQ_DEBUG(SSSDBG_TRACE_FUNC, req_name, "Replying with empty message"); - --- -2.14.3 - diff --git a/SOURCES/0050-dp-add-method-to-refresh-access-control-rules.patch b/SOURCES/0050-dp-add-method-to-refresh-access-control-rules.patch deleted file mode 100644 index cb7b567..0000000 --- a/SOURCES/0050-dp-add-method-to-refresh-access-control-rules.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 7de7fd7a9378461ce57f9b5174938af9440381ca Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Thu, 2 Nov 2017 14:58:38 +0100 -Subject: [PATCH 50/57] dp: add method to refresh access control rules -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related: -https://pagure.io/SSSD/sssd/issue/2840 - -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Jakub Hrozek -(cherry picked from commit e737cdfa225e0d455c0e574bcb82c2cc16a17d9d) ---- - src/providers/data_provider/dp.h | 2 ++ - src/providers/data_provider/dp_iface.c | 6 ++++++ - src/providers/data_provider/dp_iface.h | 4 ++++ - src/providers/data_provider/dp_iface.xml | 6 ++++++ - src/providers/data_provider/dp_iface_generated.c | 27 ++++++++++++++++++++++++ - src/providers/data_provider/dp_iface_generated.h | 16 ++++++++++++++ - src/providers/data_provider/dp_target_auth.c | 14 ++++++++++++ - 7 files changed, 75 insertions(+) - -diff --git a/src/providers/data_provider/dp.h b/src/providers/data_provider/dp.h -index 9cdbe5b3a56ba159f9a10df6e010e616e4aefcac..aa5b781158c54545b26034602bb25db46b189e87 100644 ---- a/src/providers/data_provider/dp.h -+++ b/src/providers/data_provider/dp.h -@@ -83,6 +83,8 @@ enum dp_methods { - DPM_DOMAINS_HANDLER, - DPM_SESSION_HANDLER, - -+ DPM_REFRESH_ACCESS_RULES, -+ - DP_METHOD_SENTINEL - }; - -diff --git a/src/providers/data_provider/dp_iface.c b/src/providers/data_provider/dp_iface.c -index 4b2b0ddca68be8899f7285b4d881a91444b99362..28d70e686f63a3572ac595f493aa1d59436c563f 100644 ---- a/src/providers/data_provider/dp_iface.c -+++ b/src/providers/data_provider/dp_iface.c -@@ -48,10 +48,16 @@ struct iface_dp_failover iface_dp_failover = { - .ListServers = dp_failover_list_servers - }; - -+struct iface_dp_access_control iface_dp_access_control = { -+ { &iface_dp_access_control_meta, 0 }, -+ .RefreshRules = dp_access_control_refresh_rules_handler -+}; -+ - static struct sbus_iface_map dp_map[] = { - { DP_PATH, &iface_dp.vtable }, - { DP_PATH, &iface_dp_backend.vtable }, - { DP_PATH, &iface_dp_failover.vtable }, -+ { DP_PATH, &iface_dp_access_control.vtable }, - { NULL, NULL } - }; - -diff --git a/src/providers/data_provider/dp_iface.h b/src/providers/data_provider/dp_iface.h -index 8ae7a2ad7a61f82b000493f3309926cd932211f6..759b9e6c9eb7f53836ae0b641b34e6c31e65779f 100644 ---- a/src/providers/data_provider/dp_iface.h -+++ b/src/providers/data_provider/dp_iface.h -@@ -76,4 +76,8 @@ errno_t dp_failover_list_servers(struct sbus_request *sbus_req, - void *dp_cli, - const char *service_name); - -+/* org.freedesktop.sssd.DataProvider.AccessControl */ -+errno_t dp_access_control_refresh_rules_handler(struct sbus_request *sbus_req, -+ void *dp_cli); -+ - #endif /* DP_IFACE_H_ */ -diff --git a/src/providers/data_provider/dp_iface.xml b/src/providers/data_provider/dp_iface.xml -index a3969873ad1660c71ebdcae7a951757f5254c865..2bfa9dfa7e9d02d2d12c3358967f6969438a97a2 100644 ---- a/src/providers/data_provider/dp_iface.xml -+++ b/src/providers/data_provider/dp_iface.xml -@@ -32,6 +32,12 @@ - - - -+ -+ -+ -+ -+ -+ - - - -diff --git a/src/providers/data_provider/dp_iface_generated.c b/src/providers/data_provider/dp_iface_generated.c -index e2e0216bd98c498b2b34c524ba615b70564420a2..11ee2e24a69cc8d4d19fdbeed613e76081aef15d 100644 ---- a/src/providers/data_provider/dp_iface_generated.c -+++ b/src/providers/data_provider/dp_iface_generated.c -@@ -187,6 +187,33 @@ const struct sbus_interface_meta iface_dp_failover_meta = { - sbus_invoke_get_all, /* GetAll invoker */ - }; - -+int iface_dp_access_control_RefreshRules_finish(struct sbus_request *req) -+{ -+ return sbus_request_return_and_finish(req, -+ DBUS_TYPE_INVALID); -+} -+ -+/* methods for org.freedesktop.sssd.DataProvider.AccessControl */ -+const struct sbus_method_meta iface_dp_access_control__methods[] = { -+ { -+ "RefreshRules", /* name */ -+ NULL, /* no in_args */ -+ NULL, /* no out_args */ -+ offsetof(struct iface_dp_access_control, RefreshRules), -+ NULL, /* no invoker */ -+ }, -+ { NULL, } -+}; -+ -+/* interface info for org.freedesktop.sssd.DataProvider.AccessControl */ -+const struct sbus_interface_meta iface_dp_access_control_meta = { -+ "org.freedesktop.sssd.DataProvider.AccessControl", /* name */ -+ iface_dp_access_control__methods, -+ NULL, /* no signals */ -+ NULL, /* no properties */ -+ sbus_invoke_get_all, /* GetAll invoker */ -+}; -+ - /* arguments for org.freedesktop.sssd.dataprovider.autofsHandler */ - const struct sbus_arg_meta iface_dp_autofsHandler__in[] = { - { "dp_flags", "u" }, -diff --git a/src/providers/data_provider/dp_iface_generated.h b/src/providers/data_provider/dp_iface_generated.h -index b7f63fb438d7b3024a0f66de0a5d15cc3d426f44..541a90b0b5a5bc0a346cbd04974d33c8bb0983c5 100644 ---- a/src/providers/data_provider/dp_iface_generated.h -+++ b/src/providers/data_provider/dp_iface_generated.h -@@ -26,6 +26,10 @@ - #define IFACE_DP_FAILOVER_ACTIVESERVER "ActiveServer" - #define IFACE_DP_FAILOVER_LISTSERVERS "ListServers" - -+/* constants for org.freedesktop.sssd.DataProvider.AccessControl */ -+#define IFACE_DP_ACCESS_CONTROL "org.freedesktop.sssd.DataProvider.AccessControl" -+#define IFACE_DP_ACCESS_CONTROL_REFRESHRULES "RefreshRules" -+ - /* constants for org.freedesktop.sssd.dataprovider */ - #define IFACE_DP "org.freedesktop.sssd.dataprovider" - #define IFACE_DP_PAMHANDLER "pamHandler" -@@ -88,6 +92,15 @@ int iface_dp_failover_ActiveServer_finish(struct sbus_request *req, const char * - /* finish function for ListServers */ - int iface_dp_failover_ListServers_finish(struct sbus_request *req, const char *arg_servers[], int len_servers); - -+/* vtable for org.freedesktop.sssd.DataProvider.AccessControl */ -+struct iface_dp_access_control { -+ struct sbus_vtable vtable; /* derive from sbus_vtable */ -+ int (*RefreshRules)(struct sbus_request *req, void *data); -+}; -+ -+/* finish function for RefreshRules */ -+int iface_dp_access_control_RefreshRules_finish(struct sbus_request *req); -+ - /* vtable for org.freedesktop.sssd.dataprovider */ - struct iface_dp { - struct sbus_vtable vtable; /* derive from sbus_vtable */ -@@ -130,6 +143,9 @@ extern const struct sbus_interface_meta iface_dp_backend_meta; - /* interface info for org.freedesktop.sssd.DataProvider.Failover */ - extern const struct sbus_interface_meta iface_dp_failover_meta; - -+/* interface info for org.freedesktop.sssd.DataProvider.AccessControl */ -+extern const struct sbus_interface_meta iface_dp_access_control_meta; -+ - /* interface info for org.freedesktop.sssd.dataprovider */ - extern const struct sbus_interface_meta iface_dp_meta; - -diff --git a/src/providers/data_provider/dp_target_auth.c b/src/providers/data_provider/dp_target_auth.c -index 6bb3313b2de002466e5ca84464c962acd2412bfa..4b47975569a04a4d79aef4c16fcacf92c295de25 100644 ---- a/src/providers/data_provider/dp_target_auth.c -+++ b/src/providers/data_provider/dp_target_auth.c -@@ -306,3 +306,17 @@ void dp_pam_handler_selinux_done(struct tevent_req *req) - dp_pam_reply(state->sbus_req, state->request_name, pd); - return; - } -+ -+errno_t dp_access_control_refresh_rules_handler(struct sbus_request *sbus_req, -+ void *dp_cli) -+{ -+ const char *key; -+ -+ key = "RefreshRules"; -+ -+ dp_req_with_reply(dp_cli, NULL, "Refresh Access Control Rules", key, -+ sbus_req, DPT_ACCESS, DPM_REFRESH_ACCESS_RULES, 0, NULL, -+ dp_req_reply_default, void *); -+ -+ return EOK; -+} --- -2.14.3 - diff --git a/SOURCES/0051-ipa-implement-method-to-refresh-HBAC-rules.patch b/SOURCES/0051-ipa-implement-method-to-refresh-HBAC-rules.patch deleted file mode 100644 index 5ccb7fd..0000000 --- a/SOURCES/0051-ipa-implement-method-to-refresh-HBAC-rules.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 42f16ffa434de2efcdb9010df39dfe7cc619dfb0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Thu, 2 Nov 2017 14:59:19 +0100 -Subject: [PATCH 51/57] ipa: implement method to refresh HBAC rules -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related: -https://pagure.io/SSSD/sssd/issue/2840 - -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Jakub Hrozek -(cherry picked from commit 2754a8dcfa937d45b024a2e57419248bfd4c4919) ---- - src/providers/ipa/ipa_access.c | 68 ++++++++++++++++++++++++++++++++++++++++-- - src/providers/ipa/ipa_access.h | 10 +++++++ - src/providers/ipa/ipa_init.c | 4 +++ - 3 files changed, 80 insertions(+), 2 deletions(-) - -diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c -index 32ccf541c9436b633e7724b2c44ee545810a7fb8..de9f68170b6e9c38fd8b6d23f1d565250bbf78d2 100644 ---- a/src/providers/ipa/ipa_access.c -+++ b/src/providers/ipa/ipa_access.c -@@ -682,8 +682,8 @@ done: - - errno_t - ipa_pam_access_handler_recv(TALLOC_CTX *mem_ctx, -- struct tevent_req *req, -- struct pam_data **_data) -+ struct tevent_req *req, -+ struct pam_data **_data) - { - struct ipa_pam_access_handler_state *state = NULL; - -@@ -695,3 +695,67 @@ ipa_pam_access_handler_recv(TALLOC_CTX *mem_ctx, - - return EOK; - } -+ -+struct ipa_refresh_access_rules_state { -+ int dummy; -+}; -+ -+static void ipa_refresh_access_rules_done(struct tevent_req *subreq); -+ -+struct tevent_req * -+ipa_refresh_access_rules_send(TALLOC_CTX *mem_ctx, -+ struct ipa_access_ctx *access_ctx, -+ void *no_input_data, -+ struct dp_req_params *params) -+{ -+ struct ipa_refresh_access_rules_state *state; -+ struct tevent_req *subreq; -+ struct tevent_req *req; -+ -+ DEBUG(SSSDBG_TRACE_FUNC, "Refreshing HBAC rules\n"); -+ -+ req = tevent_req_create(mem_ctx, &state, -+ struct ipa_refresh_access_rules_state); -+ if (req == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create tevent request!\n"); -+ return NULL; -+ } -+ -+ subreq = ipa_fetch_hbac_send(state, params->ev, params->be_ctx, access_ctx); -+ if (subreq == NULL) { -+ tevent_req_error(req, ENOMEM); -+ tevent_req_post(req, params->ev); -+ return req; -+ } -+ -+ tevent_req_set_callback(subreq, ipa_refresh_access_rules_done, req); -+ -+ return req; -+} -+ -+static void ipa_refresh_access_rules_done(struct tevent_req *subreq) -+{ -+ struct tevent_req *req; -+ errno_t ret; -+ -+ req = tevent_req_callback_data(subreq, struct tevent_req); -+ -+ ret = ipa_fetch_hbac_recv(subreq); -+ talloc_zfree(subreq); -+ if (ret != EOK) { -+ tevent_req_error(req, ret); -+ return; -+ } -+ -+ tevent_req_done(req); -+ return; -+} -+ -+errno_t ipa_refresh_access_rules_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ void **_no_output_data) -+{ -+ TEVENT_REQ_RETURN_ON_ERROR(req); -+ -+ return EOK; -+} -diff --git a/src/providers/ipa/ipa_access.h b/src/providers/ipa/ipa_access.h -index de690350218bd47165a2b48c10059b8de96b718a..9cec0d1063fd39380a77093526e3240523752075 100644 ---- a/src/providers/ipa/ipa_access.h -+++ b/src/providers/ipa/ipa_access.h -@@ -63,4 +63,14 @@ ipa_pam_access_handler_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *req, - struct pam_data **_data); - -+struct tevent_req * -+ipa_refresh_access_rules_send(TALLOC_CTX *mem_ctx, -+ struct ipa_access_ctx *access_ctx, -+ void *no_input_data, -+ struct dp_req_params *params); -+ -+errno_t ipa_refresh_access_rules_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ void **_no_output_data); -+ - #endif /* _IPA_ACCESS_H_ */ -diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c -index 5b7c8e1348f561901782c872078a0e7391d4ff75..f335d51fd65959d256c54a5d92c594a24e895b7c 100644 ---- a/src/providers/ipa/ipa_init.c -+++ b/src/providers/ipa/ipa_init.c -@@ -831,6 +831,10 @@ errno_t sssm_ipa_access_init(TALLOC_CTX *mem_ctx, - ipa_pam_access_handler_send, ipa_pam_access_handler_recv, access_ctx, - struct ipa_access_ctx, struct pam_data, struct pam_data *); - -+ dp_set_method(dp_methods, DPM_REFRESH_ACCESS_RULES, -+ ipa_refresh_access_rules_send, ipa_refresh_access_rules_recv, access_ctx, -+ struct ipa_access_ctx, void, void *); -+ - ret = EOK; - - done: --- -2.14.3 - diff --git a/SOURCES/0052-ifp-add-method-to-refresh-access-control-rules-in-do.patch b/SOURCES/0052-ifp-add-method-to-refresh-access-control-rules-in-do.patch deleted file mode 100644 index 55e224d..0000000 --- a/SOURCES/0052-ifp-add-method-to-refresh-access-control-rules-in-do.patch +++ /dev/null @@ -1,158 +0,0 @@ -From c6e02c84a567127b37b1c036abf7952f1d36783a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Thu, 2 Nov 2017 14:59:57 +0100 -Subject: [PATCH 52/57] ifp: add method to refresh access control rules in - domain -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related: -https://pagure.io/SSSD/sssd/issue/2840 - -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Jakub Hrozek -(cherry picked from commit c6cf752337f5977ce3753b7113dc1a2342c86319) ---- - src/responder/ifp/ifp_domains.c | 22 ++++++++++++++++++++++ - src/responder/ifp/ifp_domains.h | 3 +++ - src/responder/ifp/ifp_iface.c | 3 ++- - src/responder/ifp/ifp_iface.xml | 3 +++ - src/responder/ifp/ifp_iface_generated.c | 13 +++++++++++++ - src/responder/ifp/ifp_iface_generated.h | 5 +++++ - 6 files changed, 48 insertions(+), 1 deletion(-) - -diff --git a/src/responder/ifp/ifp_domains.c b/src/responder/ifp/ifp_domains.c -index 977bbfcbe818f08873ce072d34fdcf900cabf52f..cd7e2fc7aeff5467514269e5b078b0da88ab4f50 100644 ---- a/src/responder/ifp/ifp_domains.c -+++ b/src/responder/ifp/ifp_domains.c -@@ -630,3 +630,25 @@ int ifp_domains_domain_list_servers(struct sbus_request *sbus_req, - - return EOK; - } -+ -+int ifp_domains_domain_refresh_access_rules(struct sbus_request *sbus_req, -+ void *data) -+{ -+ struct ifp_ctx *ifp_ctx; -+ struct sss_domain_info *dom; -+ -+ ifp_ctx = talloc_get_type(data, struct ifp_ctx); -+ -+ dom = get_domain_info_from_req(sbus_req, data); -+ if (dom == NULL) { -+ sbus_request_reply_error(sbus_req, SBUS_ERROR_UNKNOWN_DOMAIN, -+ "Unknown domain"); -+ return EOK; -+ } -+ -+ rdp_message_send_and_reply(sbus_req, ifp_ctx->rctx, dom, DP_PATH, -+ IFACE_DP_ACCESS_CONTROL, -+ IFACE_DP_ACCESS_CONTROL_REFRESHRULES); -+ -+ return EOK; -+} -diff --git a/src/responder/ifp/ifp_domains.h b/src/responder/ifp/ifp_domains.h -index 621ba6158e285911cb8298cef212219dfd3afec8..d8cc9d34c92cd04b6db432c1fc0e179a717001da 100644 ---- a/src/responder/ifp/ifp_domains.h -+++ b/src/responder/ifp/ifp_domains.h -@@ -108,4 +108,7 @@ int ifp_domains_domain_list_servers(struct sbus_request *sbus_req, - void *data, - const char *service); - -+int ifp_domains_domain_refresh_access_rules(struct sbus_request *sbus_req, -+ void *data); -+ - #endif /* IFP_DOMAINS_H_ */ -diff --git a/src/responder/ifp/ifp_iface.c b/src/responder/ifp/ifp_iface.c -index 3293b92d750d33b2ecf77a03098c5169d052c924..f995e28f99f9489ca17fbc51fa6894d458f9e21f 100644 ---- a/src/responder/ifp/ifp_iface.c -+++ b/src/responder/ifp/ifp_iface.c -@@ -79,7 +79,8 @@ struct iface_ifp_domains_domain iface_ifp_domains_domain = { - .IsOnline = ifp_domains_domain_is_online, - .ListServices = ifp_domains_domain_list_services, - .ActiveServer = ifp_domains_domain_active_server, -- .ListServers = ifp_domains_domain_list_servers -+ .ListServers = ifp_domains_domain_list_servers, -+ .RefreshAccessRules = ifp_domains_domain_refresh_access_rules - }; - - struct iface_ifp_users iface_ifp_users = { -diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml -index 39385e866f31131c7860001ae4d6e6b51105aa52..1aa7eac03f0a3dc86f1d25883ac37f2fabf6b9e8 100644 ---- a/src/responder/ifp/ifp_iface.xml -+++ b/src/responder/ifp/ifp_iface.xml -@@ -112,6 +112,9 @@ - - - -+ -+ -+ - - - -diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c -index 6943e38e3b6d2fc9e09ade1a863905c8d81a39ba..c2cdbf5b0ef3d59068aeed7a8f45099c14c4a94a 100644 ---- a/src/responder/ifp/ifp_iface_generated.c -+++ b/src/responder/ifp/ifp_iface_generated.c -@@ -552,6 +552,12 @@ int iface_ifp_domains_domain_ListServers_finish(struct sbus_request *req, const - DBUS_TYPE_INVALID); - } - -+int iface_ifp_domains_domain_RefreshAccessRules_finish(struct sbus_request *req) -+{ -+ return sbus_request_return_and_finish(req, -+ DBUS_TYPE_INVALID); -+} -+ - /* methods for org.freedesktop.sssd.infopipe.Domains.Domain */ - const struct sbus_method_meta iface_ifp_domains_domain__methods[] = { - { -@@ -582,6 +588,13 @@ const struct sbus_method_meta iface_ifp_domains_domain__methods[] = { - offsetof(struct iface_ifp_domains_domain, ListServers), - invoke_s_method, - }, -+ { -+ "RefreshAccessRules", /* name */ -+ NULL, /* no in_args */ -+ NULL, /* no out_args */ -+ offsetof(struct iface_ifp_domains_domain, RefreshAccessRules), -+ NULL, /* no invoker */ -+ }, - { NULL, } - }; - -diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h -index 30752bf063de1f2530c7451f01cc22ad3e863185..f1e6c80bab27d0ed581abc566a178e6857794805 100644 ---- a/src/responder/ifp/ifp_iface_generated.h -+++ b/src/responder/ifp/ifp_iface_generated.h -@@ -57,6 +57,7 @@ - #define IFACE_IFP_DOMAINS_DOMAIN_LISTSERVICES "ListServices" - #define IFACE_IFP_DOMAINS_DOMAIN_ACTIVESERVER "ActiveServer" - #define IFACE_IFP_DOMAINS_DOMAIN_LISTSERVERS "ListServers" -+#define IFACE_IFP_DOMAINS_DOMAIN_REFRESHACCESSRULES "RefreshAccessRules" - - /* constants for org.freedesktop.sssd.infopipe.Cache */ - #define IFACE_IFP_CACHE "org.freedesktop.sssd.infopipe.Cache" -@@ -209,6 +210,7 @@ struct iface_ifp_domains_domain { - int (*ListServices)(struct sbus_request *req, void *data); - int (*ActiveServer)(struct sbus_request *req, void *data, const char *arg_service); - int (*ListServers)(struct sbus_request *req, void *data, const char *arg_service_name); -+ int (*RefreshAccessRules)(struct sbus_request *req, void *data); - }; - - /* finish function for IsOnline */ -@@ -223,6 +225,9 @@ int iface_ifp_domains_domain_ActiveServer_finish(struct sbus_request *req, const - /* finish function for ListServers */ - int iface_ifp_domains_domain_ListServers_finish(struct sbus_request *req, const char *arg_servers[], int len_servers); - -+/* finish function for RefreshAccessRules */ -+int iface_ifp_domains_domain_RefreshAccessRules_finish(struct sbus_request *req); -+ - /* vtable for org.freedesktop.sssd.infopipe.Cache */ - struct iface_ifp_cache { - struct sbus_vtable vtable; /* derive from sbus_vtable */ --- -2.14.3 - diff --git a/SOURCES/0053-sssctl-call-dbus-instead-of-pam-to-refresh-HBAC-rule.patch b/SOURCES/0053-sssctl-call-dbus-instead-of-pam-to-refresh-HBAC-rule.patch deleted file mode 100644 index 4c2404e..0000000 --- a/SOURCES/0053-sssctl-call-dbus-instead-of-pam-to-refresh-HBAC-rule.patch +++ /dev/null @@ -1,200 +0,0 @@ -From cbe1f1f8fa207eded53260a0fb288c5b31b18c96 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Pavel=20B=C5=99ezina?= -Date: Thu, 2 Nov 2017 15:00:17 +0100 -Subject: [PATCH 53/57] sssctl: call dbus instead of pam to refresh HBAC rules -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related: -https://pagure.io/SSSD/sssd/issue/2840 - -Reviewed-by: Jakub Hrozek -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit be804178d5e5fee64be2b080e73f4ce7b0074f76) ---- - src/tools/sssctl/sssctl_access_report.c | 127 +++++++++++++++----------------- - 1 file changed, 58 insertions(+), 69 deletions(-) - -diff --git a/src/tools/sssctl/sssctl_access_report.c b/src/tools/sssctl/sssctl_access_report.c -index 11172329817b4dedaca480ab8a4537149853c330..8cf1a8a871b27827c317d658c0f93f34773c4841 100644 ---- a/src/tools/sssctl/sssctl_access_report.c -+++ b/src/tools/sssctl/sssctl_access_report.c -@@ -15,11 +15,11 @@ - along with this program. If not, see . - */ - --#include -- - #include "util/util.h" - #include "tools/common/sss_tools.h" - #include "tools/sssctl/sssctl.h" -+#include "sbus/sssd_dbus.h" -+#include "responder/ifp/ifp_iface.h" - - /* - * We're searching the cache directly.. -@@ -27,58 +27,9 @@ - #include "providers/ipa/ipa_hbac_private.h" - #include "providers/ipa/ipa_rules_common.h" - --#ifdef HAVE_SECURITY_PAM_MISC_H --# include --#elif defined(HAVE_SECURITY_OPENPAM_H) --# include --#endif -- --#ifdef HAVE_SECURITY_PAM_MISC_H --static struct pam_conv conv = { -- misc_conv, -- NULL --}; --#elif defined(HAVE_SECURITY_OPENPAM_H) --static struct pam_conv conv = { -- openpam_ttyconv, -- NULL --}; --#else --# error "Missing text based pam conversation function" --#endif -- --#ifndef DEFAULT_SERVICE --#define DEFAULT_SERVICE "system-auth" --#endif /* DEFAULT_SERVICE */ -- --#ifndef DEFAULT_USER --#define DEFAULT_USER "admin" --#endif /* DEFAULT_USER */ -- - typedef errno_t (*sssctl_dom_access_reporter_fn)(struct sss_tool_ctx *tool_ctx, -- const char *user, -- const char *service, - struct sss_domain_info *domain); - --static errno_t run_pam_acct(struct sss_tool_ctx *tool_ctx, -- const char *user, -- const char *service, -- struct sss_domain_info *domain) --{ -- errno_t ret; -- pam_handle_t *pamh; -- -- ret = pam_start(service, user, &conv, &pamh); -- if (ret != PAM_SUCCESS) { -- ERROR("pam_start failed: %s\n", pam_strerror(pamh, ret)); -- return EIO; -- } -- -- ret = pam_acct_mgmt(pamh, 0); -- pam_end(pamh, ret); -- return ret; --} -- - static errno_t get_rdn_value(TALLOC_CTX *mem_ctx, - struct sss_domain_info *dom, - const char *dn_attr, -@@ -315,9 +266,58 @@ static void print_ipa_hbac_rule(struct sss_domain_info *domain, - PRINT("\n"); - } - -+static errno_t refresh_hbac_rules(struct sss_tool_ctx *tool_ctx, -+ struct sss_domain_info *domain) -+{ -+ TALLOC_CTX *tmp_ctx; -+ sss_sifp_error error; -+ sss_sifp_ctx *sifp; -+ DBusMessage *reply; -+ const char *path; -+ errno_t ret; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); -+ return ENOMEM; -+ } -+ -+ path = sbus_opath_compose(tmp_ctx, IFP_PATH_DOMAINS, domain->name); -+ if (path == NULL) { -+ printf(_("Out of memory!\n")); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ error = sssctl_sifp_init(tool_ctx, &sifp); -+ if (error != SSS_SIFP_OK) { -+ sssctl_sifp_error(sifp, error, "Unable to connect to the InfoPipe"); -+ ret = EIO; -+ goto done; -+ } -+ -+ error = sssctl_sifp_send(tmp_ctx, sifp, &reply, path, -+ IFACE_IFP_DOMAINS_DOMAIN, -+ IFACE_IFP_DOMAINS_DOMAIN_REFRESHACCESSRULES); -+ if (error != SSS_SIFP_OK) { -+ sssctl_sifp_error(sifp, error, "Unable to refresh HBAC rules"); -+ ret = EIO; -+ goto done; -+ } -+ -+ ret = sbus_parse_reply(reply); -+ if (ret != EOK) { -+ goto done; -+ } -+ -+ ret = EOK; -+ -+done: -+ talloc_free(tmp_ctx); -+ return ret; -+} -+ - static errno_t sssctl_ipa_access_report(struct sss_tool_ctx *tool_ctx, -- const char *user, -- const char *service, - struct sss_domain_info *domain) - { - TALLOC_CTX *tmp_ctx = NULL; -@@ -338,9 +338,9 @@ static errno_t sssctl_ipa_access_report(struct sss_tool_ctx *tool_ctx, - struct ldb_message **msgs = NULL; - - /* Run the pam account phase to make sure the rules are fetched by SSSD */ -- ret = run_pam_acct(tool_ctx, user, service, domain); -- if (ret != PAM_SUCCESS && ret != PAM_PERM_DENIED) { -- ERROR("Cannot run the PAM account phase, reporting stale rules\n"); -+ ret = refresh_hbac_rules(tool_ctx, domain); -+ if (ret != EOK) { -+ ERROR("Unable to refresh HBAC rules, using cached content\n"); - /* Non-fatal */ - } - -@@ -398,19 +398,8 @@ errno_t sssctl_access_report(struct sss_cmdline *cmdline, - const char *domname = NULL; - sssctl_dom_access_reporter_fn reporter; - struct sss_domain_info *dom; -- const char *user = DEFAULT_USER; -- const char *service = DEFAULT_SERVICE; - -- /* Parse command line. */ -- struct poptOption options[] = { -- { "user", 'u', POPT_ARG_STRING, &user, 0, -- _("PAM user, default: " DEFAULT_USER), NULL }, -- { "service", 's', POPT_ARG_STRING, &service, 0, -- _("PAM service, default: " DEFAULT_SERVICE), NULL }, -- POPT_TABLEEND -- }; -- -- ret = sss_tool_popt_ex(cmdline, options, SSS_TOOL_OPT_OPTIONAL, -+ ret = sss_tool_popt_ex(cmdline, NULL, SSS_TOOL_OPT_OPTIONAL, - NULL, NULL, "DOMAIN", _("Specify domain name."), - &domname, NULL); - if (ret != EOK) { -@@ -431,5 +420,5 @@ errno_t sssctl_access_report(struct sss_cmdline *cmdline, - return ret; - } - -- return reporter(tool_ctx, user, service, dom); -+ return reporter(tool_ctx, dom); - } --- -2.14.3 - diff --git a/SOURCES/0054-sysdb-be_refresh_get_values_ex-remove-unused-option.patch b/SOURCES/0054-sysdb-be_refresh_get_values_ex-remove-unused-option.patch deleted file mode 100644 index a4f566f..0000000 --- a/SOURCES/0054-sysdb-be_refresh_get_values_ex-remove-unused-option.patch +++ /dev/null @@ -1,66 +0,0 @@ -From e32a5bd6fa76c7146a7024d42efeb26895337048 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 8 Nov 2017 14:04:40 +0100 -Subject: [PATCH 54/57] sysdb: be_refresh_get_values_ex() remove unused option -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The objectclass argument is not used in be_refresh_get_values_ex() -anymore. - -Related to https://pagure.io/SSSD/sssd/issue/3503 - -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Jakub Hrozek -(cherry picked from commit 0cce3d3ad14caf406303cf2ce6bf80171b708a93) ---- - src/providers/be_refresh.c | 7 +------ - 1 file changed, 1 insertion(+), 6 deletions(-) - -diff --git a/src/providers/be_refresh.c b/src/providers/be_refresh.c -index 81f2c5d1d368987bf9135fce730d917a32c1e24f..e8cf5da75847cd6ab647e91865b36ec6e4e59822 100644 ---- a/src/providers/be_refresh.c -+++ b/src/providers/be_refresh.c -@@ -32,7 +32,6 @@ - static errno_t be_refresh_get_values_ex(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - time_t period, -- const char *objectclass, - struct ldb_dn *base_dn, - const char *attr, - char ***_values) -@@ -96,21 +95,17 @@ static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx, - char ***_values) - { - struct ldb_dn *base_dn = NULL; -- const char *class = NULL; - errno_t ret; - - switch (type) { - case BE_REFRESH_TYPE_USERS: - base_dn = sysdb_user_base_dn(mem_ctx, domain); -- class = SYSDB_USER_CLASS; - break; - case BE_REFRESH_TYPE_GROUPS: - base_dn = sysdb_group_base_dn(mem_ctx, domain); -- class = SYSDB_GROUP_CLASS; - break; - case BE_REFRESH_TYPE_NETGROUPS: - base_dn = sysdb_netgroup_base_dn(mem_ctx, domain); -- class = SYSDB_NETGROUP_CLASS; - break; - case BE_REFRESH_TYPE_SENTINEL: - return ERR_INTERNAL; -@@ -121,7 +116,7 @@ static errno_t be_refresh_get_values(TALLOC_CTX *mem_ctx, - return ENOMEM; - } - -- ret = be_refresh_get_values_ex(mem_ctx, domain, period, class, -+ ret = be_refresh_get_values_ex(mem_ctx, domain, period, - base_dn, SYSDB_NAME, _values); - - talloc_free(base_dn); --- -2.14.3 - diff --git a/SOURCES/0055-sysdb-do-not-use-objectClass-for-users-and-groups.patch b/SOURCES/0055-sysdb-do-not-use-objectClass-for-users-and-groups.patch deleted file mode 100644 index 4d94916..0000000 --- a/SOURCES/0055-sysdb-do-not-use-objectClass-for-users-and-groups.patch +++ /dev/null @@ -1,758 +0,0 @@ -From e4ba8c5c6c08f86d51485d49c27635d7079efe13 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 8 Nov 2017 15:14:58 +0100 -Subject: [PATCH 55/57] sysdb: do not use objectClass for users and groups -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The majority of the object in the SSSD cache are users and groups. If -there are many user and groups in the cache the index objects of the -objectclass attributes 'user' and 'group' become large because the -must hold references to all objects of those object classes. - -As a result the management of these index objects becomes costly because -they must be parsed and split apart quite often. Additionally they are -mostly useless because user and groups are lookup up by more specific -attributes in general. - -Only when enumerating all user or groups this kind of index might be -useful. - -There are two way of removing this kind of index from the user and group -objects. Either by removing objectClass from the list of indexes and add -a new attribute to all other type of object we want and index for. Or by -replacing objectClass with a different attribute for the user and group -objects. After some testing I think the latter one is the more reliable -one and implemented it in this patch. - -Related to https://pagure.io/SSSD/sssd/issue/3503 - -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Jakub Hrozek -(cherry picked from commit 0e238c259c066cf997aaa940d33d6bda96c15925) ---- - src/db/sysdb.h | 10 ++-- - src/db/sysdb_init.c | 5 +- - src/db/sysdb_ops.c | 6 +-- - src/db/sysdb_search.c | 11 +++-- - src/db/sysdb_upgrade.c | 4 ++ - src/ldb_modules/memberof.c | 6 +-- - src/providers/ad/ad_pac.c | 2 +- - src/providers/ipa/ipa_id.c | 9 ++-- - src/providers/ipa/ipa_subdomains_ext_groups.c | 2 +- - src/providers/ipa/ipa_subdomains_id.c | 2 +- - src/providers/krb5/krb5_renew_tgt.c | 3 +- - src/providers/ldap/ldap_id_cleanup.c | 2 +- - src/providers/ldap/sdap_async_groups.c | 8 ++-- - src/providers/ldap/sdap_async_initgroups.c | 2 +- - src/providers/ldap/sdap_async_initgroups_ad.c | 2 +- - src/providers/ldap/sdap_async_nested_groups.c | 2 +- - .../common/cache_req/plugins/cache_req_common.c | 2 +- - src/responder/ifp/ifp_cache.c | 4 +- - src/responder/ifp/ifp_groups.c | 4 +- - src/responder/ifp/ifp_users.c | 2 +- - src/responder/nss/nss_cmd.c | 2 +- - src/responder/nss/nss_protocol_grent.c | 2 +- - src/responder/nss/nss_protocol_sid.c | 4 +- - src/tests/cmocka/test_ad_common.c | 2 +- - src/tests/cmocka/test_ipa_subdomains_server.c | 54 ++++++++++++++++------ - src/tests/sysdb-tests.c | 20 +++++--- - src/tools/sssctl/sssctl_cache.c | 3 +- - 27 files changed, 110 insertions(+), 65 deletions(-) - -diff --git a/src/db/sysdb.h b/src/db/sysdb.h -index 4192f9085d941814eccd2ac60ce8fb6d4e1bfa67..fd18ecefed2b2c5f35060fa47fd160a8968e073b 100644 ---- a/src/db/sysdb.h -+++ b/src/db/sysdb.h -@@ -192,9 +192,10 @@ - - #define SYSDB_NEXTID_FILTER "("SYSDB_NEXTID"=*)" - --#define SYSDB_UC "objectclass="SYSDB_USER_CLASS --#define SYSDB_GC "objectclass="SYSDB_GROUP_CLASS --#define SYSDB_NC "objectclass="SYSDB_NETGROUP_CLASS -+#define SYSDB_OBJECTCATEGORY "objectCategory" -+#define SYSDB_UC SYSDB_OBJECTCATEGORY"="SYSDB_USER_CLASS -+#define SYSDB_GC SYSDB_OBJECTCATEGORY"="SYSDB_GROUP_CLASS -+#define SYSDB_NC SYSDB_OBJECTCLASS"="SYSDB_NETGROUP_CLASS - #define SYSDB_MPGC "|("SYSDB_UC")("SYSDB_GC")" - - #define SYSDB_PWNAM_FILTER "(&("SYSDB_UC")(|("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME_ALIAS"=%s)("SYSDB_NAME"=%s)))" -@@ -227,7 +228,8 @@ - #define SYSDB_DEFAULT_ATTRS SYSDB_LAST_UPDATE, \ - SYSDB_CACHE_EXPIRE, \ - SYSDB_INITGR_EXPIRE, \ -- SYSDB_OBJECTCLASS -+ SYSDB_OBJECTCLASS, \ -+ SYSDB_OBJECTCATEGORY - - #define SYSDB_PW_ATTRS {SYSDB_NAME, SYSDB_UIDNUM, \ - SYSDB_GIDNUM, SYSDB_GECOS, \ -diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c -index e246a165ec1d654dba19aa771ed97bfc3a07f245..44a7918f603fe1368b7d81738666de6bb47b83d0 100644 ---- a/src/db/sysdb_init.c -+++ b/src/db/sysdb_init.c -@@ -31,11 +31,12 @@ - #define LDB_MODULES_PATH "LDB_MODULES_PATH" - - /* If an entry differs only in these attributes, they are written to -- * the timestamp cache only. In addition, objectclass is added so that -- * we can distinguish between users and groups. -+ * the timestamp cache only. In addition, objectclass/objectcategory is added -+ * so that we can distinguish between users and groups. - */ - const char *sysdb_ts_cache_attrs[] = { - SYSDB_OBJECTCLASS, -+ SYSDB_OBJECTCATEGORY, - SYSDB_LAST_UPDATE, - SYSDB_CACHE_EXPIRE, - SYSDB_ORIG_MODSTAMP, -diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c -index 1539c41c93e7d6ebd1e544abbb1707df5578cd72..024683317cab99743681db804f7026c8dbb33a38 100644 ---- a/src/db/sysdb_ops.c -+++ b/src/db/sysdb_ops.c -@@ -958,7 +958,7 @@ static struct sysdb_attrs *ts_obj_attrs(TALLOC_CTX *mem_ctx, - return NULL; - } - -- ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS, oc); -+ ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCATEGORY, oc); - if (ret != EOK) { - talloc_free(attrs); - return NULL; -@@ -1667,7 +1667,7 @@ int sysdb_add_basic_user(struct sss_domain_info *domain, - ERROR_OUT(ret, ENOMEM, done); - } - -- ret = sysdb_add_string(msg, SYSDB_OBJECTCLASS, SYSDB_USER_CLASS); -+ ret = sysdb_add_string(msg, SYSDB_OBJECTCATEGORY, SYSDB_USER_CLASS); - if (ret) goto done; - - ret = sysdb_add_string(msg, SYSDB_NAME, name); -@@ -2120,7 +2120,7 @@ int sysdb_add_basic_group(struct sss_domain_info *domain, - ERROR_OUT(ret, ENOMEM, done); - } - -- ret = sysdb_add_string(msg, SYSDB_OBJECTCLASS, SYSDB_GROUP_CLASS); -+ ret = sysdb_add_string(msg, SYSDB_OBJECTCATEGORY, SYSDB_GROUP_CLASS); - if (ret) goto done; - - ret = sysdb_add_string(msg, SYSDB_NAME, name); -diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c -index 8083966900429b268a3b984f1cad3d47d1099198..a6a81e23d257331614085403b4dca8ded860600b 100644 ---- a/src/db/sysdb_search.c -+++ b/src/db/sysdb_search.c -@@ -114,10 +114,11 @@ static errno_t merge_msg_ts_attrs(struct sysdb_ctx *sysdb, - return EIO; - } - -- /* Deliberately start from 1 in order to not merge objectclass and avoid -- * breaking MPGs where the OC might be made up -+ /* Deliberately start from 2 in order to not merge -+ * objectclass/objectcategory and avoid breaking MPGs where the OC might -+ * be made up - */ -- for (size_t c = 1; sysdb_ts_cache_attrs[c]; c++) { -+ for (size_t c = 2; sysdb_ts_cache_attrs[c]; c++) { - ret = merge_ts_attr(ts_msgs[0], sysdb_msg, - sysdb_ts_cache_attrs[c], attrs); - if (ret != EOK) { -@@ -751,7 +752,7 @@ static int mpg_convert(struct ldb_message *msg) - struct ldb_val *val = NULL; - int i; - -- el = ldb_msg_find_element(msg, "objectClass"); -+ el = ldb_msg_find_element(msg, SYSDB_OBJECTCATEGORY); - if (!el) return EINVAL; - - /* see if this is a user to convert to a group */ -@@ -2088,7 +2089,7 @@ errno_t sysdb_get_direct_parents(TALLOC_CTX *mem_ctx, - } - - member_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(%s=%s))", -- SYSDB_OBJECTCLASS, SYSDB_GROUP_CLASS, -+ SYSDB_OBJECTCATEGORY, SYSDB_GROUP_CLASS, - SYSDB_MEMBER, sanitized_dn); - if (!member_filter) { - ret = ENOMEM; -diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c -index 040c91ca6276e7c51a126eefe034aa5fe9d0433f..365d45f7ebd78523ca9ec4b9c2158cc09acb5489 100644 ---- a/src/db/sysdb_upgrade.c -+++ b/src/db/sysdb_upgrade.c -@@ -149,6 +149,7 @@ int sysdb_upgrade_01(struct ldb_context *ldb, const char **ver) - struct ldb_dn *mem_dn; - struct ldb_message *msg; - const struct ldb_val *val; -+ /* No change needed because this version has objectclass group */ - const char *filter = "(&(memberUid=*)(objectclass=group))"; - const char *attrs[] = { "memberUid", NULL }; - const char *mdn; -@@ -1041,6 +1042,7 @@ int sysdb_upgrade_10(struct sysdb_ctx *sysdb, struct sss_domain_info *domain, - struct ldb_message_element *memberof_el; - const char *name; - struct ldb_dn *basedn; -+ /* No change needed because version 10 has objectclass user */ - const char *filter = "(&(objectClass=user)(!(uidNumber=*))(memberOf=*))"; - const char *attrs[] = { "name", "memberof", NULL }; - struct upgrade_ctx *ctx; -@@ -2082,6 +2084,7 @@ static void qualify_users(struct upgrade_ctx *ctx, - struct sss_names_ctx *names, - struct ldb_dn *base_dn) - { -+ /* No change needed because this version has objectclass user */ - const char *user_filter = "objectclass=user"; - const char *user_name_attrs[] = { SYSDB_NAME, - SYSDB_NAME_ALIAS, -@@ -2107,6 +2110,7 @@ static void qualify_groups(struct upgrade_ctx *ctx, - struct sss_names_ctx *names, - struct ldb_dn *base_dn) - { -+ /* No change needed because this version has objectclass group */ - const char *group_filter = "objectclass=group"; - const char *group_name_attrs[] = { SYSDB_NAME, - SYSDB_NAME_ALIAS, -diff --git a/src/ldb_modules/memberof.c b/src/ldb_modules/memberof.c -index af7147ee7cc9299d4040d63a637373842dcee02a..327a38c5f75afcde1b997796afd1217d45acbde2 100644 ---- a/src/ldb_modules/memberof.c -+++ b/src/ldb_modules/memberof.c -@@ -31,7 +31,7 @@ - #define DB_USER_CLASS "user" - #define DB_GROUP_CLASS "group" - #define DB_CACHE_EXPIRE "dataExpireTimestamp" --#define DB_OC "objectClass" -+#define DB_OC "objectCategory" - - #ifndef MAX - #define MAX(a,b) (((a) > (b)) ? (a) : (b)) -@@ -3928,7 +3928,7 @@ static int memberof_recompute_task(struct ldb_module *module, - { - struct ldb_context *ldb = ldb_module_get_ctx(module); - static const char *attrs[] = { DB_NAME, DB_MEMBEROF, NULL }; -- static const char *filter = "(objectclass=user)"; -+ static const char *filter = "("DB_OC"="DB_USER_CLASS")"; - struct mbof_rcmp_context *ctx; - struct ldb_request *src_req; - int ret; -@@ -4035,7 +4035,7 @@ static int mbof_rcmp_search_groups(struct mbof_rcmp_context *ctx) - struct ldb_context *ldb = ldb_module_get_ctx(ctx->module); - static const char *attrs[] = { DB_MEMBEROF, DB_MEMBERUID, - DB_NAME, DB_MEMBER, NULL }; -- static const char *filter = "(objectclass=group)"; -+ static const char *filter = "("DB_OC"="DB_GROUP_CLASS")"; - struct ldb_request *req; - int ret; - -diff --git a/src/providers/ad/ad_pac.c b/src/providers/ad/ad_pac.c -index ed002e1f9bf8f15d5b5d4b1c55392a34d18575e4..6b47462cf79a81b9258e3508914c043432edfed3 100644 ---- a/src/providers/ad/ad_pac.c -+++ b/src/providers/ad/ad_pac.c -@@ -31,7 +31,7 @@ static errno_t find_user_entry(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, - struct dp_id_data *ar, - struct ldb_message **_msg) - { -- const char *user_attrs[] = { SYSDB_NAME, SYSDB_OBJECTCLASS, -+ const char *user_attrs[] = { SYSDB_NAME, SYSDB_OBJECTCATEGORY, - SYSDB_PAC_BLOB, SYSDB_PAC_BLOB_EXPIRE, - NULL }; - struct ldb_message *msg; -diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c -index 5044577f0faa95b19de9233240e92aa60f029774..8f8759f64b758aae7e45c88588e97a1bcf16ad79 100644 ---- a/src/providers/ipa/ipa_id.c -+++ b/src/providers/ipa/ipa_id.c -@@ -431,7 +431,8 @@ static errno_t ipa_id_get_group_uuids(TALLOC_CTX *mem_ctx, - } - - filter = talloc_asprintf(tmp_ctx, -- "(&(objectclass=%s)(!(%s=*))(%s=*))", -+ "(&(%s=%s)(!(%s=*))(%s=*))", -+ SYSDB_OBJECTCATEGORY, - SYSDB_GROUP_CLASS, SYSDB_OVERRIDE_DN, - SYSDB_UUID); - if (filter == NULL) { -@@ -733,7 +734,7 @@ static void ipa_id_get_account_info_orig_done(struct tevent_req *subreq) - const char *attrs[] = { SYSDB_NAME, - SYSDB_UIDNUM, - SYSDB_SID_STR, -- SYSDB_OBJECTCLASS, -+ SYSDB_OBJECTCATEGORY, - SYSDB_UUID, - SYSDB_GHOST, - SYSDB_HOMEDIR, -@@ -819,7 +820,7 @@ static int ipa_id_get_account_info_post_proc_step(struct tevent_req *req) - struct ipa_id_get_account_info_state *state = tevent_req_data(req, - struct ipa_id_get_account_info_state); - -- class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCLASS, -+ class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCATEGORY, - NULL); - if (class == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find an objectclass.\n"); -@@ -957,7 +958,7 @@ static void ipa_id_get_account_info_done(struct tevent_req *subreq) - goto fail; - } - -- class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCLASS, -+ class = ldb_msg_find_attr_as_string(state->obj_msg, SYSDB_OBJECTCATEGORY, - NULL); - if (class == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find an objectclass.\n"); -diff --git a/src/providers/ipa/ipa_subdomains_ext_groups.c b/src/providers/ipa/ipa_subdomains_ext_groups.c -index 0359e0dedeef8db0da71d16a6f0044e43a7a9840..9e1d6c3a9bdeda56b421a2dc9198dff0b84c54ce 100644 ---- a/src/providers/ipa/ipa_subdomains_ext_groups.c -+++ b/src/providers/ipa/ipa_subdomains_ext_groups.c -@@ -940,7 +940,7 @@ search_user_or_group_by_sid_str(TALLOC_CTX *mem_ctx, - const char *attrs[] = { SYSDB_NAME, - SYSDB_SID_STR, - SYSDB_ORIG_DN, -- SYSDB_OBJECTCLASS, -+ SYSDB_OBJECTCATEGORY, - SYSDB_CACHE_EXPIRE, - NULL }; - TALLOC_CTX *tmp_ctx = NULL; -diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c -index 3530af94ef59397db72465fcb0c4a03117a4d8bd..2ba9813a44b4d914d9c2ef7a1a7504546f52954c 100644 ---- a/src/providers/ipa/ipa_subdomains_id.c -+++ b/src/providers/ipa/ipa_subdomains_id.c -@@ -888,7 +888,7 @@ apply_subdomain_homedir(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, - struct ldb_message_element *msg_el = NULL; - size_t c; - -- msg_el = ldb_msg_find_element(msg, SYSDB_OBJECTCLASS); -+ msg_el = ldb_msg_find_element(msg, SYSDB_OBJECTCATEGORY); - if (msg_el == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_find_element failed.\n"); - ret = ENOENT; -diff --git a/src/providers/krb5/krb5_renew_tgt.c b/src/providers/krb5/krb5_renew_tgt.c -index ea6b39deb8dacdfa9211058a54a57b6e9f6b7d9d..549c08c6f105276fa9913568c228d3ff627623ae 100644 ---- a/src/providers/krb5/krb5_renew_tgt.c -+++ b/src/providers/krb5/krb5_renew_tgt.c -@@ -385,8 +385,7 @@ static errno_t check_ccache_files(struct renew_tgt_ctx *renew_tgt_ctx) - { - TALLOC_CTX *tmp_ctx; - int ret; -- const char *ccache_filter = "(&("SYSDB_CCACHE_FILE"=*)" \ -- "("SYSDB_OBJECTCLASS"="SYSDB_USER_CLASS"))"; -+ const char *ccache_filter = "(&("SYSDB_CCACHE_FILE"=*)("SYSDB_UC"))"; - const char *ccache_attrs[] = { SYSDB_CCACHE_FILE, SYSDB_UPN, SYSDB_NAME, - SYSDB_CANONICAL_UPN, NULL }; - size_t msgs_count = 0; -diff --git a/src/providers/ldap/ldap_id_cleanup.c b/src/providers/ldap/ldap_id_cleanup.c -index c85ce45918cf938a95ff85c31bfe0541f9ddd052..8c0f0c18ba587e9bbfec144abe9c172cd5e0465b 100644 ---- a/src/providers/ldap/ldap_id_cleanup.c -+++ b/src/providers/ldap/ldap_id_cleanup.c -@@ -438,7 +438,7 @@ static int cleanup_groups(TALLOC_CTX *memctx, - */ - gid = (gid_t) ldb_msg_find_attr_as_uint(msgs[i], SYSDB_GIDNUM, 0); - subfilter = talloc_asprintf(tmpctx, "(&(%s=%s)(|(%s=%s)(%s=%lu)))", -- SYSDB_OBJECTCLASS, SYSDB_USER_CLASS, -+ SYSDB_OBJECTCATEGORY, SYSDB_USER_CLASS, - SYSDB_MEMBEROF, sanitized_dn, - SYSDB_GIDNUM, (long unsigned) gid); - } else { -diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c -index 536e3f13744c5350eed518c9bd35fd89e0899dc6..b1cfb7e4a4c054e5d365da5fca65da27c9ef5461 100644 ---- a/src/providers/ldap/sdap_async_groups.c -+++ b/src/providers/ldap/sdap_async_groups.c -@@ -39,7 +39,7 @@ static int sdap_find_entry_by_origDN(TALLOC_CTX *memctx, - bool *_is_group) - { - TALLOC_CTX *tmpctx; -- const char *attrs[] = {SYSDB_OBJECTCLASS, NULL}; -+ const char *attrs[] = {SYSDB_OBJECTCLASS, SYSDB_OBJECTCATEGORY, NULL}; - struct ldb_dn *base_dn; - char *filter; - struct ldb_message **msgs; -@@ -90,11 +90,11 @@ static int sdap_find_entry_by_origDN(TALLOC_CTX *memctx, - } - - if (_is_group != NULL) { -- objectclass = ldb_msg_find_attr_as_string(msgs[0], SYSDB_OBJECTCLASS, -+ objectclass = ldb_msg_find_attr_as_string(msgs[0], SYSDB_OBJECTCATEGORY, - NULL); - if (objectclass == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "An antry without a %s?\n", -- SYSDB_OBJECTCLASS); -+ DEBUG(SSSDBG_OP_FAILURE, "An entry without a %s?\n", -+ SYSDB_OBJECTCATEGORY); - ret = EINVAL; - goto done; - } -diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c -index a33975cde4bc359cfe8395c0de04fd1774b8763d..f8a84474749e08349b539c774d68c876167cfdf1 100644 ---- a/src/providers/ldap/sdap_async_initgroups.c -+++ b/src/providers/ldap/sdap_async_initgroups.c -@@ -2341,7 +2341,7 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req) - } - - ret = sysdb_attrs_get_string(state->groups[state->group_iter], -- SYSDB_OBJECTCLASS, &class); -+ SYSDB_OBJECTCATEGORY, &class); - if (ret == EOK) { - /* If there is a objectClass attribute the object is coming from the - * cache and the name attribute of the object already has the primary -diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c -index 2831be9776293260aeec0e2ff85160f1938bdb32..61aa69a2dfbe22cac37a5b7fddc07473527e5de5 100644 ---- a/src/providers/ldap/sdap_async_initgroups_ad.c -+++ b/src/providers/ldap/sdap_async_initgroups_ad.c -@@ -1606,7 +1606,7 @@ sdap_ad_get_domain_local_groups_parse_parents(TALLOC_CTX *mem_ctx, - goto done; - } - -- ret = sysdb_attrs_get_string(gr->group, SYSDB_OBJECTCLASS, &class); -+ ret = sysdb_attrs_get_string(gr->group, SYSDB_OBJECTCATEGORY, &class); - if (ret != EOK) { - /* If objectclass is missing gr->group is a nested parent found during - * the nested group lookup. It might not already stored in the cache. -diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c -index 9271d8cfe38d11fb1ea14960a997f0deee175b27..b1f9753d7cdf5f6e278c54394d4f306cc21a42ab 100644 ---- a/src/providers/ldap/sdap_async_nested_groups.c -+++ b/src/providers/ldap/sdap_async_nested_groups.c -@@ -1686,7 +1686,7 @@ static errno_t sdap_nested_group_get_ipa_user(TALLOC_CTX *mem_ctx, - goto done; - } - -- ret = sysdb_attrs_add_string(user, SYSDB_OBJECTCLASS, SYSDB_USER_CLASS); -+ ret = sysdb_attrs_add_string(user, SYSDB_OBJECTCATEGORY, SYSDB_USER_CLASS); - if (ret != EOK) { - goto done; - } -diff --git a/src/responder/common/cache_req/plugins/cache_req_common.c b/src/responder/common/cache_req/plugins/cache_req_common.c -index b80f310feeebbdbc824db441ff5313632585d3fb..1f86258bc14c7a382712959f24a4ec4c153572d4 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_common.c -+++ b/src/responder/common/cache_req/plugins/cache_req_common.c -@@ -53,7 +53,7 @@ cache_req_well_known_sid_msg(TALLOC_CTX *mem_ctx, - goto done; - } - -- ldberr = ldb_msg_add_string(msg, SYSDB_OBJECTCLASS, SYSDB_GROUP_CLASS); -+ ldberr = ldb_msg_add_string(msg, SYSDB_OBJECTCATEGORY, SYSDB_GROUP_CLASS); - if (ldberr != LDB_SUCCESS) { - goto done; - } -diff --git a/src/responder/ifp/ifp_cache.c b/src/responder/ifp/ifp_cache.c -index 8ea2d8008d40bc0a28f3871b511690af677c5c5e..f84cb14de48b5c86acb027f275edded4eb73e192 100644 ---- a/src/responder/ifp/ifp_cache.c -+++ b/src/responder/ifp/ifp_cache.c -@@ -100,7 +100,7 @@ ifp_cache_get_cached_objects(TALLOC_CTX *mem_ctx, - errno_t ret; - int ldb_ret; - int i; -- const char *attrs[] = {SYSDB_OBJECTCLASS, SYSDB_UIDNUM, -+ const char *attrs[] = {SYSDB_OBJECTCATEGORY, SYSDB_UIDNUM, - SYSDB_GIDNUM, NULL}; - - tmp_ctx = talloc_new(NULL); -@@ -117,7 +117,7 @@ ifp_cache_get_cached_objects(TALLOC_CTX *mem_ctx, - - ldb_ret = ldb_search(sysdb_ctx_get_ldb(domain->sysdb), tmp_ctx, &result, - base_dn, LDB_SCOPE_SUBTREE, attrs, -- "(&(objectClass=%s)(%s=TRUE))", class, -+ "(&(%s=%s)(%s=TRUE))", SYSDB_OBJECTCATEGORY, class, - SYSDB_IFP_CACHED); - if (ldb_ret != LDB_SUCCESS) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to search the cache\n"); -diff --git a/src/responder/ifp/ifp_groups.c b/src/responder/ifp/ifp_groups.c -index 7503254238eafdafbe2d90fbf7416587be49e1b7..b274b8f52d7908165acc10b91a7d6afe638f1a82 100644 ---- a/src/responder/ifp/ifp_groups.c -+++ b/src/responder/ifp/ifp_groups.c -@@ -841,7 +841,7 @@ ifp_groups_group_get_members(TALLOC_CTX *mem_ctx, - int num_groups; - int i; - errno_t ret; -- const char *attrs[] = {SYSDB_OBJECTCLASS, SYSDB_UIDNUM, -+ const char *attrs[] = {SYSDB_OBJECTCATEGORY, SYSDB_UIDNUM, - SYSDB_GIDNUM, NULL}; - - tmp_ctx = talloc_new(NULL); -@@ -888,7 +888,7 @@ ifp_groups_group_get_members(TALLOC_CTX *mem_ctx, - num_users = 0; - num_groups = 0; - for (i = 0; i < num_members; i++) { -- class = ldb_msg_find_attr_as_string(members[i], SYSDB_OBJECTCLASS, -+ class = ldb_msg_find_attr_as_string(members[i], SYSDB_OBJECTCATEGORY, - NULL); - if (class == NULL) { - ret = ERR_INTERNAL; -diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c -index 86a1f43a2c6e7d785c9d34e350c71f242ff7182f..cb342a245ef6545168a7a60c252505f50576fdf7 100644 ---- a/src/responder/ifp/ifp_users.c -+++ b/src/responder/ifp/ifp_users.c -@@ -1441,7 +1441,7 @@ void ifp_users_user_get_extra_attributes(struct sbus_request *sbus_req, - } - - filter = talloc_asprintf(sbus_req, "(&(%s=%s)(%s=%s))", -- SYSDB_OBJECTCLASS, SYSDB_USER_CLASS, -+ SYSDB_OBJECTCATEGORY, SYSDB_USER_CLASS, - SYSDB_NAME, name); - if (filter == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf() failed\n"); -diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c -index 545257a0be7e91e9de767a57848bb77c5791db4e..956ee53cb88dd24faaa95ac39c8d9540af66cfb2 100644 ---- a/src/responder/nss/nss_cmd.c -+++ b/src/responder/nss/nss_cmd.c -@@ -1148,7 +1148,7 @@ static errno_t nss_cmd_getorigbyname(struct cli_ctx *cli_ctx) - errno_t ret; - struct nss_ctx *nss_ctx; - const char **attrs; -- static const char *defattrs[] = { SYSDB_NAME, SYSDB_OBJECTCLASS, -+ static const char *defattrs[] = { SYSDB_NAME, SYSDB_OBJECTCATEGORY, - SYSDB_SID_STR, - ORIGINALAD_PREFIX SYSDB_NAME, - ORIGINALAD_PREFIX SYSDB_UIDNUM, -diff --git a/src/responder/nss/nss_protocol_grent.c b/src/responder/nss/nss_protocol_grent.c -index 6f6ae57dd97b000ad3cf174b0f649d46981563e2..3550c3f0d375b305d4dbdf3ea19613696448da35 100644 ---- a/src/responder/nss/nss_protocol_grent.c -+++ b/src/responder/nss/nss_protocol_grent.c -@@ -33,7 +33,7 @@ nss_get_grent(TALLOC_CTX *mem_ctx, - errno_t ret; - - /* Check object class. */ -- if (!ldb_msg_check_string_attribute(msg, "objectClass", -+ if (!ldb_msg_check_string_attribute(msg, SYSDB_OBJECTCATEGORY, - SYSDB_GROUP_CLASS)) { - DEBUG(SSSDBG_MINOR_FAILURE, "Wrong object (%s) found on stack!\n", - ldb_dn_get_linearized(msg->dn)); -diff --git a/src/responder/nss/nss_protocol_sid.c b/src/responder/nss/nss_protocol_sid.c -index 61357c2bf92e2f15d978b64a15ad5bd5aa354445..3f60967d750eea3135257ccb597efaa5aa1e2de3 100644 ---- a/src/responder/nss/nss_protocol_sid.c -+++ b/src/responder/nss/nss_protocol_sid.c -@@ -30,9 +30,9 @@ find_sss_id_type(struct ldb_message *msg, - struct ldb_message_element *el; - struct ldb_val *val = NULL; - -- el = ldb_msg_find_element(msg, SYSDB_OBJECTCLASS); -+ el = ldb_msg_find_element(msg, SYSDB_OBJECTCATEGORY); - if (el == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "Objectclass attribute not found.\n"); -+ DEBUG(SSSDBG_OP_FAILURE, "Objectcategory attribute not found.\n"); - return EINVAL; - } - -diff --git a/src/tests/cmocka/test_ad_common.c b/src/tests/cmocka/test_ad_common.c -index 3187af1b004cf3d1ffc1746950faa842f3a05fbc..80b3bb5599a95578b7734d5dfcd20a2a7428a084 100644 ---- a/src/tests/cmocka/test_ad_common.c -+++ b/src/tests/cmocka/test_ad_common.c -@@ -336,7 +336,7 @@ static void test_ad_get_pac_data_from_user_entry(void **state) - - ret = ldb_msg_add_string(user_msg, SYSDB_NAME, "username"); - assert_int_equal(ret, EOK); -- ret = ldb_msg_add_string(user_msg, SYSDB_OBJECTCLASS, "user"); -+ ret = ldb_msg_add_string(user_msg, SYSDB_OBJECTCATEGORY, SYSDB_USER_CLASS); - assert_int_equal(ret, EOK); - ret = ldb_msg_add_string(user_msg, SYSDB_PAC_BLOB_EXPIRE, "12345"); - assert_int_equal(ret, EOK); -diff --git a/src/tests/cmocka/test_ipa_subdomains_server.c b/src/tests/cmocka/test_ipa_subdomains_server.c -index eccfc2fe1e2a224b2cec8ea3184796a23d32febe..1e492e86c1caf26d8890bfa37ebb21321afca366 100644 ---- a/src/tests/cmocka/test_ipa_subdomains_server.c -+++ b/src/tests/cmocka/test_ipa_subdomains_server.c -@@ -455,6 +455,8 @@ static void test_ipa_server_create_trusts_twoway(struct tevent_req *req) - tevent_req_callback_data(req, struct trust_test_ctx); - errno_t ret; - struct sss_domain_info *child_dom; -+ struct ipa_ad_server_ctx *s_trust; -+ struct ipa_ad_server_ctx *c_trust; - - ret = ipa_server_create_trusts_recv(req); - talloc_zfree(req); -@@ -462,9 +464,18 @@ static void test_ipa_server_create_trusts_twoway(struct tevent_req *req) - - /* Trust object should be around now */ - assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); -+ assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); - -+ if (strcmp(test_ctx->ipa_ctx->server_mode->trusts->dom->name, -+ SUBDOM_NAME) == 0) { -+ s_trust = test_ctx->ipa_ctx->server_mode->trusts; -+ c_trust = test_ctx->ipa_ctx->server_mode->trusts->next; -+ } else { -+ s_trust = test_ctx->ipa_ctx->server_mode->trusts->next; -+ c_trust = test_ctx->ipa_ctx->server_mode->trusts; -+ } - /* Two-way trusts should use the system realm */ -- assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts, -+ assert_trust_object(c_trust, - CHILD_NAME, - DOM_REALM, - CHILD_SID, -@@ -472,9 +483,8 @@ static void test_ipa_server_create_trusts_twoway(struct tevent_req *req) - TEST_AUTHID, - DOM_REALM); - -- assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); - -- assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts->next, -+ assert_trust_object(s_trust, - SUBDOM_NAME, - DOM_REALM, - SUBDOM_SID, -@@ -523,6 +533,8 @@ static void test_ipa_server_trust_init(void **state) - errno_t ret; - struct tevent_timer *timeout_handler; - struct timeval tv; -+ struct ipa_ad_server_ctx *s_trust; -+ struct ipa_ad_server_ctx *c_trust; - - add_test_2way_subdomains(test_ctx); - -@@ -537,13 +549,21 @@ static void test_ipa_server_trust_init(void **state) - ret = test_ev_loop(test_ctx->tctx); - assert_int_equal(ret, ERR_OK); - -- assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); -- - /* Trust object should be around now */ - assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); -+ assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); -+ -+ if (strcmp(test_ctx->ipa_ctx->server_mode->trusts->dom->name, -+ SUBDOM_NAME) == 0) { -+ s_trust = test_ctx->ipa_ctx->server_mode->trusts; -+ c_trust = test_ctx->ipa_ctx->server_mode->trusts->next; -+ } else { -+ s_trust = test_ctx->ipa_ctx->server_mode->trusts->next; -+ c_trust = test_ctx->ipa_ctx->server_mode->trusts; -+ } - - /* Two-way trusts should use the system realm */ -- assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts, -+ assert_trust_object(c_trust, - CHILD_NAME, - DOM_REALM, - CHILD_SID, -@@ -551,9 +571,7 @@ static void test_ipa_server_trust_init(void **state) - TEST_AUTHID, - DOM_REALM); - -- assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); -- -- assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts->next, -+ assert_trust_object(s_trust, - SUBDOM_NAME, - DOM_REALM, - SUBDOM_SID, -@@ -708,6 +726,8 @@ static void test_ipa_server_create_trusts_oneway(struct tevent_req *req) - struct trust_test_ctx *test_ctx = \ - tevent_req_callback_data(req, struct trust_test_ctx); - errno_t ret; -+ struct ipa_ad_server_ctx *s_trust; -+ struct ipa_ad_server_ctx *c_trust; - - ret = ipa_server_create_trusts_recv(req); - talloc_zfree(req); -@@ -720,9 +740,19 @@ static void test_ipa_server_create_trusts_oneway(struct tevent_req *req) - - /* Trust object should be around now */ - assert_non_null(test_ctx->ipa_ctx->server_mode->trusts); -+ assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); -+ -+ if (strcmp(test_ctx->ipa_ctx->server_mode->trusts->dom->name, -+ SUBDOM_NAME) == 0) { -+ s_trust = test_ctx->ipa_ctx->server_mode->trusts; -+ c_trust = test_ctx->ipa_ctx->server_mode->trusts->next; -+ } else { -+ s_trust = test_ctx->ipa_ctx->server_mode->trusts->next; -+ c_trust = test_ctx->ipa_ctx->server_mode->trusts; -+ } - - assert_trust_object( -- test_ctx->ipa_ctx->server_mode->trusts, -+ c_trust, - CHILD_NAME, /* AD domain name */ - CHILD_REALM, /* AD realm can be child if SDAP realm is parent's */ - CHILD_SID, -@@ -730,10 +760,8 @@ static void test_ipa_server_create_trusts_oneway(struct tevent_req *req) - ONEWAY_PRINC, /* Principal shared with parent AD dom */ - SUBDOM_REALM); /* SDAP realm must be AD root domain */ - -- assert_non_null(test_ctx->ipa_ctx->server_mode->trusts->next); -- - /* Here all properties point to the AD domain */ -- assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts->next, -+ assert_trust_object(s_trust, - SUBDOM_NAME, - SUBDOM_REALM, - SUBDOM_SID, -diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c -index 4652661087238c18f7fabb398d054db99f77d6cf..fc9936968bcde8370c7054ba303de4463b35e15a 100644 ---- a/src/tests/sysdb-tests.c -+++ b/src/tests/sysdb-tests.c -@@ -503,7 +503,7 @@ static int test_search_all_users(struct test_data *data) - } - - ret = sysdb_search_entry(data, data->ctx->sysdb, base_dn, -- LDB_SCOPE_SUBTREE, "objectClass=user", -+ LDB_SCOPE_SUBTREE, SYSDB_UC, - data->attrlist, &data->msgs_count, &data->msgs); - return ret; - } -@@ -2219,6 +2219,7 @@ START_TEST (test_sysdb_search_all_users) - struct test_data *data; - int ret; - int i; -+ int j; - char *uid_str; - - /* Setup */ -@@ -2253,8 +2254,15 @@ START_TEST (test_sysdb_search_all_users) - "wrong number of values, found [%d] expected [1]", - data->msgs[i]->elements[0].num_values); - -- uid_str = talloc_asprintf(data, "%d", 27010 + i); -- fail_unless(uid_str != NULL, "talloc_asprintf failed."); -+ for (j = 0; j < data->msgs_count; j++) { -+ uid_str = talloc_asprintf(data, "%d", 27010 + j); -+ fail_unless(uid_str != NULL, "talloc_asprintf failed."); -+ if (strncmp(uid_str, -+ (char *) data->msgs[i]->elements[0].values[0].data, -+ data->msgs[i]->elements[0].values[0].length) == 0) { -+ break; -+ } -+ } - fail_unless(strncmp(uid_str, - (char *) data->msgs[i]->elements[0].values[0].data, - data->msgs[i]->elements[0].values[0].length) == 0, -@@ -4411,7 +4419,7 @@ START_TEST(test_SSS_LDB_SEARCH) - - /* Non-empty filter */ - SSS_LDB_SEARCH(ret, test_ctx->sysdb->ldb, test_ctx, &res, group_dn, -- LDB_SCOPE_BASE, NULL, "objectClass=group"); -+ LDB_SCOPE_BASE, NULL, SYSDB_GC); - - fail_unless(ret == EOK, "SSS_LDB_SEARCH error [%d][%s]", - ret, strerror(ret)); -@@ -5203,7 +5211,7 @@ START_TEST (test_sysdb_search_return_ENOENT) - - ret = sysdb_search_entry(test_ctx, test_ctx->sysdb, - user_dn, LDB_SCOPE_SUBTREE, -- "objectClass=user", NULL, -+ SYSDB_UC, NULL, - &count, &msgs); - fail_unless(ret == ENOENT, "sysdb_search_entry failed: %d, %s", - ret, strerror(ret)); -@@ -5215,7 +5223,7 @@ START_TEST (test_sysdb_search_return_ENOENT) - data->username); - fail_if(user_dn == NULL, "sysdb_user_dn failed"); - SSS_LDB_SEARCH(ret, test_ctx->sysdb->ldb, test_ctx, &res, user_dn, -- LDB_SCOPE_BASE, NULL, "objectClass=user"); -+ LDB_SCOPE_BASE, NULL, SYSDB_UC); - - fail_unless(ret == ENOENT, "SSS_LDB_SEARCH failed: %d, %s", - ret, strerror(ret)); -diff --git a/src/tools/sssctl/sssctl_cache.c b/src/tools/sssctl/sssctl_cache.c -index 80f65bb55df42d0b123023bb9b1efdb2353b8e20..42a2a60fd31631b3c86d17ddbdd8027a8468366d 100644 ---- a/src/tools/sssctl/sssctl_cache.c -+++ b/src/tools/sssctl/sssctl_cache.c -@@ -335,7 +335,8 @@ static const char *sssctl_create_filter(TALLOC_CTX *mem_ctx, - talloc_free(filter_value_old); - } - -- filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|(%s=%s)(%s=%s)))", -+ filter = talloc_asprintf(mem_ctx, "(&(%s=%s)(|(%s=%s)(%s=%s)))", -+ obj_type == CACHED_NETGROUP ? SYSDB_OBJECTCLASS : SYSDB_OBJECTCATEGORY, - class, attr_name, filter_value, - SYSDB_NAME_ALIAS, filter_value); - --- -2.14.3 - diff --git a/SOURCES/0056-sysdb-do-not-use-LDB_SCOPE_ONELEVEL.patch b/SOURCES/0056-sysdb-do-not-use-LDB_SCOPE_ONELEVEL.patch deleted file mode 100644 index e0f0758..0000000 --- a/SOURCES/0056-sysdb-do-not-use-LDB_SCOPE_ONELEVEL.patch +++ /dev/null @@ -1,83 +0,0 @@ -From c36d5d56e62f879dbc1c58155097dfc26746a7f4 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 14 Nov 2017 13:09:18 +0100 -Subject: [PATCH 56/57] sysdb: do not use LDB_SCOPE_ONELEVEL -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently the index for one-level searches is a huge blob which maps all -parents with all it children. Handling this blob is costly and since all -searches using LDB_SCOPE_ONELEVEL also have a filter with indexed -attributes a sub-tree search would be more efficient. But since libldb -currently first looks at the scope and hence use the one-level index -blob we have to explicitly use LDB_SCOPE_SUBTREE in the callers to use -the more efficient attribute based inxed. - -Related to https://pagure.io/SSSD/sssd/issue/3503 - -Reviewed-by: Jakub Hrozek -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 98195e591c4d97caa6125e8214879660b740973f) ---- - src/db/sysdb_autofs.c | 2 +- - src/db/sysdb_ranges.c | 2 +- - src/db/sysdb_subdomains.c | 2 +- - src/responder/ifp/ifp_users.c | 2 +- - 4 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/db/sysdb_autofs.c b/src/db/sysdb_autofs.c -index b3e9b4ec83b66ec65a72ab7a3180106e2293d8a5..89803a778c370c899611ee5e15b7ae1a48e82cb9 100644 ---- a/src/db/sysdb_autofs.c -+++ b/src/db/sysdb_autofs.c -@@ -384,7 +384,7 @@ sysdb_autofs_entries_by_map(TALLOC_CTX *mem_ctx, - goto done; - } - -- ret = sysdb_search_entry(tmp_ctx, domain->sysdb, mapdn, LDB_SCOPE_ONELEVEL, -+ ret = sysdb_search_entry(tmp_ctx, domain->sysdb, mapdn, LDB_SCOPE_SUBTREE, - filter, attrs, &count, &msgs); - if (ret != EOK && ret != ENOENT) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb search failed: %d\n", ret); -diff --git a/src/db/sysdb_ranges.c b/src/db/sysdb_ranges.c -index 511e4785d9aa68b2a33b440e1c5ee62e5ccf7ce4..be3a0d37220f833d27417808ddfef0e74c0ba9b2 100644 ---- a/src/db/sysdb_ranges.c -+++ b/src/db/sysdb_ranges.c -@@ -71,7 +71,7 @@ errno_t sysdb_get_ranges(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, - goto done; - } - ret = ldb_search(sysdb->ldb, tmp_ctx, &res, -- basedn, LDB_SCOPE_ONELEVEL, -+ basedn, LDB_SCOPE_SUBTREE, - attrs, "objectclass=%s", SYSDB_ID_RANGE_CLASS); - if (ret != LDB_SUCCESS) { - ret = EIO; -diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c -index 353561765904efe4bd698c38949a1b290ecf0b80..0dd05c24c963f12a28ef6f6b64dc40faa7fcc649 100644 ---- a/src/db/sysdb_subdomains.c -+++ b/src/db/sysdb_subdomains.c -@@ -338,7 +338,7 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain, - goto done; - } - ret = ldb_search(domain->sysdb->ldb, tmp_ctx, &res, -- basedn, LDB_SCOPE_ONELEVEL, -+ basedn, LDB_SCOPE_SUBTREE, - attrs, "objectclass=%s", SYSDB_SUBDOMAIN_CLASS); - if (ret != LDB_SUCCESS) { - ret = EIO; -diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c -index cb342a245ef6545168a7a60c252505f50576fdf7..f66587b8cf81a555dd1cb7aff12e0c8347c250b1 100644 ---- a/src/responder/ifp/ifp_users.c -+++ b/src/responder/ifp/ifp_users.c -@@ -1449,7 +1449,7 @@ void ifp_users_user_get_extra_attributes(struct sbus_request *sbus_req, - } - - ret = sysdb_search_entry(sbus_req, domain->sysdb, basedn, -- LDB_SCOPE_ONELEVEL, filter, -+ LDB_SCOPE_SUBTREE, filter, - extra, &count, &user); - if (ret != EOK) { - DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup user [%d]: %s\n", --- -2.14.3 - diff --git a/SOURCES/0057-sysdb-remove-IDXONE-and-objectClass-from-users-and-g.patch b/SOURCES/0057-sysdb-remove-IDXONE-and-objectClass-from-users-and-g.patch deleted file mode 100644 index 278541e..0000000 --- a/SOURCES/0057-sysdb-remove-IDXONE-and-objectClass-from-users-and-g.patch +++ /dev/null @@ -1,384 +0,0 @@ -From 0f907d8501387ec32dbb00e1c38d5da25e698f90 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 14 Nov 2017 13:14:14 +0100 -Subject: [PATCH 57/57] sysdb: remove IDXONE and objectClass from users and - groups -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This patch does the needed sysdb update for the previous to patches. It -removes the one-level search index IDXONE and replaces objectClass with -objectCategory in the user and group objects. - -Related to https://pagure.io/SSSD/sssd/issue/3503 - -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Jakub Hrozek -(cherry picked from commit 2927da49dd8a16fff6312d89ad43cc355655800c) ---- - src/db/sysdb_init.c | 52 +++++++++++- - src/db/sysdb_private.h | 11 ++- - src/db/sysdb_upgrade.c | 217 +++++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 274 insertions(+), 6 deletions(-) - -diff --git a/src/db/sysdb_init.c b/src/db/sysdb_init.c -index 44a7918f603fe1368b7d81738666de6bb47b83d0..74ad23f3050da0ae14fa495d2302f4a858fcd3c5 100644 ---- a/src/db/sysdb_init.c -+++ b/src/db/sysdb_init.c -@@ -359,8 +359,48 @@ static errno_t sysdb_ts_cache_upgrade(TALLOC_CTX *mem_ctx, - const char *cur_version, - const char **_new_version) - { -- /* Currently the sysdb cache only has one version */ -- return EFAULT; -+ errno_t ret; -+ TALLOC_CTX *tmp_ctx; -+ const char *version; -+ struct ldb_context *save_ldb; -+ -+ tmp_ctx = talloc_new(NULL); -+ if (tmp_ctx == NULL) { -+ return ENOMEM; -+ } -+ -+ /* The upgrade process depends on having ldb around, yet the upgrade -+ * function shouldn't set the ldb pointer, only the connect function -+ * should after it's successful. To avoid hard refactoring, save the -+ * ldb pointer here and restore in the 'done' handler -+ */ -+ save_ldb = sysdb->ldb; -+ sysdb->ldb = ldb; -+ -+ version = talloc_strdup(tmp_ctx, cur_version); -+ if (version == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "Upgrading timstamp cache of DB [%s] from version: %s\n", -+ domain->name, version); -+ -+ if (strcmp(version, SYSDB_TS_VERSION_0_1) == 0) { -+ ret = sysdb_ts_upgrade_01(sysdb, &version); -+ if (ret != EOK) { -+ goto done; -+ } -+ } -+ -+ ret = EOK; -+ -+done: -+ sysdb->ldb = save_ldb; -+ *_new_version = version; -+ talloc_free(tmp_ctx); -+ return ret; - } - - static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx, -@@ -511,6 +551,14 @@ static errno_t sysdb_domain_cache_upgrade(TALLOC_CTX *mem_ctx, - } - } - -+ if (strcmp(version, SYSDB_VERSION_0_19) == 0) { -+ ret = sysdb_upgrade_19(sysdb, &version); -+ if (ret != EOK) { -+ goto done; -+ } -+ } -+ -+ - ret = EOK; - done: - sysdb->ldb = save_ldb; -diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h -index dbd75615bc212e73c4338a76dceaa68a5889ed1d..cac06ba46da23080d1ab661502d0792bd37b9291 100644 ---- a/src/db/sysdb_private.h -+++ b/src/db/sysdb_private.h -@@ -23,6 +23,7 @@ - #ifndef __INT_SYS_DB_H__ - #define __INT_SYS_DB_H__ - -+#define SYSDB_VERSION_0_20 "0.20" - #define SYSDB_VERSION_0_19 "0.19" - #define SYSDB_VERSION_0_18 "0.18" - #define SYSDB_VERSION_0_17 "0.17" -@@ -43,7 +44,7 @@ - #define SYSDB_VERSION_0_2 "0.2" - #define SYSDB_VERSION_0_1 "0.1" - --#define SYSDB_VERSION SYSDB_VERSION_0_19 -+#define SYSDB_VERSION SYSDB_VERSION_0_20 - - #define SYSDB_BASE_LDIF \ - "dn: @ATTRIBUTES\n" \ -@@ -72,7 +73,6 @@ - "@IDXATTR: sudoUser\n" \ - "@IDXATTR: sshKnownHostsExpire\n" \ - "@IDXATTR: objectSIDString\n" \ -- "@IDXONE: 1\n" \ - "@IDXATTR: ghost\n" \ - "@IDXATTR: userPrincipalName\n" \ - "@IDXATTR: canonicalUserPrincipalName\n" \ -@@ -92,9 +92,10 @@ - "\n" - - /* The timestamp cache has its own versioning */ -+#define SYSDB_TS_VERSION_0_2 "0.2" - #define SYSDB_TS_VERSION_0_1 "0.1" - --#define SYSDB_TS_VERSION SYSDB_TS_VERSION_0_1 -+#define SYSDB_TS_VERSION SYSDB_TS_VERSION_0_2 - - #define SYSDB_TS_BASE_LDIF \ - "dn: @ATTRIBUTES\n" \ -@@ -103,7 +104,6 @@ - "dn: @INDEXLIST\n" \ - "@IDXATTR: lastUpdate\n" \ - "@IDXATTR: dataExpireTimestamp\n" \ -- "@IDXONE: 1\n" \ - "\n" \ - "dn: cn=sysdb\n" \ - "cn: sysdb\n" \ -@@ -169,6 +169,9 @@ int sysdb_upgrade_17(struct sysdb_ctx *sysdb, - struct sysdb_dom_upgrade_ctx *upgrade_ctx, - const char **ver); - int sysdb_upgrade_18(struct sysdb_ctx *sysdb, const char **ver); -+int sysdb_upgrade_19(struct sysdb_ctx *sysdb, const char **ver); -+ -+int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver); - - int sysdb_add_string(struct ldb_message *msg, - const char *attr, const char *value); -diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c -index 365d45f7ebd78523ca9ec4b9c2158cc09acb5489..bc157a24664239bc1255e49a1825243a07acc90f 100644 ---- a/src/db/sysdb_upgrade.c -+++ b/src/db/sysdb_upgrade.c -@@ -2317,6 +2317,223 @@ done: - return ret; - } - -+static errno_t add_object_category(struct ldb_context *ldb, -+ struct upgrade_ctx *ctx) -+{ -+ errno_t ret; -+ struct ldb_result *objects = NULL; -+ const char *attrs[] = { SYSDB_OBJECTCLASS, NULL }; -+ struct ldb_dn *base_dn; -+ size_t c; -+ const char *class_name; -+ struct ldb_message *msg = NULL; -+ struct ldb_message *del_msg = NULL; -+ -+ base_dn = ldb_dn_new(ctx, ldb, SYSDB_BASE); -+ if (base_dn == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed create base dn.\n"); -+ return ENOMEM; -+ } -+ -+ ret = ldb_search(ldb, ctx, &objects, base_dn, -+ LDB_SCOPE_SUBTREE, attrs, -+ "(|("SYSDB_OBJECTCLASS"="SYSDB_USER_CLASS")" -+ "("SYSDB_OBJECTCLASS"="SYSDB_GROUP_CLASS"))"); -+ talloc_free(base_dn); -+ if (ret != LDB_SUCCESS) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to search objects: %d\n", ret); -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ -+ if (objects == NULL || objects->count == 0) { -+ DEBUG(SSSDBG_TRACE_LIBS, "No objects found, nothing to do."); -+ ret = EOK; -+ goto done; -+ } -+ -+ del_msg = ldb_msg_new(ctx); -+ if (del_msg == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ ret = ldb_msg_add_empty(del_msg, SYSDB_OBJECTCLASS, LDB_FLAG_MOD_DELETE, -+ NULL); -+ if (ret != LDB_SUCCESS) { -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ -+ DEBUG(SSSDBG_TRACE_ALL, "Found [%d] objects.\n", objects->count); -+ for (c = 0; c < objects->count; c++) { -+ DEBUG(SSSDBG_TRACE_ALL, "Updating [%s].\n", -+ ldb_dn_get_linearized(objects->msgs[c]->dn)); -+ -+ class_name = ldb_msg_find_attr_as_string(objects->msgs[c], -+ SYSDB_OBJECTCLASS, NULL); -+ if (class_name == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "Searched objects by objectClass, " -+ "but result does not have one.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ talloc_free(msg); -+ msg = ldb_msg_new(ctx); -+ if (msg == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ msg->dn = objects->msgs[c]->dn; -+ del_msg->dn = objects->msgs[c]->dn; -+ -+ ret = ldb_msg_add_empty(msg, SYSDB_OBJECTCATEGORY, LDB_FLAG_MOD_ADD, -+ NULL); -+ if (ret != LDB_SUCCESS) { -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ -+ ret = ldb_msg_add_string(msg, SYSDB_OBJECTCATEGORY, class_name); -+ if (ret != LDB_SUCCESS) { -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed.\n"); -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ -+ DEBUG(SSSDBG_TRACE_ALL, "Adding [%s] to [%s].\n", class_name, -+ ldb_dn_get_linearized(objects->msgs[c]->dn)); -+ ret = ldb_modify(ldb, msg); -+ if (ret != LDB_SUCCESS) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Failed to add objectCategory to %s: %d.\n", -+ ldb_dn_get_linearized(objects->msgs[c]->dn), -+ sysdb_error_to_errno(ret)); -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ -+ ret = ldb_modify(ldb, del_msg); -+ if (ret != LDB_SUCCESS) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Failed to remove objectClass from %s: %d.\n", -+ ldb_dn_get_linearized(objects->msgs[c]->dn), -+ sysdb_error_to_errno(ret)); -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ } -+ -+ ret = EOK; -+ -+done: -+ talloc_free(msg); -+ talloc_free(del_msg); -+ talloc_free(objects); -+ -+ return ret; -+} -+ -+int sysdb_upgrade_19(struct sysdb_ctx *sysdb, const char **ver) -+{ -+ struct upgrade_ctx *ctx; -+ errno_t ret; -+ struct ldb_message *msg = NULL; -+ -+ ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_VERSION_0_20, &ctx); -+ if (ret) { -+ return ret; -+ } -+ -+ ret = add_object_category(sysdb->ldb, ctx); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "add_object_category failed.\n"); -+ goto done; -+ } -+ -+ /* Remove @IDXONE from index */ -+ msg = ldb_msg_new(ctx); -+ if (msg == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ msg->dn = ldb_dn_new(msg, sysdb->ldb, "@INDEXLIST"); -+ if (msg->dn == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_DELETE, NULL); -+ if (ret != LDB_SUCCESS) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = ldb_modify(sysdb->ldb, msg); -+ if (ret != LDB_SUCCESS) { -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ -+ /* conversion done, update version number */ -+ ret = update_version(ctx); -+ -+done: -+ ret = finish_upgrade(ret, &ctx, ver); -+ return ret; -+} -+ -+int sysdb_ts_upgrade_01(struct sysdb_ctx *sysdb, const char **ver) -+{ -+ struct upgrade_ctx *ctx; -+ errno_t ret; -+ struct ldb_message *msg = NULL; -+ -+ ret = commence_upgrade(sysdb, sysdb->ldb, SYSDB_TS_VERSION_0_2, &ctx); -+ if (ret) { -+ return ret; -+ } -+ -+ /* Remove @IDXONE from index */ -+ talloc_free(msg); -+ msg = ldb_msg_new(ctx); -+ if (msg == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ msg->dn = ldb_dn_new(msg, sysdb->ldb, "@INDEXLIST"); -+ if (msg->dn == NULL) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = ldb_msg_add_empty(msg, "@IDXONE", LDB_FLAG_MOD_DELETE, NULL); -+ if (ret != LDB_SUCCESS) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = ldb_modify(sysdb->ldb, msg); -+ if (ret != LDB_SUCCESS) { -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ -+ /* conversion done, update version number */ -+ ret = update_version(ctx); -+ -+done: -+ ret = finish_upgrade(ret, &ctx, ver); -+ return ret; -+} -+ - /* - * Example template for future upgrades. - * Copy and change version numbers as appropriate. --- -2.14.3 - diff --git a/SOURCES/0058-mmap_cache-make-checks-independent-of-input-size.patch b/SOURCES/0058-mmap_cache-make-checks-independent-of-input-size.patch deleted file mode 100644 index cc91c58..0000000 --- a/SOURCES/0058-mmap_cache-make-checks-independent-of-input-size.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 531c0ad3e13ddc1f5c31a620aa1f8b91aa8a4053 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 17 Nov 2017 10:51:44 +0100 -Subject: [PATCH 58/59] mmap_cache: make checks independent of input size -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently the consistency checks for the mmap_cache payload data on the -client and the responder side include the length of the input string of -the current request. Since there might be hash collisions which other -much longer or much shorter names those checks might fail although there -is no data corruption. - -This patch removes the checks using the length of the input and adds a -check if the name found in the payload is zero-terminated inside of the -payload data. - -Resolves https://pagure.io/SSSD/sssd/issue/3571 - -Reviewed-by: Michal Židek -Reviewed-by: Lukáš Slebodník -(cherry picked from commit 4382047490dd4f80b407cc1e618da048f13e5f8f) ---- - src/responder/nss/nsssrv_mmap_cache.c | 34 ++++++++++++++++++++++++---------- - src/sss_client/nss_mc_group.c | 14 ++++++++------ - src/sss_client/nss_mc_initgr.c | 14 +++++++++----- - src/sss_client/nss_mc_passwd.c | 14 ++++++++------ - 4 files changed, 49 insertions(+), 27 deletions(-) - -diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c -index a87ad646f9b741db3eb18680678697032fc420ba..ad5adbce15e50c065d4d16e626be97fd23d06643 100644 ---- a/src/responder/nss/nsssrv_mmap_cache.c -+++ b/src/responder/nss/nsssrv_mmap_cache.c -@@ -547,18 +547,32 @@ static struct sss_mc_rec *sss_mc_find_record(struct sss_mc_ctx *mcc, - return NULL; - } - -+ if (key->len > strs_len) { -+ /* The string cannot be in current record */ -+ slot = sss_mc_next_slot_with_hash(rec, hash); -+ continue; -+ } -+ - safealign_memcpy(&name_ptr, rec->data, sizeof(rel_ptr_t), NULL); -- if (key->len > strs_len -- || (name_ptr + key->len) > (strs_offset + strs_len) -- || (uint8_t *)rec->data + strs_offset + strs_len > max_addr) { -- DEBUG(SSSDBG_FATAL_FAILURE, -- "Corrupted fastcache. name_ptr value is %u.\n", name_ptr); -- sss_mc_save_corrupted(mcc); -- sss_mmap_cache_reset(mcc); -- return NULL; -- } -- - t_key = (char *)rec->data + name_ptr; -+ /* name_ptr must point to some data in the strs/gids area of the data -+ * payload. Since it is a pointer relative to rec->data it must larger -+ * equal strs_offset and must be smaller then strs_offset + strs_len. -+ * Additionally the area must not end outside of the data table and -+ * t_key must be a zero-terminates string. */ -+ if (name_ptr < strs_offset -+ || name_ptr >= strs_offset + strs_len -+ || (uint8_t *)rec->data > max_addr -+ || strs_offset > max_addr - (uint8_t *)rec->data -+ || strs_len > max_addr - (uint8_t *)rec->data - strs_offset) { -+ DEBUG(SSSDBG_FATAL_FAILURE, -+ "Corrupted fastcache entry at slot %u. " -+ "name_ptr value is %u.\n", slot, name_ptr); -+ sss_mc_save_corrupted(mcc); -+ sss_mmap_cache_reset(mcc); -+ return NULL; -+ } -+ - if (strcmp(key->str, t_key) == 0) { - break; - } -diff --git a/src/sss_client/nss_mc_group.c b/src/sss_client/nss_mc_group.c -index ce88d42fdaf4f19e78fc43e187bc28651cdc3c4e..4b1601a171a3af700b6f0d2bfedb3a6198e6df6d 100644 ---- a/src/sss_client/nss_mc_group.c -+++ b/src/sss_client/nss_mc_group.c -@@ -148,20 +148,22 @@ errno_t sss_nss_mc_getgrnam(const char *name, size_t name_len, - } - - data = (struct sss_mc_grp_data *)rec->data; -+ rec_name = (char *)data + data->name; - /* Integrity check -- * - name_len cannot be longer than all strings - * - data->name cannot point outside strings - * - all strings must be within copy of record -- * - size of record must be lower that data table size */ -- if (name_len > data->strs_len -- || (data->name + name_len) > (strs_offset + data->strs_len) -+ * - record must not end outside data table -+ * - rec_name is a zero-terminated string */ -+ if (data->name < strs_offset -+ || data->name >= strs_offset + data->strs_len - || data->strs_len > rec->len -- || rec->len > data_size) { -+ || (uint8_t *) rec + rec->len > gr_mc_ctx.data_table + data_size -+ || memchr(rec_name, '\0', -+ (strs_offset + data->strs_len) - data->name) == NULL) { - ret = ENOENT; - goto done; - } - -- rec_name = (char *)data + data->name; - if (strcmp(name, rec_name) == 0) { - break; - } -diff --git a/src/sss_client/nss_mc_initgr.c b/src/sss_client/nss_mc_initgr.c -index a77088d849ad3601cb3edb55fc5ea4ae4c52fe38..d8c01f52ea2d23515d0b462541657dc9416b0915 100644 ---- a/src/sss_client/nss_mc_initgr.c -+++ b/src/sss_client/nss_mc_initgr.c -@@ -131,15 +131,19 @@ errno_t sss_nss_mc_initgroups_dyn(const char *name, size_t name_len, - data = (struct sss_mc_initgr_data *)rec->data; - rec_name = (char *)data + data->name; - /* Integrity check -- * - name_len cannot be longer than all strings or data -+ * - data->name cannot point outside all strings or data - * - all data must be within copy of record - * - size of record must be lower that data table size -- * - data->strs cannot point outside strings */ -- if (name_len > data->strs_len -+ * - data->strs cannot point outside strings -+ * - rec_name is a zero-terminated string */ -+ if (data->name < data_offset -+ || data->name >= data_offset + data->data_len - || data->strs_len > data->data_len - || data->data_len > rec->len -- || rec->len > data_size -- || (data->strs + name_len) > (data_offset + data->data_len)) { -+ || (uint8_t *) rec + rec->len -+ > initgr_mc_ctx.data_table + data_size -+ || memchr(rec_name, '\0', -+ (data_offset + data->data_len) - data->name) == NULL) { - ret = ENOENT; - goto done; - } -diff --git a/src/sss_client/nss_mc_passwd.c b/src/sss_client/nss_mc_passwd.c -index 0da7ad0aeece7d38ca34bb3fde64adc898eaf0ae..868427f03a7ec0c8bd7401c8547a6f6bead7af28 100644 ---- a/src/sss_client/nss_mc_passwd.c -+++ b/src/sss_client/nss_mc_passwd.c -@@ -141,20 +141,22 @@ errno_t sss_nss_mc_getpwnam(const char *name, size_t name_len, - } - - data = (struct sss_mc_pwd_data *)rec->data; -+ rec_name = (char *)data + data->name; - /* Integrity check -- * - name_len cannot be longer than all strings - * - data->name cannot point outside strings - * - all strings must be within copy of record -- * - size of record must be lower that data table size */ -- if (name_len > data->strs_len -- || (data->name + name_len) > (strs_offset + data->strs_len) -+ * - record must not end outside data table -+ * - rec_name is a zero-terminated string */ -+ if (data->name < strs_offset -+ || data->name >= strs_offset + data->strs_len - || data->strs_len > rec->len -- || rec->len > data_size) { -+ || (uint8_t *) rec + rec->len > pw_mc_ctx.data_table + data_size -+ || memchr(rec_name, '\0', -+ (strs_offset + data->strs_len) - data->name) == NULL ) { - ret = ENOENT; - goto done; - } - -- rec_name = (char *)data + data->name; - if (strcmp(name, rec_name) == 0) { - break; - } --- -2.14.3 - diff --git a/SOURCES/0059-NSS-Fix-covscan-warning.patch b/SOURCES/0059-NSS-Fix-covscan-warning.patch deleted file mode 100644 index 2dfd5be..0000000 --- a/SOURCES/0059-NSS-Fix-covscan-warning.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 2fd201a6e8f263f30fb3aeb3d7f826a06321e58e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= -Date: Tue, 21 Nov 2017 16:12:24 +0100 -Subject: [PATCH 59/59] NSS: Fix covscan warning -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - - Error: NULL_RETURNS (CWE-476): [#def1] - sssd-1.16.1/src/responder/nss/nss_protocol.c:162: returned_null: "memchr" returns null (checked 7 out of 8 times). - sssd-1.16.1/src/responder/nss/nsssrv_mmap_cache.c:557: example_checked: Example 1: "memchr(t_key, 0, strs_offset + strs_len - name_ptr)" has its value checked in "memchr(t_key, 0, strs_offset + strs_len - name_ptr) == NULL". - sssd-1.16.1/src/sss_client/idmap/sss_nss_idmap.c:171: example_assign: Example 2: Assigning: "p" = return value from "memchr(p, 0, buf_len - (p - buf))". - sssd-1.16.1/src/sss_client/idmap/sss_nss_idmap.c:172: example_checked: Example 2 (cont.): "p" has its value checked in "p == NULL". - sssd-1.16.1/src/sss_client/nss_mc_group.c:157: example_checked: Example 3: "memchr(rec_name, 0, 16UL + data->strs_len - data->name)" has its value checked in "memchr(rec_name, 0, 16UL + data->strs_len - data->name) == NULL". - sssd-1.16.1/src/sss_client/nss_mc_initgr.c:139: example_checked: Example 4: "memchr(rec_name, 0, 24UL + data->data_len - data->name)" has its value checked in "memchr(rec_name, 0, 24UL + data->data_len - data->name) == NULL". - sssd-1.16.1/src/sss_client/nss_mc_passwd.c:150: example_checked: Example 5: "memchr(rec_name, 0, 16UL + data->strs_len - data->name)" has its value checked in "memchr(rec_name, 0, 16UL + data->strs_len - data->name) == NULL". - sssd-1.16.1/src/responder/nss/nss_protocol.c:162: var_assigned: Assigning: "p" = null return value from "memchr". - sssd-1.16.1/src/responder/nss/nss_protocol.c:176: dereference: Incrementing a pointer which might be null: "p". - # 174| } - # 175| - # 176|-> p++; - # 177| if ((p - body) + sizeof(uint32_t) != blen) { - # 178| DEBUG(SSSDBG_CRIT_FAILURE, "Body has unexpected size!\n"); - -Signed-off-by: Fabiano Fidêncio - -Reviewed-by: Lukáš Slebodník -Reviewed-by: Michal Židek -(cherry picked from commit 1d88a0591ce8445ea3b6a88845a5997d61c915b4) ---- - src/responder/nss/nss_protocol.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/responder/nss/nss_protocol.c b/src/responder/nss/nss_protocol.c -index 2655386498754c46fbb363bdd1f976f9ded6a434..13f6d1541b79bf5494e1560841f027bf98bef72b 100644 ---- a/src/responder/nss/nss_protocol.c -+++ b/src/responder/nss/nss_protocol.c -@@ -160,6 +160,13 @@ nss_protocol_parse_name_ex(struct cli_ctx *cli_ctx, const char **_rawname, - } - - p = memchr(body, '\0', blen); -+ /* Although body for sure is null terminated, let's add this check here -+ * so static analyzers are happier. */ -+ if (p == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "memchr() returned NULL, body is not null terminated!\n"); -+ return EINVAL; -+ } - - /* If the body isn't valid UTF-8, fail */ - if (!sss_utf8_check(body, (p - body))) { --- -2.14.3 - diff --git a/SOURCES/0060-responder-Fix-talloc-hierarchy-in-sized_output_name.patch b/SOURCES/0060-responder-Fix-talloc-hierarchy-in-sized_output_name.patch deleted file mode 100644 index dc76425..0000000 --- a/SOURCES/0060-responder-Fix-talloc-hierarchy-in-sized_output_name.patch +++ /dev/null @@ -1,59 +0,0 @@ -From af95dd657586d3fc5680a7f8b493a5502640235e Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Tue, 28 Nov 2017 12:19:54 +0100 -Subject: [PATCH 60/67] responder: Fix talloc hierarchy in sized_output_name -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -sized_output_name was a called with NULL context in -memcache_delete_entry but returned data from sized_output_name -didn't have proper talloc hierarchy and we could not release all -all returned data. - -==00:01:01:29.871 10088== 934,414 bytes in 8,731 blocks are definitely lost in loss record 121 of 121 -==00:01:01:29.871 10088== at 0x4C29BE3: malloc (vg_replace_malloc.c:299) -==00:01:01:29.871 10088== by 0x8FF4EAB: talloc_strdup (in /usr/lib64/libtalloc.so.2.1.9) -==00:01:01:29.871 10088== by 0x52933B9: sss_output_name (usertools.c:808) -==00:01:01:29.871 10088== by 0x5293550: sss_output_fqname (usertools.c:863) -==00:01:01:29.871 10088== by 0x1211F9: sized_output_name (responder_common.c:1708) -==00:01:01:29.871 10088== by 0x1137E6: memcache_delete_entry (nss_get_object.c:112) -==00:01:01:29.871 10088== by 0x113BB6: nss_get_object_done (nss_get_object.c:245) -==00:01:01:29.871 10088== by 0x8DE5291: _tevent_req_error (in /usr/lib64/libtevent.so.0.9.31) -==00:01:01:29.871 10088== by 0x1276CE: cache_req_done (cache_req.c:1047) -==00:01:01:29.871 10088== by 0x8DE5291: _tevent_req_error (in /usr/lib64/libtevent.so.0.9.31) -==00:01:01:29.871 10088== by 0x126AF6: cache_req_search_domains_done (cache_req.c:607) -==00:01:01:29.871 10088== by 0x8DE4AB9: tevent_common_loop_immediate (in /usr/lib64/libtevent.so.0.9.31) -==00:01:01:29.871 10088== by 0x8DE9C9C: ??? (in /usr/lib64/libtevent.so.0.9.31) -==00:01:01:29.871 10088== by 0x8DE82A6: ??? (in /usr/lib64/libtevent.so.0.9.31) -==00:01:01:29.871 10088== by 0x8DE40CC: _tevent_loop_once (in /usr/lib64/libtevent.so.0.9.31) -==00:01:01:29.871 10088== by 0x8DE42FA: tevent_common_loop_wait (in /usr/lib64/libtevent.so.0.9.31) -==00:01:01:29.871 10088== by 0x8DE8246: ??? (in /usr/lib64/libtevent.so.0.9.31) -==00:01:01:29.871 10088== by 0x5291B32: server_loop (server.c:718) -==00:01:01:29.871 10088== by 0x11004C: main (nsssrv.c:560) - -Resolves: -https://pagure.io/SSSD/sssd/issue/3588 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 06e741a9bf23a18a998f366d9a8990b887a01638) ---- - src/responder/common/responder_common.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c -index 6b4d2d9e5936c79944b6f883e9fe46fd03ff32f6..e1100ce4b1eaae8bc561246699dc9bacc96133c8 100644 ---- a/src/responder/common/responder_common.c -+++ b/src/responder/common/responder_common.c -@@ -1815,7 +1815,7 @@ int sized_output_name(TALLOC_CTX *mem_ctx, - goto done; - } - -- ret = sss_output_fqname(mem_ctx, name_dom, orig_name, -+ ret = sss_output_fqname(name, name_dom, orig_name, - rctx->override_space, &name_str); - if (ret != EOK) { - goto done; --- -2.14.3 - diff --git a/SOURCES/0061-test_responder-Check-memory-leak-in-sized_output_nam.patch b/SOURCES/0061-test_responder-Check-memory-leak-in-sized_output_nam.patch deleted file mode 100644 index 79da5fd..0000000 --- a/SOURCES/0061-test_responder-Check-memory-leak-in-sized_output_nam.patch +++ /dev/null @@ -1,58 +0,0 @@ -From d624420972d061f72b08727bd7b2e227ce047272 Mon Sep 17 00:00:00 2001 -From: Lukas Slebodnik -Date: Tue, 28 Nov 2017 12:20:26 +0100 -Subject: [PATCH 61/67] test_responder: Check memory leak in sized_output_name -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Resolves: -https://pagure.io/SSSD/sssd/issue/3588 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 051e0fc7cc86fb4e4b3a9323a61684ad3a6fa589) ---- - src/tests/cmocka/test_responder_common.c | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/src/tests/cmocka/test_responder_common.c b/src/tests/cmocka/test_responder_common.c -index fb7e4ee500570319999e6e85ee14a05cddea8de3..5441167caeb284982ee76926117da029966ec997 100644 ---- a/src/tests/cmocka/test_responder_common.c -+++ b/src/tests/cmocka/test_responder_common.c -@@ -316,6 +316,23 @@ void test_schedule_get_domains_task(void **state) - talloc_free(dummy_ncache_ptr); - } - -+void test_sss_output_fqname(void **state) -+{ -+ struct parse_inp_test_ctx *parse_inp_ctx = talloc_get_type(*state, -+ struct parse_inp_test_ctx); -+ errno_t ret; -+ struct sized_string *res = NULL; -+ -+ ret = sized_output_name(parse_inp_ctx, parse_inp_ctx->rctx, "dummy", -+ parse_inp_ctx->tctx->dom, &res); -+ assert_int_equal(ret, EOK); -+ assert_non_null(res); -+ assert_string_equal("dummy", res->str); -+ assert_int_equal(6, res->len); -+ -+ talloc_zfree(res); -+} -+ - int main(int argc, const char *argv[]) - { - int rv; -@@ -346,6 +363,9 @@ int main(int argc, const char *argv[]) - cmocka_unit_test_setup_teardown(test_schedule_get_domains_task, - parse_inp_test_setup, - parse_inp_test_teardown), -+ cmocka_unit_test_setup_teardown(test_sss_output_fqname, -+ parse_inp_test_setup, -+ parse_inp_test_teardown), - }; - - /* Set debug level to invalid value so we can deside if -d 0 was used. */ --- -2.14.3 - diff --git a/SOURCES/0062-UTIL-add-find_domain_by_object_name_ex.patch b/SOURCES/0062-UTIL-add-find_domain_by_object_name_ex.patch deleted file mode 100644 index 321cedc..0000000 --- a/SOURCES/0062-UTIL-add-find_domain_by_object_name_ex.patch +++ /dev/null @@ -1,82 +0,0 @@ -From ab9a8db7539bea30effe398d9bd82b1ecadd8a6f Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 20 Nov 2017 12:08:30 +0100 -Subject: [PATCH 62/67] UTIL: add find_domain_by_object_name_ex() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The _ex version of find_domain_by_object_name() has a additional option -'strict'. If set to 'true' NULL is return instead to domain from the -first argument. This way the caller can see if the provider object name -really contains a known domain. - -Related to https://pagure.io/SSSD/sssd/issue/3579 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit b6d3da6cfe78c6d0ddb854088bc23e293b336401) ---- - src/util/domain_info_utils.c | 17 ++++++++++++++--- - src/util/util.h | 4 ++++ - 2 files changed, 18 insertions(+), 3 deletions(-) - -diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c -index 3a3f5130a32e2c5fe4b81819bf2de697a4474111..66077092a40111967a98b0937506d9e4472f50d5 100644 ---- a/src/util/domain_info_utils.c -+++ b/src/util/domain_info_utils.c -@@ -174,8 +174,8 @@ sss_get_domain_by_sid_ldap_fallback(struct sss_domain_info *domain, - } - - struct sss_domain_info * --find_domain_by_object_name(struct sss_domain_info *domain, -- const char *object_name) -+find_domain_by_object_name_ex(struct sss_domain_info *domain, -+ const char *object_name, bool strict) - { - TALLOC_CTX *tmp_ctx; - struct sss_domain_info *dom = NULL; -@@ -197,7 +197,11 @@ find_domain_by_object_name(struct sss_domain_info *domain, - } - - if (domainname == NULL) { -- dom = domain; -+ if (strict) { -+ dom = NULL; -+ } else { -+ dom = domain; -+ } - } else { - dom = find_domain_by_name(domain, domainname, true); - } -@@ -207,6 +211,13 @@ done: - return dom; - } - -+struct sss_domain_info * -+find_domain_by_object_name(struct sss_domain_info *domain, -+ const char *object_name) -+{ -+ return find_domain_by_object_name_ex(domain, object_name, false); -+} -+ - errno_t sssd_domain_init(TALLOC_CTX *mem_ctx, - struct confdb_ctx *cdb, - const char *domain_name, -diff --git a/src/util/util.h b/src/util/util.h -index 37383011763a9a2a3c2c066215e3ed94aca77308..2521b1789b0b8701b1fbcce33890eedb7fe18d5e 100644 ---- a/src/util/util.h -+++ b/src/util/util.h -@@ -551,6 +551,10 @@ struct sss_domain_info * - find_domain_by_object_name(struct sss_domain_info *domain, - const char *object_name); - -+struct sss_domain_info * -+find_domain_by_object_name_ex(struct sss_domain_info *domain, -+ const char *object_name, bool strict); -+ - bool subdomain_enumerates(struct sss_domain_info *parent, - const char *sd_name); - --- -2.14.3 - diff --git a/SOURCES/0063-ipa-handle-users-from-different-domains-in-ipa_resol.patch b/SOURCES/0063-ipa-handle-users-from-different-domains-in-ipa_resol.patch deleted file mode 100644 index 68c09b2..0000000 --- a/SOURCES/0063-ipa-handle-users-from-different-domains-in-ipa_resol.patch +++ /dev/null @@ -1,76 +0,0 @@ -From d8d4e9fb842444eb3bd4e1a116fce00aba557707 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 20 Nov 2017 12:04:50 +0100 -Subject: [PATCH 63/67] ipa: handle users from different domains in - ipa_resolve_user_list_send() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Instead of assuming that all users in the list can be found in the -provided domain with this patch the domain name part of the user name is -preferred. The provided domain name is used as a fallback. - -Related to https://pagure.io/SSSD/sssd/issue/3579 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 7988988aab5bd0249476671b850eb3909aa753f8) ---- - src/providers/ipa/ipa_id.c | 20 ++++++++++++++++---- - 1 file changed, 16 insertions(+), 4 deletions(-) - -diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c -index 8f8759f64b758aae7e45c88588e97a1bcf16ad79..2b4386584192d6b5ef0372099292ed73b77177bd 100644 ---- a/src/providers/ipa/ipa_id.c -+++ b/src/providers/ipa/ipa_id.c -@@ -63,6 +63,8 @@ struct ipa_resolve_user_list_state { - struct ipa_id_ctx *ipa_ctx; - struct ldb_message_element *users; - const char *domain_name; -+ struct sss_domain_info *domain; -+ struct sss_domain_info *user_domain; - size_t user_idx; - - int dp_error; -@@ -91,6 +93,8 @@ ipa_resolve_user_list_send(TALLOC_CTX *memctx, struct tevent_context *ev, - state->ev = ev; - state->ipa_ctx = ipa_ctx; - state->domain_name = domain_name; -+ state->domain = find_domain_by_name(state->ipa_ctx->sdap_id_ctx->be->domain, -+ state->domain_name, true); - state->users = users; - state->user_idx = 0; - state->dp_error = DP_ERR_FATAL; -@@ -132,8 +136,17 @@ static errno_t ipa_resolve_user_list_get_user_step(struct tevent_req *req) - - DEBUG(SSSDBG_TRACE_ALL, "Trying to resolve user [%s].\n", ar->filter_value); - -- if (strcasecmp(state->domain_name, -- state->ipa_ctx->sdap_id_ctx->be->domain->name) != 0) { -+ state->user_domain = find_domain_by_object_name_ex( -+ state->ipa_ctx->sdap_id_ctx->be->domain, -+ ar->filter_value, true); -+ /* Use provided domain as as fallback is no known domain was found in the -+ * user name. */ -+ if (state->user_domain == NULL) { -+ state->user_domain = state->domain; -+ } -+ ar->domain = state->user_domain->name; -+ -+ if (state->user_domain != state->ipa_ctx->sdap_id_ctx->be->domain) { - subreq = ipa_subdomain_account_send(state, state->ev, state->ipa_ctx, - ar); - } else { -@@ -158,8 +171,7 @@ static void ipa_resolve_user_list_get_user_done(struct tevent_req *subreq) - struct ipa_resolve_user_list_state); - int ret; - -- if (strcasecmp(state->domain_name, -- state->ipa_ctx->sdap_id_ctx->be->domain->name) != 0) { -+ if (state->user_domain != state->ipa_ctx->sdap_id_ctx->be->domain) { - ret = ipa_subdomain_account_recv(subreq, &state->dp_error); - } else { - ret = ipa_id_get_account_info_recv(subreq, &state->dp_error); --- -2.14.3 - diff --git a/SOURCES/0064-overrides-fixes-for-sysdb_invalidate_overrides.patch b/SOURCES/0064-overrides-fixes-for-sysdb_invalidate_overrides.patch deleted file mode 100644 index c8d9de9..0000000 --- a/SOURCES/0064-overrides-fixes-for-sysdb_invalidate_overrides.patch +++ /dev/null @@ -1,203 +0,0 @@ -From c0263b48a3512d8b6984693c4b8e772844215f9e Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 20 Nov 2017 15:51:27 +0100 -Subject: [PATCH 64/67] overrides: fixes for sysdb_invalidate_overrides() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There were two issues in sysdb_invalidate_overrides(). - -First, SYSDB_CACHE_EXPIRE was only reset for the entry in the data cache -but not in the timestamp cache. - -Second, if one of the steps in the combined replace and delete operation -failed no change was committed to the cache. If, for whatever reasons, -a user or group object didn't had SYSDB_OVERRIDE_DN set the delete -failed and hence SYSDB_CACHE_EXPIRE wasn't reset as well. To make sure -the cache is in a consistent state after a view change the replace and -the delete operations are don in two steps. - -Related to https://pagure.io/SSSD/sssd/issue/3579 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 4671acb949c65c5c080532e03b1b6f1c9377a6a5) ---- - src/db/sysdb_views.c | 111 +++++++++++++++++++++++++++++++++++++-------------- - 1 file changed, 80 insertions(+), 31 deletions(-) - -diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c -index afc7852ecf402ef144beca9c1b94fbe3cc4bbb6a..70082d8db9b25c11e8c0823d4e5da2ba0c0d10d1 100644 ---- a/src/db/sysdb_views.c -+++ b/src/db/sysdb_views.c -@@ -279,6 +279,45 @@ done: - return ret; - } - -+static errno_t invalidate_entry_override(struct sysdb_ctx *sysdb, -+ struct ldb_dn *dn, -+ struct ldb_message *msg_del, -+ struct ldb_message *msg_repl) -+{ -+ int ret; -+ -+ msg_del->dn = dn; -+ msg_repl->dn = dn; -+ -+ ret = ldb_modify(sysdb->ldb, msg_del); -+ if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "ldb_modify failed: [%s](%d)[%s]\n", -+ ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); -+ return sysdb_error_to_errno(ret); -+ } -+ -+ ret = ldb_modify(sysdb->ldb, msg_repl); -+ if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "ldb_modify failed: [%s](%d)[%s]\n", -+ ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); -+ return sysdb_error_to_errno(ret); -+ } -+ -+ if (sysdb->ldb_ts != NULL) { -+ ret = ldb_modify(sysdb->ldb_ts, msg_repl); -+ if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "ldb_modify failed: [%s](%d)[%s]\n", -+ ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb_ts)); -+ return sysdb_error_to_errno(ret); -+ } -+ } -+ -+ return EOK; -+} -+ - errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) - { - int ret; -@@ -287,22 +326,23 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) - bool in_transaction = false; - struct ldb_result *res; - size_t c; -- struct ldb_message *msg; -+ struct ldb_message *msg_del; -+ struct ldb_message *msg_repl; - struct ldb_dn *base_dn; - -+ if (sysdb->ldb_ts == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Timestamp cache context not available, cache might not be " -+ "invalidated completely. Please call 'sss_cache -E' or remove " -+ "the cache file if there are issues after a view name change.\n"); -+ } -+ - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); - return ENOMEM; - } - -- msg = ldb_msg_new(tmp_ctx); -- if (msg == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n"); -- ret = ENOMEM; -- goto done; -- } -- - base_dn = ldb_dn_new(tmp_ctx, sysdb->ldb, SYSDB_BASE); - if (base_dn == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed\n"); -@@ -310,27 +350,40 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) - goto done; - } - -- ret = ldb_msg_add_empty(msg, SYSDB_CACHE_EXPIRE, LDB_FLAG_MOD_REPLACE, -+ msg_del = ldb_msg_new(tmp_ctx); -+ if (msg_del == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ ret = ldb_msg_add_empty(msg_del, SYSDB_OVERRIDE_DN, LDB_FLAG_MOD_DELETE, - NULL); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); - ret = sysdb_error_to_errno(ret); - goto done; - } -- ret = ldb_msg_add_string(msg, SYSDB_CACHE_EXPIRE, "1"); -+ -+ msg_repl = ldb_msg_new(tmp_ctx); -+ if (msg_repl == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_new failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ ret = ldb_msg_add_empty(msg_repl, SYSDB_CACHE_EXPIRE, -+ LDB_FLAG_MOD_REPLACE, NULL); -+ if (ret != LDB_SUCCESS) { -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); -+ ret = sysdb_error_to_errno(ret); -+ goto done; -+ } -+ ret = ldb_msg_add_string(msg_repl, SYSDB_CACHE_EXPIRE, "1"); - if (ret != LDB_SUCCESS) { - DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_string failed.\n"); - ret = sysdb_error_to_errno(ret); - goto done; - } - -- ret = ldb_msg_add_empty(msg, SYSDB_OVERRIDE_DN, LDB_FLAG_MOD_DELETE, NULL); -- if (ret != LDB_SUCCESS) { -- DEBUG(SSSDBG_OP_FAILURE, "ldb_msg_add_empty failed.\n"); -- ret = sysdb_error_to_errno(ret); -- goto done; -- } -- - ret = sysdb_transaction_start(sysdb); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_transaction_start failed.\n"); -@@ -347,14 +400,12 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) - } - - for (c = 0; c < res->count; c++) { -- msg->dn = res->msgs[c]->dn; -- -- ret = ldb_modify(sysdb->ldb, msg); -- if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { -+ ret = invalidate_entry_override(sysdb, res->msgs[c]->dn, msg_del, -+ msg_repl); -+ if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, -- "ldb_modify failed: [%s](%d)[%s]\n", -- ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); -- ret = sysdb_error_to_errno(ret); -+ "invalidate_entry_override failed [%d][%s].\n", -+ ret, sss_strerror(ret)); - goto done; - } - } -@@ -370,14 +421,12 @@ errno_t sysdb_invalidate_overrides(struct sysdb_ctx *sysdb) - } - - for (c = 0; c < res->count; c++) { -- msg->dn = res->msgs[c]->dn; -- -- ret = ldb_modify(sysdb->ldb, msg); -- if (ret != LDB_SUCCESS && ret != LDB_ERR_NO_SUCH_ATTRIBUTE) { -+ ret = invalidate_entry_override(sysdb, res->msgs[c]->dn, msg_del, -+ msg_repl); -+ if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, -- "ldb_modify failed: [%s](%d)[%s]\n", -- ldb_strerror(ret), ret, ldb_errstring(sysdb->ldb)); -- ret = sysdb_error_to_errno(ret); -+ "invalidate_entry_override failed [%d][%s].\n", -+ ret, sss_strerror(ret)); - goto done; - } - } --- -2.14.3 - diff --git a/SOURCES/0065-ipa-check-for-SYSDB_OVERRIDE_DN-in-process_members-a.patch b/SOURCES/0065-ipa-check-for-SYSDB_OVERRIDE_DN-in-process_members-a.patch deleted file mode 100644 index 74f5f5e..0000000 --- a/SOURCES/0065-ipa-check-for-SYSDB_OVERRIDE_DN-in-process_members-a.patch +++ /dev/null @@ -1,254 +0,0 @@ -From 53c6201539d24f8b929120565ca661977ecbb1a4 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 20 Nov 2017 16:12:58 +0100 -Subject: [PATCH 65/67] ipa: check for SYSDB_OVERRIDE_DN in process_members and - get_group_dn_list -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -process_members() and get_group_dn_list() are used on an IPA client to -determine a list of users or groups which are missing in the cache and -are needed to properly add a group or user object to the cache -respectively. - -If a non-default view is assigned to the client the SYSDB_OVERRIDE_DN -must be set for all user and group objects to indicate that it was -already checked if there is an id-override defined for the object or -not. There a circumstances were SYSDB_OVERRIDE_DN is not set, e.g. after -a view name change. To make sure the cache is in a consistent state with -this patch user and group entries without SYSDB_OVERRIDE_DN are -considered as missing is a non-default view is assigned to the client. - -Related to https://pagure.io/SSSD/sssd/issue/3579 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 919b5d76057d31877e0c25ca495711ff76c713d6) ---- - src/providers/ipa/ipa_s2n_exop.c | 145 ++++++++++++++++++++++----------------- - 1 file changed, 83 insertions(+), 62 deletions(-) - -diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c -index 39ed17cbf0e8c523212084197e9f2963fed88dc8..c6132f509dcc8e7af84e03e8bfe20701107d1392 100644 ---- a/src/providers/ipa/ipa_s2n_exop.c -+++ b/src/providers/ipa/ipa_s2n_exop.c -@@ -1523,6 +1523,7 @@ fail: - } - - static errno_t process_members(struct sss_domain_info *domain, -+ bool is_default_view, - struct sysdb_attrs *group_attrs, - char **members, - TALLOC_CTX *mem_ctx, char ***_missing_members) -@@ -1536,6 +1537,7 @@ static errno_t process_members(struct sss_domain_info *domain, - struct sss_domain_info *parent_domain; - char **missing_members = NULL; - size_t miss_count = 0; -+ const char *attrs[] = {SYSDB_NAME, SYSDB_OVERRIDE_DN, NULL}; - - if (members == NULL) { - DEBUG(SSSDBG_TRACE_INTERNAL, "No members\n"); -@@ -1572,53 +1574,59 @@ static errno_t process_members(struct sss_domain_info *domain, - goto done; - } - -- ret = sysdb_search_user_by_name(tmp_ctx, obj_domain, members[c], NULL, -+ ret = sysdb_search_user_by_name(tmp_ctx, obj_domain, members[c], attrs, - &msg); -- if (ret == EOK) { -- if (group_attrs != NULL) { -- dn_str = ldb_dn_get_linearized(msg->dn); -- if (dn_str == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_get_linearized failed.\n"); -- ret = EINVAL; -- goto done; -- } -- -- DEBUG(SSSDBG_TRACE_ALL, "Adding member [%s][%s]\n", -- members[c], dn_str); -+ if (ret == EOK || ret == ENOENT) { -+ if (ret == ENOENT -+ || (!is_default_view -+ && ldb_msg_find_attr_as_string(msg, SYSDB_OVERRIDE_DN, -+ NULL) == NULL)) { -+ /* only add ghost if the member is really missing */ -+ if (group_attrs != NULL && ret == ENOENT) { -+ DEBUG(SSSDBG_TRACE_ALL, "Adding ghost member [%s]\n", -+ members[c]); - -- ret = sysdb_attrs_add_string_safe(group_attrs, SYSDB_MEMBER, -- dn_str); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- "sysdb_attrs_add_string_safe failed.\n"); -- goto done; -+ /* There were cases where the server returned the same user -+ * multiple times */ -+ ret = sysdb_attrs_add_string_safe(group_attrs, SYSDB_GHOST, -+ members[c]); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sysdb_attrs_add_string failed.\n"); -+ goto done; -+ } - } -- } -- } else if (ret == ENOENT) { -- if (group_attrs != NULL) { -- DEBUG(SSSDBG_TRACE_ALL, "Adding ghost member [%s]\n", -- members[c]); - -- /* There were cases where the server returned the same user -- * multiple times */ -- ret = sysdb_attrs_add_string_safe(group_attrs, SYSDB_GHOST, -- members[c]); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, -- "sysdb_attrs_add_string failed.\n"); -- goto done; -+ if (missing_members != NULL) { -+ missing_members[miss_count] = talloc_strdup(missing_members, -+ members[c]); -+ if (missing_members[miss_count] == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ miss_count++; - } -- } -+ } else { -+ if (group_attrs != NULL) { -+ dn_str = ldb_dn_get_linearized(msg->dn); -+ if (dn_str == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_get_linearized failed.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ -+ DEBUG(SSSDBG_TRACE_ALL, "Adding member [%s][%s]\n", -+ members[c], dn_str); - -- if (missing_members != NULL) { -- missing_members[miss_count] = talloc_strdup(missing_members, -- members[c]); -- if (missing_members[miss_count] == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); -- ret = ENOMEM; -- goto done; -+ ret = sysdb_attrs_add_string_safe(group_attrs, SYSDB_MEMBER, -+ dn_str); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "sysdb_attrs_add_string_safe failed.\n"); -+ goto done; -+ } - } -- miss_count++; - } - } else { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_user_by_name failed.\n"); -@@ -1649,6 +1657,7 @@ done: - } - - static errno_t get_group_dn_list(TALLOC_CTX *mem_ctx, -+ bool is_default_view, - struct sss_domain_info *dom, - size_t ngroups, char **groups, - struct ldb_dn ***_dn_list, -@@ -1664,6 +1673,7 @@ static errno_t get_group_dn_list(TALLOC_CTX *mem_ctx, - size_t n_missing = 0; - struct sss_domain_info *obj_domain; - struct sss_domain_info *parent_domain; -+ const char *attrs[] = {SYSDB_NAME, SYSDB_OVERRIDE_DN, NULL}; - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { -@@ -1689,25 +1699,31 @@ static errno_t get_group_dn_list(TALLOC_CTX *mem_ctx, - goto done; - } - -- ret = sysdb_search_group_by_name(tmp_ctx, obj_domain, groups[c], NULL, -+ ret = sysdb_search_group_by_name(tmp_ctx, obj_domain, groups[c], attrs, - &msg); -- if (ret == EOK) { -- dn_list[n_dns] = ldb_dn_copy(dn_list, msg->dn); -- if (dn_list[n_dns] == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_copy failed.\n"); -- ret = ENOMEM; -- goto done; -+ if (ret == EOK || ret == ENOENT) { -+ if (ret == ENOENT -+ || (!is_default_view -+ && ldb_msg_find_attr_as_string(msg, SYSDB_OVERRIDE_DN, -+ NULL) == NULL)) { -+ missing_groups[n_missing] = talloc_strdup(missing_groups, -+ groups[c]); -+ if (missing_groups[n_missing] == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ n_missing++; -+ -+ } else { -+ dn_list[n_dns] = ldb_dn_copy(dn_list, msg->dn); -+ if (dn_list[n_dns] == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_copy failed.\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ n_dns++; - } -- n_dns++; -- } else if (ret == ENOENT) { -- missing_groups[n_missing] = talloc_strdup(missing_groups, -- groups[c]); -- if (missing_groups[n_missing] == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); -- ret = ENOMEM; -- goto done; -- } -- n_missing++; - } else { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_search_group_by_name failed.\n"); - goto done; -@@ -1803,7 +1819,9 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq) - } - - -- ret = get_group_dn_list(state, state->dom, -+ ret = get_group_dn_list(state, -+ is_default_view(state->ipa_ctx->view_name), -+ state->dom, - attrs->ngroups, attrs->groups, - &group_dn_list, &missing_list); - if (ret != EOK) { -@@ -1832,8 +1850,10 @@ static void ipa_s2n_get_user_done(struct tevent_req *subreq) - } - break; - } else if (attrs->response_type == RESP_GROUP_MEMBERS) { -- ret = process_members(state->dom, NULL, attrs->a.group.gr_mem, -- state, &missing_list); -+ ret = process_members(state->dom, -+ is_default_view(state->ipa_ctx->view_name), -+ NULL, attrs->a.group.gr_mem, state, -+ &missing_list); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "process_members failed.\n"); - goto done; -@@ -2572,8 +2592,9 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, - } - } - -- ret = process_members(dom, attrs->sysdb_attrs, -- attrs->a.group.gr_mem, NULL, NULL); -+ ret = process_members(dom, is_default_view(view_name), -+ attrs->sysdb_attrs, attrs->a.group.gr_mem, -+ NULL, NULL); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "process_members failed.\n"); - goto done; --- -2.14.3 - diff --git a/SOURCES/0066-IPA-use-cache-searches-in-get_groups_dns.patch b/SOURCES/0066-IPA-use-cache-searches-in-get_groups_dns.patch deleted file mode 100644 index 5268e1a..0000000 --- a/SOURCES/0066-IPA-use-cache-searches-in-get_groups_dns.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 3500a7766f5443c9ec50f9c8de27e2dea8c0c234 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 20 Nov 2017 16:41:29 +0100 -Subject: [PATCH 66/67] IPA: use cache searches in get_groups_dns() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If the group name is overridden in the default view we have to search -for the name and cannot construct it because the extdom plugin will -return the overridden name but the DN of the related group object in the -cache will contain the original name. - -Related to https://pagure.io/SSSD/sssd/issue/3579 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit f29040342a6d69e170f4543662621f2e27221f91) ---- - src/providers/ipa/ipa_s2n_exop.c | 27 +++++++++++++++++++-------- - 1 file changed, 19 insertions(+), 8 deletions(-) - -diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c -index c6132f509dcc8e7af84e03e8bfe20701107d1392..49c393e9a1eb19ab683949cf633a6838274bc0fe 100644 ---- a/src/providers/ipa/ipa_s2n_exop.c -+++ b/src/providers/ipa/ipa_s2n_exop.c -@@ -2038,6 +2038,7 @@ static errno_t get_groups_dns(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, - int c; - struct sss_domain_info *root_domain; - char **dn_list; -+ struct ldb_message *msg; - - if (name_list == NULL) { - *_dn_list = NULL; -@@ -2082,15 +2083,25 @@ static errno_t get_groups_dns(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, - goto done; - } - -- /* This might fail if some unexpected cases are used. But current -- * sysdb code which handles group membership constructs DNs this way -- * as well, IPA names are lowercased and AD names by default will be -- * lowercased as well. If there are really use-cases which cause an -- * issue here, sysdb_group_strdn() has to be replaced by a proper -- * search. */ -- dn_list[c] = sysdb_group_strdn(dn_list, dom->name, name_list[c]); -+ /* If the group name is overridden in the default view we have to -+ * search for the name and cannot construct it because the extdom -+ * plugin will return the overridden name but the DN of the related -+ * group object in the cache will contain the original name. */ -+ -+ ret = sysdb_search_group_by_name(tmp_ctx, dom, name_list[c], NULL, -+ &msg); -+ if (ret == EOK) { -+ dn_list[c] = ldb_dn_alloc_linearized(dn_list, msg->dn); -+ } else { -+ /* best effort, try to construct the DN */ -+ DEBUG(SSSDBG_TRACE_FUNC, -+ "sysdb_search_group_by_name failed with [%d], " -+ "generating DN for [%s] in domain [%s].\n", -+ ret, name_list[c], dom->name); -+ dn_list[c] = sysdb_group_strdn(dn_list, dom->name, name_list[c]); -+ } - if (dn_list[c] == NULL) { -- DEBUG(SSSDBG_OP_FAILURE, "sysdb_group_strdn failed.\n"); -+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_alloc_linearized failed.\n"); - ret = ENOMEM; - goto done; - } --- -2.14.3 - diff --git a/SOURCES/0067-ipa-compare-DNs-instead-of-group-names-in-ipa_s2n_sa.patch b/SOURCES/0067-ipa-compare-DNs-instead-of-group-names-in-ipa_s2n_sa.patch deleted file mode 100644 index cc19a9e..0000000 --- a/SOURCES/0067-ipa-compare-DNs-instead-of-group-names-in-ipa_s2n_sa.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 118860519777791368520f4e92ecbf2ef60cb7db Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 20 Nov 2017 16:45:45 +0100 -Subject: [PATCH 67/67] ipa: compare DNs instead of group names in - ipa_s2n_save_objects() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If group names are used to compare the current list of group memberships -returned by the server with the one from the cache some groups might end -up in the wrong result list if group names are overridden. This -ambiguity can be resolved by using the DNs of the cached objects. - -Related to https://pagure.io/SSSD/sssd/issue/3579 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit a52226c651308a0a7732544b492eb4db56b84f1d) ---- - src/providers/ipa/ipa_s2n_exop.c | 31 ++++++++++++------------------- - 1 file changed, 12 insertions(+), 19 deletions(-) - -diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c -index 49c393e9a1eb19ab683949cf633a6838274bc0fe..8b97f78620f19b0708e8a480cb72fd7f12d96dfb 100644 ---- a/src/providers/ipa/ipa_s2n_exop.c -+++ b/src/providers/ipa/ipa_s2n_exop.c -@@ -2185,10 +2185,9 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, - struct ldb_result *res; - enum sysdb_member_type type; - char **sysdb_grouplist; -- char **add_groups; - char **add_groups_dns; -- char **del_groups; - char **del_groups_dns; -+ char **groups_dns; - bool in_transaction = false; - int tret; - struct sysdb_attrs *gid_override_attrs = NULL; -@@ -2514,33 +2513,27 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, - } - - if (attrs->response_type == RESP_USER_GROUPLIST) { -- ret = get_sysdb_grouplist(tmp_ctx, dom->sysdb, dom, name, -- &sysdb_grouplist); -+ ret = get_sysdb_grouplist_dn(tmp_ctx, dom->sysdb, dom, name, -+ &sysdb_grouplist); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "get_sysdb_grouplist failed.\n"); - goto done; - } - -- ret = diff_string_lists(tmp_ctx, attrs->groups, -- sysdb_grouplist, &add_groups, -- &del_groups, NULL); -+ ret = get_groups_dns(tmp_ctx, dom, attrs->groups, &groups_dns); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "get_groups_dns failed.\n"); -+ goto done; -+ } -+ -+ ret = diff_string_lists(tmp_ctx, groups_dns, -+ sysdb_grouplist, &add_groups_dns, -+ &del_groups_dns, NULL); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "diff_string_lists failed.\n"); - goto done; - } - -- ret = get_groups_dns(tmp_ctx, dom, add_groups, &add_groups_dns); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "get_groups_dns failed.\n"); -- goto done; -- } -- -- ret = get_groups_dns(tmp_ctx, dom, del_groups, &del_groups_dns); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "get_groups_dns failed.\n"); -- goto done; -- } -- - DEBUG(SSSDBG_TRACE_INTERNAL, "Updating memberships for %s\n", - name); - ret = sysdb_update_members_dn(dom, name, SYSDB_MEMBER_USER, --- -2.14.3 - diff --git a/SOURCES/0068-SDAP-Split-out-utility-function-sdap_get_object_doma.patch b/SOURCES/0068-SDAP-Split-out-utility-function-sdap_get_object_doma.patch deleted file mode 100644 index 24ee010..0000000 --- a/SOURCES/0068-SDAP-Split-out-utility-function-sdap_get_object_doma.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0e5d9f481daeeaecefeb68cdc03e45a11dfd7091 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 7 Nov 2017 17:03:13 +0100 -Subject: [PATCH 68/83] SDAP: Split out utility function - sdap_get_object_domain() from sdap_object_in_domain() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The DP request that returns a domain of an entry to responder will need -this functionality in order to map the original DN of the entry found -to a domain name. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit 37fdd9dc1ad5968067f8e3c43a51ed2ac9f3b104) ---- - src/providers/ldap/sdap.c | 26 ++++++++++++++++++++------ - src/providers/ldap/sdap.h | 4 ++++ - 2 files changed, 24 insertions(+), 6 deletions(-) - -diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c -index b6b1c91cb7507ebb95cd559634a77ed44dfb5fc0..59d24fed53cc35751b5c24679e247a42f82e1d0a 100644 ---- a/src/providers/ldap/sdap.c -+++ b/src/providers/ldap/sdap.c -@@ -1673,9 +1673,9 @@ char *sdap_make_oc_list(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map) - } - } - --bool sdap_object_in_domain(struct sdap_options *opts, -- struct sysdb_attrs *obj, -- struct sss_domain_info *dom) -+struct sss_domain_info *sdap_get_object_domain(struct sdap_options *opts, -+ struct sysdb_attrs *obj, -+ struct sss_domain_info *dom) - { - errno_t ret; - const char *original_dn = NULL; -@@ -1685,7 +1685,7 @@ bool sdap_object_in_domain(struct sdap_options *opts, - if (ret) { - DEBUG(SSSDBG_FUNC_DATA, - "The group has no original DN, assuming our domain\n"); -- return true; -+ return dom; - } - - sdmatch = sdap_domain_get_by_dn(opts, original_dn); -@@ -1693,10 +1693,24 @@ bool sdap_object_in_domain(struct sdap_options *opts, - DEBUG(SSSDBG_FUNC_DATA, - "The original DN of the group cannot " - "be related to any search base\n"); -- return true; -+ return dom; - } - -- return (sdmatch->dom == dom); -+ return sdmatch->dom; -+} -+ -+bool sdap_object_in_domain(struct sdap_options *opts, -+ struct sysdb_attrs *obj, -+ struct sss_domain_info *dom) -+{ -+ struct sss_domain_info *obj_dom; -+ -+ obj_dom = sdap_get_object_domain(opts, obj, dom); -+ if (obj_dom == NULL) { -+ return false; -+ } -+ -+ return (obj_dom == dom); - } - - size_t sdap_steal_objects_in_dom(struct sdap_options *opts, -diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h -index 2ba016ff52313198287ac5196e24517333882099..8b0f1f0ce0fef59554270f0f31cfd2d5f0aa57f5 100644 ---- a/src/providers/ldap/sdap.h -+++ b/src/providers/ldap/sdap.h -@@ -644,6 +644,10 @@ size_t sdap_steal_objects_in_dom(struct sdap_options *opts, - size_t count, - bool filter); - -+struct sss_domain_info *sdap_get_object_domain(struct sdap_options *opts, -+ struct sysdb_attrs *obj, -+ struct sss_domain_info *dom); -+ - bool sdap_object_in_domain(struct sdap_options *opts, - struct sysdb_attrs *obj, - struct sss_domain_info *dom); --- -2.14.3 - diff --git a/SOURCES/0069-LDAP-Extract-the-check-whether-to-run-a-POSIX-check-.patch b/SOURCES/0069-LDAP-Extract-the-check-whether-to-run-a-POSIX-check-.patch deleted file mode 100644 index 1b64e0d..0000000 --- a/SOURCES/0069-LDAP-Extract-the-check-whether-to-run-a-POSIX-check-.patch +++ /dev/null @@ -1,115 +0,0 @@ -From 880552cc45e55c7ef9f81423aff8fe867451d752 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Thu, 30 Nov 2017 11:47:30 +0100 -Subject: [PATCH 69/83] LDAP: Extract the check whether to run a POSIX check to - a function -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This will reduce the code duplication in the following patches and will -allow to keep all the logic on one place so that when/if we change the -code in the future, we only have to change the single place. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit 8e93ebb2a6f7644c389c1d1f4e92a21c4d0b2b45) ---- - src/providers/ldap/ldap_common.c | 15 +++++++++++++++ - src/providers/ldap/ldap_common.h | 4 ++++ - src/providers/ldap/ldap_id.c | 15 ++++++--------- - src/providers/ldap/sdap_async_enum.c | 7 +++---- - 4 files changed, 28 insertions(+), 13 deletions(-) - -diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c -index 0597e91f7fade47aeb34565597c730ac406e0cfc..3eff3515d95043d4b59cb0d9953cf050355a0ca5 100644 ---- a/src/providers/ldap/ldap_common.c -+++ b/src/providers/ldap/ldap_common.c -@@ -971,3 +971,18 @@ sdap_id_ctx_new(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, - - return sdap_ctx; - } -+ -+bool should_run_posix_check(struct sdap_id_ctx *ctx, -+ bool use_id_mapping, -+ bool posix_request) -+{ -+ if (use_id_mapping == false && -+ posix_request == true && -+ ctx->opts->schema_type == SDAP_SCHEMA_AD && -+ ctx->srv_opts && -+ ctx->srv_opts->posix_checked == false) { -+ return true; -+ } -+ -+ return false; -+} -diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h -index 0510b7d5ab5121bd96f699e8e59520a2a18a604f..fa7cda4df9d7334f6f0f5baccae0cba0478bfbea 100644 ---- a/src/providers/ldap/ldap_common.h -+++ b/src/providers/ldap/ldap_common.h -@@ -304,6 +304,10 @@ char *get_enterprise_principal_string_filter(TALLOC_CTX *mem_ctx, - const char *princ, - struct dp_option *sdap_basic_opts); - -+bool should_run_posix_check(struct sdap_id_ctx *ctx, -+ bool id_mapping, -+ bool posix_request); -+ - char *sdap_get_access_filter(TALLOC_CTX *mem_ctx, - const char *base_filter); - -diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c -index e89fc6133316f684810afe4c1a0731b8a04f2931..6ab9e0aa1db3eed32deb75211ded30a4cb48ca30 100644 ---- a/src/providers/ldap/ldap_id.c -+++ b/src/providers/ldap/ldap_id.c -@@ -411,11 +411,9 @@ static void users_get_connect_done(struct tevent_req *subreq) - /* If POSIX attributes have been requested with an AD server and we - * have no idea about POSIX attributes support, run a one-time check - */ -- if (state->use_id_mapping == false && -- state->non_posix == false && -- state->ctx->opts->schema_type == SDAP_SCHEMA_AD && -- state->ctx->srv_opts && -- state->ctx->srv_opts->posix_checked == false) { -+ if (should_run_posix_check(state->ctx, -+ state->use_id_mapping, -+ !state->non_posix)) { - subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, - sdap_id_op_handle(state->op), - state->sdom->user_search_bases, -@@ -958,10 +956,9 @@ static void groups_get_connect_done(struct tevent_req *subreq) - /* If POSIX attributes have been requested with an AD server and we - * have no idea about POSIX attributes support, run a one-time check - */ -- if (state->use_id_mapping == false && -- state->ctx->opts->schema_type == SDAP_SCHEMA_AD && -- state->ctx->srv_opts && -- state->ctx->srv_opts->posix_checked == false) { -+ if (should_run_posix_check(state->ctx, -+ state->use_id_mapping, -+ !state->non_posix)) { - subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, - sdap_id_op_handle(state->op), - state->sdom->user_search_bases, -diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c -index 91e481c4e694126900c729e86d187fba355de0b8..2cef4eb886f982ba388a34955bdd38468fe68200 100644 ---- a/src/providers/ldap/sdap_async_enum.c -+++ b/src/providers/ldap/sdap_async_enum.c -@@ -196,10 +196,9 @@ static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq) - /* If POSIX attributes have been requested with an AD server and we - * have no idea about POSIX attributes support, run a one-time check - */ -- if (use_id_mapping == false && -- state->ctx->opts->schema_type == SDAP_SCHEMA_AD && -- state->ctx->srv_opts && -- state->ctx->srv_opts->posix_checked == false) { -+ if (should_run_posix_check(state->ctx, -+ use_id_mapping, -+ true)) { - subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, - sdap_id_op_handle(state->user_op), - state->sdom->user_search_bases, --- -2.14.3 - diff --git a/SOURCES/0070-LDAP-Only-run-the-POSIX-check-with-a-GC-connection.patch b/SOURCES/0070-LDAP-Only-run-the-POSIX-check-with-a-GC-connection.patch deleted file mode 100644 index f4be7e3..0000000 --- a/SOURCES/0070-LDAP-Only-run-the-POSIX-check-with-a-GC-connection.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 405f08eabf5017cc00891fb2090be80306c8aeae Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Thu, 30 Nov 2017 12:01:51 +0100 -Subject: [PATCH 70/83] LDAP: Only run the POSIX check with a GC connection -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Previously, we used to run the POSIX check also with an LDAP connection. -This was wasteful, but worked, so the waste wasn't the biggest problem --- the approach would only cause problems with the following patch which -uses a NULL search base to search the Global Catalog, because searching -with a SUBTREE scope and a NULL base returns a referral with an LDAP -connection. - -Instead, this patch uses a heuristics (whether the connection ignores -the offline state) to check if the connection is a POSIX one and if it -is NOT, then skips the POSIX check. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit dacfe74113dde62ddaaa7f9abf9d2b6448d89db6) ---- - src/providers/ldap/ldap_common.c | 2 ++ - src/providers/ldap/ldap_common.h | 1 + - src/providers/ldap/ldap_id.c | 2 ++ - src/providers/ldap/sdap_async_enum.c | 1 + - 4 files changed, 6 insertions(+) - -diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c -index 3eff3515d95043d4b59cb0d9953cf050355a0ca5..36e79b9d6ca23ef5e21a8b0bedc7f05db8f4fc98 100644 ---- a/src/providers/ldap/ldap_common.c -+++ b/src/providers/ldap/ldap_common.c -@@ -973,12 +973,14 @@ sdap_id_ctx_new(TALLOC_CTX *mem_ctx, struct be_ctx *bectx, - } - - bool should_run_posix_check(struct sdap_id_ctx *ctx, -+ struct sdap_id_conn_ctx *conn, - bool use_id_mapping, - bool posix_request) - { - if (use_id_mapping == false && - posix_request == true && - ctx->opts->schema_type == SDAP_SCHEMA_AD && -+ conn->ignore_mark_offline == true && - ctx->srv_opts && - ctx->srv_opts->posix_checked == false) { - return true; -diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h -index fa7cda4df9d7334f6f0f5baccae0cba0478bfbea..44dbc3fb0678412f46366321e0be836313380949 100644 ---- a/src/providers/ldap/ldap_common.h -+++ b/src/providers/ldap/ldap_common.h -@@ -305,6 +305,7 @@ char *get_enterprise_principal_string_filter(TALLOC_CTX *mem_ctx, - struct dp_option *sdap_basic_opts); - - bool should_run_posix_check(struct sdap_id_ctx *ctx, -+ struct sdap_id_conn_ctx *conn, - bool id_mapping, - bool posix_request); - -diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c -index 6ab9e0aa1db3eed32deb75211ded30a4cb48ca30..47969a9749253721334a20f46230f7aecea64882 100644 ---- a/src/providers/ldap/ldap_id.c -+++ b/src/providers/ldap/ldap_id.c -@@ -412,6 +412,7 @@ static void users_get_connect_done(struct tevent_req *subreq) - * have no idea about POSIX attributes support, run a one-time check - */ - if (should_run_posix_check(state->ctx, -+ state->conn, - state->use_id_mapping, - !state->non_posix)) { - subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, -@@ -957,6 +958,7 @@ static void groups_get_connect_done(struct tevent_req *subreq) - * have no idea about POSIX attributes support, run a one-time check - */ - if (should_run_posix_check(state->ctx, -+ state->conn, - state->use_id_mapping, - !state->non_posix)) { - subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, -diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c -index 2cef4eb886f982ba388a34955bdd38468fe68200..baa039d63c71cc5054e6af6538d34d04cde6b858 100644 ---- a/src/providers/ldap/sdap_async_enum.c -+++ b/src/providers/ldap/sdap_async_enum.c -@@ -197,6 +197,7 @@ static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq) - * have no idea about POSIX attributes support, run a one-time check - */ - if (should_run_posix_check(state->ctx, -+ state->user_conn, - use_id_mapping, - true)) { - subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, --- -2.14.3 - diff --git a/SOURCES/0071-SDAP-Search-with-a-NULL-search-base-when-looking-up-.patch b/SOURCES/0071-SDAP-Search-with-a-NULL-search-base-when-looking-up-.patch deleted file mode 100644 index 5be8736..0000000 --- a/SOURCES/0071-SDAP-Search-with-a-NULL-search-base-when-looking-up-.patch +++ /dev/null @@ -1,191 +0,0 @@ -From c7003e815aca1c28953c3dc55311ffc3f2d4ab28 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Sun, 12 Nov 2017 19:24:01 +0100 -Subject: [PATCH 71/83] SDAP: Search with a NULL search base when looking up an - ID in the Global Catalog -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The posix_check request is used to determine whether domains in the forest -replicate the POSIX attributes into the Global Catalog. And since the -schema modification that replicates the attributes is not per-domain, but -per-forest, we don't need to iterate over search bases when checking for -the POSIX attribute presence. It is OK to just search with a NULL search -base (and it's what Windows clients do, too). - -Additionally, searching over the whole GC will come handy when implementing -the request that located an account's domain. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit 6ae22d9adc0b075361defc99b8f14480ba8e7b46) ---- - src/providers/ldap/ldap_id.c | 2 -- - src/providers/ldap/sdap_async.c | 51 +++++++----------------------------- - src/providers/ldap/sdap_async.h | 1 - - src/providers/ldap/sdap_async_enum.c | 1 - - 4 files changed, 10 insertions(+), 45 deletions(-) - -diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c -index 47969a9749253721334a20f46230f7aecea64882..b5ac3a749113a281fe8a5564ac341ced0570eded 100644 ---- a/src/providers/ldap/ldap_id.c -+++ b/src/providers/ldap/ldap_id.c -@@ -417,7 +417,6 @@ static void users_get_connect_done(struct tevent_req *subreq) - !state->non_posix)) { - subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, - sdap_id_op_handle(state->op), -- state->sdom->user_search_bases, - dp_opt_get_int(state->ctx->opts->basic, - SDAP_SEARCH_TIMEOUT)); - if (subreq == NULL) { -@@ -963,7 +962,6 @@ static void groups_get_connect_done(struct tevent_req *subreq) - !state->non_posix)) { - subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, - sdap_id_op_handle(state->op), -- state->sdom->user_search_bases, - dp_opt_get_int(state->ctx->opts->basic, - SDAP_SEARCH_TIMEOUT)); - if (subreq == NULL) { -diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c -index 246e12a1f386da1841963d5c1d1c4d2870cc1b6b..1df0b85f4bda6442d8da66784ad7424306b1f051 100644 ---- a/src/providers/ldap/sdap_async.c -+++ b/src/providers/ldap/sdap_async.c -@@ -2573,7 +2573,6 @@ int sdap_asq_search_recv(struct tevent_req *req, - } - - /* ==Posix attribute presence test================================= */ --static errno_t sdap_posix_check_next(struct tevent_req *req); - static void sdap_posix_check_done(struct tevent_req *subreq); - static errno_t sdap_posix_check_parse(struct sdap_handle *sh, - struct sdap_msg *msg, -@@ -2583,12 +2582,10 @@ struct sdap_posix_check_state { - struct tevent_context *ev; - struct sdap_options *opts; - struct sdap_handle *sh; -- struct sdap_search_base **search_bases; - int timeout; - - const char **attrs; - const char *filter; -- size_t base_iter; - - bool has_posix; - }; -@@ -2596,10 +2593,10 @@ struct sdap_posix_check_state { - struct tevent_req * - sdap_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, - struct sdap_options *opts, struct sdap_handle *sh, -- struct sdap_search_base **search_bases, - int timeout) - { - struct tevent_req *req = NULL; -+ struct tevent_req *subreq = NULL; - struct sdap_posix_check_state *state; - errno_t ret; - -@@ -2610,7 +2607,6 @@ sdap_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, - state->ev = ev; - state->sh = sh; - state->opts = opts; -- state->search_bases = search_bases; - state->timeout = timeout; - - state->attrs = talloc_array(state, const char *, 4); -@@ -2634,43 +2630,26 @@ sdap_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, - goto fail; - } - -- ret = sdap_posix_check_next(req); -- if (ret != EOK) { -- goto fail; -- } -- -- return req; -- --fail: -- tevent_req_error(req, ret); -- tevent_req_post(req, ev); -- return req; --} -- --static errno_t sdap_posix_check_next(struct tevent_req *req) --{ -- struct tevent_req *subreq = NULL; -- struct sdap_posix_check_state *state = -- tevent_req_data(req, struct sdap_posix_check_state); -- -- DEBUG(SSSDBG_TRACE_FUNC, -- "Searching for POSIX attributes with base [%s]\n", -- state->search_bases[state->base_iter]->basedn); -- - subreq = sdap_get_generic_ext_send(state, state->ev, state->opts, - state->sh, -- state->search_bases[state->base_iter]->basedn, -+ "", - LDAP_SCOPE_SUBTREE, state->filter, - state->attrs, - NULL, NULL, 1, state->timeout, - sdap_posix_check_parse, state, - SDAP_SRCH_FLG_SIZELIMIT_SILENT); - if (subreq == NULL) { -- return ENOMEM; -+ ret = ENOMEM; -+ goto fail; - } - tevent_req_set_callback(subreq, sdap_posix_check_done, req); - -- return EOK; -+ return req; -+ -+fail: -+ tevent_req_error(req, ret); -+ tevent_req_post(req, ev); -+ return req; - } - - static errno_t sdap_posix_check_parse(struct sdap_handle *sh, -@@ -2746,16 +2725,6 @@ static void sdap_posix_check_done(struct tevent_req *subreq) - return; - } - -- state->base_iter++; -- if (state->search_bases[state->base_iter]) { -- /* There are more search bases to try */ -- ret = sdap_posix_check_next(req); -- if (ret != EOK) { -- tevent_req_error(req, ret); -- } -- return; -- } -- - /* All bases done! */ - DEBUG(SSSDBG_TRACE_LIBS, "Cycled through all bases\n"); - tevent_req_done(req); -diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h -index 6e5800b42ba4a045fa7985b09a80b6b86b8c6055..7216ba032e551196cf5258b4e58fbfc8cfe417ea 100644 ---- a/src/providers/ldap/sdap_async.h -+++ b/src/providers/ldap/sdap_async.h -@@ -269,7 +269,6 @@ int sdap_deref_search_recv(struct tevent_req *req, - struct tevent_req * - sdap_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, - struct sdap_options *opts, struct sdap_handle *sh, -- struct sdap_search_base **search_bases, - int timeout); - - int sdap_posix_check_recv(struct tevent_req *req, -diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c -index baa039d63c71cc5054e6af6538d34d04cde6b858..ec0c679823a8cd9820bb978f77799a3f86621271 100644 ---- a/src/providers/ldap/sdap_async_enum.c -+++ b/src/providers/ldap/sdap_async_enum.c -@@ -202,7 +202,6 @@ static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq) - true)) { - subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, - sdap_id_op_handle(state->user_op), -- state->sdom->user_search_bases, - dp_opt_get_int(state->ctx->opts->basic, - SDAP_SEARCH_TIMEOUT)); - if (subreq == NULL) { --- -2.14.3 - diff --git a/SOURCES/0072-SDAP-Rename-sdap_posix_check-to-sdap_gc_posix_check.patch b/SOURCES/0072-SDAP-Rename-sdap_posix_check-to-sdap_gc_posix_check.patch deleted file mode 100644 index 3335d35..0000000 --- a/SOURCES/0072-SDAP-Rename-sdap_posix_check-to-sdap_gc_posix_check.patch +++ /dev/null @@ -1,251 +0,0 @@ -From ada45cd38a73b1b196db459849fcc19781bc06fc Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Wed, 6 Dec 2017 16:26:15 +0100 -Subject: [PATCH 72/83] SDAP: Rename sdap_posix_check to sdap_gc_posix_check -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Because searching the LDAP port of Active Directory server with a NULL -search base yields an error: - https://technet.microsoft.com/en-us/library/cc755809(v=ws.10).aspx -we changed the POSIX check request to only run against a GC connection -in a previous patch. To make it clearer to the caller that this request -should only be used with a GC connection, this patch renames the -request. - -There are no functional changes in this patch. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit ba8a92bbd59f189bd1323dd0c4010cdfc694be35) ---- - src/providers/ldap/ldap_id.c | 20 +++++++-------- - src/providers/ldap/sdap_async.c | 48 ++++++++++++++++++------------------ - src/providers/ldap/sdap_async.h | 16 ++++++++---- - src/providers/ldap/sdap_async_enum.c | 10 ++++---- - 4 files changed, 50 insertions(+), 44 deletions(-) - -diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c -index b5ac3a749113a281fe8a5564ac341ced0570eded..3824f8f9aa8d2892664f1182376bedf6fb8627f6 100644 ---- a/src/providers/ldap/ldap_id.c -+++ b/src/providers/ldap/ldap_id.c -@@ -415,10 +415,10 @@ static void users_get_connect_done(struct tevent_req *subreq) - state->conn, - state->use_id_mapping, - !state->non_posix)) { -- subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, -- sdap_id_op_handle(state->op), -- dp_opt_get_int(state->ctx->opts->basic, -- SDAP_SEARCH_TIMEOUT)); -+ subreq = sdap_gc_posix_check_send(state, state->ev, state->ctx->opts, -+ sdap_id_op_handle(state->op), -+ dp_opt_get_int(state->ctx->opts->basic, -+ SDAP_SEARCH_TIMEOUT)); - if (subreq == NULL) { - tevent_req_error(req, ENOMEM); - return; -@@ -441,7 +441,7 @@ static void users_get_posix_check_done(struct tevent_req *subreq) - struct users_get_state *state = tevent_req_data(req, - struct users_get_state); - -- ret = sdap_posix_check_recv(subreq, &has_posix); -+ ret = sdap_gc_posix_check_recv(subreq, &has_posix); - talloc_zfree(subreq); - if (ret != EOK) { - /* We can only finish the id_op on error as the connection -@@ -960,10 +960,10 @@ static void groups_get_connect_done(struct tevent_req *subreq) - state->conn, - state->use_id_mapping, - !state->non_posix)) { -- subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, -- sdap_id_op_handle(state->op), -- dp_opt_get_int(state->ctx->opts->basic, -- SDAP_SEARCH_TIMEOUT)); -+ subreq = sdap_gc_posix_check_send(state, state->ev, state->ctx->opts, -+ sdap_id_op_handle(state->op), -+ dp_opt_get_int(state->ctx->opts->basic, -+ SDAP_SEARCH_TIMEOUT)); - if (subreq == NULL) { - tevent_req_error(req, ENOMEM); - return; -@@ -985,7 +985,7 @@ static void groups_get_posix_check_done(struct tevent_req *subreq) - struct groups_get_state *state = tevent_req_data(req, - struct groups_get_state); - -- ret = sdap_posix_check_recv(subreq, &has_posix); -+ ret = sdap_gc_posix_check_recv(subreq, &has_posix); - talloc_zfree(subreq); - if (ret != EOK) { - /* We can only finish the id_op on error as the connection -diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c -index 1df0b85f4bda6442d8da66784ad7424306b1f051..a9bea4f80903aeb9d0fdb4d2b8f2acb36d81d6fe 100644 ---- a/src/providers/ldap/sdap_async.c -+++ b/src/providers/ldap/sdap_async.c -@@ -2573,12 +2573,12 @@ int sdap_asq_search_recv(struct tevent_req *req, - } - - /* ==Posix attribute presence test================================= */ --static void sdap_posix_check_done(struct tevent_req *subreq); --static errno_t sdap_posix_check_parse(struct sdap_handle *sh, -- struct sdap_msg *msg, -- void *pvt); -+static void sdap_gc_posix_check_done(struct tevent_req *subreq); -+static errno_t sdap_gc_posix_check_parse(struct sdap_handle *sh, -+ struct sdap_msg *msg, -+ void *pvt); - --struct sdap_posix_check_state { -+struct sdap_gc_posix_check_state { - struct tevent_context *ev; - struct sdap_options *opts; - struct sdap_handle *sh; -@@ -2591,16 +2591,16 @@ struct sdap_posix_check_state { - }; - - struct tevent_req * --sdap_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, -- struct sdap_options *opts, struct sdap_handle *sh, -- int timeout) -+sdap_gc_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, -+ struct sdap_options *opts, struct sdap_handle *sh, -+ int timeout) - { - struct tevent_req *req = NULL; - struct tevent_req *subreq = NULL; -- struct sdap_posix_check_state *state; -+ struct sdap_gc_posix_check_state *state; - errno_t ret; - -- req = tevent_req_create(memctx, &state, struct sdap_posix_check_state); -+ req = tevent_req_create(memctx, &state, struct sdap_gc_posix_check_state); - if (req == NULL) { - return NULL; - } -@@ -2636,13 +2636,13 @@ sdap_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, - LDAP_SCOPE_SUBTREE, state->filter, - state->attrs, - NULL, NULL, 1, state->timeout, -- sdap_posix_check_parse, state, -+ sdap_gc_posix_check_parse, state, - SDAP_SRCH_FLG_SIZELIMIT_SILENT); - if (subreq == NULL) { - ret = ENOMEM; - goto fail; - } -- tevent_req_set_callback(subreq, sdap_posix_check_done, req); -+ tevent_req_set_callback(subreq, sdap_gc_posix_check_done, req); - - return req; - -@@ -2652,13 +2652,13 @@ fail: - return req; - } - --static errno_t sdap_posix_check_parse(struct sdap_handle *sh, -- struct sdap_msg *msg, -- void *pvt) -+static errno_t sdap_gc_posix_check_parse(struct sdap_handle *sh, -+ struct sdap_msg *msg, -+ void *pvt) - { - struct berval **vals = NULL; -- struct sdap_posix_check_state *state = -- talloc_get_type(pvt, struct sdap_posix_check_state); -+ struct sdap_gc_posix_check_state *state = -+ talloc_get_type(pvt, struct sdap_gc_posix_check_state); - char *dn; - char *endptr; - -@@ -2700,12 +2700,12 @@ done: - return EOK; - } - --static void sdap_posix_check_done(struct tevent_req *subreq) -+static void sdap_gc_posix_check_done(struct tevent_req *subreq) - { - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); -- struct sdap_posix_check_state *state = -- tevent_req_data(req, struct sdap_posix_check_state); -+ struct sdap_gc_posix_check_state *state = -+ tevent_req_data(req, struct sdap_gc_posix_check_state); - errno_t ret; - - ret = sdap_get_generic_ext_recv(subreq, NULL, NULL, NULL); -@@ -2730,11 +2730,11 @@ static void sdap_posix_check_done(struct tevent_req *subreq) - tevent_req_done(req); - } - --int sdap_posix_check_recv(struct tevent_req *req, -- bool *_has_posix) -+int sdap_gc_posix_check_recv(struct tevent_req *req, -+ bool *_has_posix) - { -- struct sdap_posix_check_state *state = tevent_req_data(req, -- struct sdap_posix_check_state); -+ struct sdap_gc_posix_check_state *state = tevent_req_data(req, -+ struct sdap_gc_posix_check_state); - - TEVENT_REQ_RETURN_ON_ERROR(req); - -diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h -index 7216ba032e551196cf5258b4e58fbfc8cfe417ea..26f13e38bf6dff08a8cd0e6b3b5282effda80c9e 100644 ---- a/src/providers/ldap/sdap_async.h -+++ b/src/providers/ldap/sdap_async.h -@@ -266,13 +266,19 @@ int sdap_deref_search_recv(struct tevent_req *req, - size_t *reply_count, - struct sdap_deref_attrs ***reply); - -+/* -+ * This request should only be ran against a Global Catalog connection -+ * because it uses a NULL search base to search all domains in the forest, -+ * which would return an error with an LDAP port: -+ * https://technet.microsoft.com/en-us/library/cc755809(v=ws.10).aspx -+ */ - struct tevent_req * --sdap_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, -- struct sdap_options *opts, struct sdap_handle *sh, -- int timeout); -+sdap_gc_posix_check_send(TALLOC_CTX *memctx, struct tevent_context *ev, -+ struct sdap_options *opts, struct sdap_handle *sh, -+ int timeout); - --int sdap_posix_check_recv(struct tevent_req *req, -- bool *_has_posix); -+int sdap_gc_posix_check_recv(struct tevent_req *req, -+ bool *_has_posix); - - struct tevent_req * - sdap_sd_search_send(TALLOC_CTX *memctx, -diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c -index ec0c679823a8cd9820bb978f77799a3f86621271..ea9d51adc7f94145cd7e689893bf7fd81028c5bb 100644 ---- a/src/providers/ldap/sdap_async_enum.c -+++ b/src/providers/ldap/sdap_async_enum.c -@@ -200,10 +200,10 @@ static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq) - state->user_conn, - use_id_mapping, - true)) { -- subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, -- sdap_id_op_handle(state->user_op), -- dp_opt_get_int(state->ctx->opts->basic, -- SDAP_SEARCH_TIMEOUT)); -+ subreq = sdap_gc_posix_check_send(state, state->ev, state->ctx->opts, -+ sdap_id_op_handle(state->user_op), -+ dp_opt_get_int(state->ctx->opts->basic, -+ SDAP_SEARCH_TIMEOUT)); - if (subreq == NULL) { - tevent_req_error(req, ENOMEM); - return; -@@ -233,7 +233,7 @@ static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq) - struct sdap_dom_enum_ex_state *state = tevent_req_data(req, - struct sdap_dom_enum_ex_state); - -- ret = sdap_posix_check_recv(subreq, &has_posix); -+ ret = sdap_gc_posix_check_recv(subreq, &has_posix); - talloc_zfree(subreq); - if (ret != EOK && ret != ERR_NO_POSIX) { - /* We can only finish the id_op on error as the connection --- -2.14.3 - diff --git a/SOURCES/0073-DP-Create-a-new-handler-function-getAccountDomain.patch b/SOURCES/0073-DP-Create-a-new-handler-function-getAccountDomain.patch deleted file mode 100644 index 72a0f99..0000000 --- a/SOURCES/0073-DP-Create-a-new-handler-function-getAccountDomain.patch +++ /dev/null @@ -1,455 +0,0 @@ -From 1bed72e4faa2734b0eef6a107b2dc24bf052e576 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 30 Oct 2017 20:50:41 +0100 -Subject: [PATCH 73/83] DP: Create a new handler function getAccountDomain() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adds a new method getAccountDomain() which is a bit similar to -getAccountInfo, except it doesn't fetch, parse and store the entry, but -just returns the domain or a subdomain the entry was found in. - -At the moment, the method only supports requests by ID. - -A default handler is provided (and in this patch used by all the -domains) which returns ERR_GET_ACCT_DOM_NOT_SUPPORTED. This return -code should be evaluated by the responder so that this DP method is -not called again, because it's not supported by the back end type. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit c0f9f5a0f6d71a1596ee3cef549b4b02295313c3) ---- - src/providers/ad/ad_init.c | 4 + - src/providers/data_provider/dp.h | 20 ++++ - src/providers/data_provider/dp_custom_data.h | 6 ++ - src/providers/data_provider/dp_iface.c | 3 +- - src/providers/data_provider/dp_iface.h | 17 ++++ - src/providers/data_provider/dp_iface.xml | 7 ++ - src/providers/data_provider/dp_iface_generated.c | 31 +++++++ - src/providers/data_provider/dp_iface_generated.h | 5 + - src/providers/data_provider/dp_target_id.c | 113 +++++++++++++++++++++++ - src/providers/files/files_init.c | 6 ++ - src/providers/ipa/ipa_init.c | 4 + - src/providers/ldap/ldap_init.c | 4 + - src/providers/proxy/proxy_init.c | 4 + - src/util/util_errors.c | 1 + - src/util/util_errors.h | 1 + - 15 files changed, 225 insertions(+), 1 deletion(-) - -diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c -index e62025d4acd24844a5c7082d00c597516f35de16..7efb6aa71cbd2551422c87e0b0c5c1fe91390375 100644 ---- a/src/providers/ad/ad_init.c -+++ b/src/providers/ad/ad_init.c -@@ -510,6 +510,10 @@ errno_t sssm_ad_id_init(TALLOC_CTX *mem_ctx, - sdap_online_check_handler_send, sdap_online_check_handler_recv, id_ctx->sdap_id_ctx, - struct sdap_id_ctx, void, struct dp_reply_std); - -+ dp_set_method(dp_methods, DPM_ACCT_DOMAIN_HANDLER, -+ default_account_domain_send, default_account_domain_recv, NULL, -+ void, struct dp_get_acct_domain_data, struct dp_reply_std); -+ - return EOK; - } - -diff --git a/src/providers/data_provider/dp.h b/src/providers/data_provider/dp.h -index aa5b781158c54545b26034602bb25db46b189e87..ceb49da53b88142924e1792c6f64a22ec369677b 100644 ---- a/src/providers/data_provider/dp.h -+++ b/src/providers/data_provider/dp.h -@@ -82,6 +82,7 @@ enum dp_methods { - DPM_HOSTID_HANDLER, - DPM_DOMAINS_HANDLER, - DPM_SESSION_HANDLER, -+ DPM_ACCT_DOMAIN_HANDLER, - - DPM_REFRESH_ACCESS_RULES, - -@@ -179,4 +180,23 @@ void dp_sbus_reset_users_memcache(struct data_provider *provider); - void dp_sbus_reset_groups_memcache(struct data_provider *provider); - void dp_sbus_reset_initgr_memcache(struct data_provider *provider); - -+/* -+ * A dummy handler for DPM_ACCT_DOMAIN_HANDLER. -+ * -+ * Its purpose is to always return ERR_GET_ACCT_DOM_NOT_SUPPORTED -+ * which the responder should evaluate as "this back end does not -+ * support locating entries' domain" and never call -+ * DPM_ACCT_DOMAIN_HANDLER again -+ * -+ * This request cannot fail, except for critical errors like OOM. -+ */ -+struct tevent_req * -+default_account_domain_send(TALLOC_CTX *mem_ctx, -+ void *unused_ctx, -+ struct dp_get_acct_domain_data *data, -+ struct dp_req_params *params); -+errno_t default_account_domain_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ struct dp_reply_std *data); -+ - #endif /* _DP_H_ */ -diff --git a/src/providers/data_provider/dp_custom_data.h b/src/providers/data_provider/dp_custom_data.h -index d9de288b62f4f6763ceb205dc596876cfc58bf6c..7c64bde4513961e79200e852c7277f77e064d5a3 100644 ---- a/src/providers/data_provider/dp_custom_data.h -+++ b/src/providers/data_provider/dp_custom_data.h -@@ -43,6 +43,12 @@ struct dp_subdomains_data { - const char *domain_hint; - }; - -+struct dp_get_acct_domain_data { -+ uint32_t entry_type; -+ uint32_t filter_type; -+ const char *filter_value; -+}; -+ - struct dp_id_data { - uint32_t entry_type; - uint32_t filter_type; -diff --git a/src/providers/data_provider/dp_iface.c b/src/providers/data_provider/dp_iface.c -index 28d70e686f63a3572ac595f493aa1d59436c563f..124be0048f38a93d06561ff7b0d1916838587103 100644 ---- a/src/providers/data_provider/dp_iface.c -+++ b/src/providers/data_provider/dp_iface.c -@@ -33,7 +33,8 @@ struct iface_dp iface_dp = { - .autofsHandler = dp_autofs_handler, - .hostHandler = dp_host_handler, - .getDomains = dp_subdomains_handler, -- .getAccountInfo = dp_get_account_info_handler -+ .getAccountInfo = dp_get_account_info_handler, -+ .getAccountDomain = dp_get_account_domain_handler, - }; - - struct iface_dp_backend iface_dp_backend = { -diff --git a/src/providers/data_provider/dp_iface.h b/src/providers/data_provider/dp_iface.h -index 759b9e6c9eb7f53836ae0b641b34e6c31e65779f..0a2f81eb5c108aa7596c974157b0dfafb041869f 100644 ---- a/src/providers/data_provider/dp_iface.h -+++ b/src/providers/data_provider/dp_iface.h -@@ -58,6 +58,23 @@ errno_t dp_subdomains_handler(struct sbus_request *sbus_req, - void *dp_cli, - const char *domain_hint); - -+/* -+ * Return a domain the account belongs to. -+ * -+ * The request uses the dp_reply_std structure for reply, with the following -+ * semantics: -+ * - DP_ERR_OK - it is expected that the string message contains the domain name -+ * the entry was found in. A 'negative' reply where the -+ * request returns DP_ERR_OK, but no domain should be treated -+ * as authoritative, as if the entry does not exist. -+ * - DP_ERR_* - the string message contains error string that corresponds -+ * to the errno field in dp_reply_std(). -+ */ -+errno_t dp_get_account_domain_handler(struct sbus_request *sbus_req, -+ void *dp_cli, -+ uint32_t entry_type, -+ const char *filter); -+ - /* org.freedesktop.sssd.DataProvider.Backend */ - errno_t dp_backend_is_online(struct sbus_request *sbus_req, - void *dp_cli, -diff --git a/src/providers/data_provider/dp_iface.xml b/src/providers/data_provider/dp_iface.xml -index 2bfa9dfa7e9d02d2d12c3358967f6969438a97a2..c2431850bca4baa529fb18e0480e781308b12dd6 100644 ---- a/src/providers/data_provider/dp_iface.xml -+++ b/src/providers/data_provider/dp_iface.xml -@@ -79,5 +79,12 @@ - - - -+ -+ -+ -+ -+ -+ -+ - - -diff --git a/src/providers/data_provider/dp_iface_generated.c b/src/providers/data_provider/dp_iface_generated.c -index 11ee2e24a69cc8d4d19fdbeed613e76081aef15d..4d093444536b15d8a17f7e507b93948e1df6ffee 100644 ---- a/src/providers/data_provider/dp_iface_generated.c -+++ b/src/providers/data_provider/dp_iface_generated.c -@@ -313,6 +313,30 @@ int iface_dp_getAccountInfo_finish(struct sbus_request *req, uint16_t arg_dp_err - DBUS_TYPE_INVALID); - } - -+/* arguments for org.freedesktop.sssd.dataprovider.getAccountDomain */ -+const struct sbus_arg_meta iface_dp_getAccountDomain__in[] = { -+ { "entry_type", "u" }, -+ { "filter", "s" }, -+ { NULL, } -+}; -+ -+/* arguments for org.freedesktop.sssd.dataprovider.getAccountDomain */ -+const struct sbus_arg_meta iface_dp_getAccountDomain__out[] = { -+ { "dp_error", "q" }, -+ { "error", "u" }, -+ { "domain_name", "s" }, -+ { NULL, } -+}; -+ -+int iface_dp_getAccountDomain_finish(struct sbus_request *req, uint16_t arg_dp_error, uint32_t arg_error, const char *arg_domain_name) -+{ -+ return sbus_request_return_and_finish(req, -+ DBUS_TYPE_UINT16, &arg_dp_error, -+ DBUS_TYPE_UINT32, &arg_error, -+ DBUS_TYPE_STRING, &arg_domain_name, -+ DBUS_TYPE_INVALID); -+} -+ - /* methods for org.freedesktop.sssd.dataprovider */ - const struct sbus_method_meta iface_dp__methods[] = { - { -@@ -357,6 +381,13 @@ const struct sbus_method_meta iface_dp__methods[] = { - offsetof(struct iface_dp, getAccountInfo), - invoke_uusss_method, - }, -+ { -+ "getAccountDomain", /* name */ -+ iface_dp_getAccountDomain__in, -+ iface_dp_getAccountDomain__out, -+ offsetof(struct iface_dp, getAccountDomain), -+ invoke_us_method, -+ }, - { NULL, } - }; - -diff --git a/src/providers/data_provider/dp_iface_generated.h b/src/providers/data_provider/dp_iface_generated.h -index 541a90b0b5a5bc0a346cbd04974d33c8bb0983c5..b629ec77487328a41615f3ca7e812088730f40c4 100644 ---- a/src/providers/data_provider/dp_iface_generated.h -+++ b/src/providers/data_provider/dp_iface_generated.h -@@ -38,6 +38,7 @@ - #define IFACE_DP_HOSTHANDLER "hostHandler" - #define IFACE_DP_GETDOMAINS "getDomains" - #define IFACE_DP_GETACCOUNTINFO "getAccountInfo" -+#define IFACE_DP_GETACCOUNTDOMAIN "getAccountDomain" - - /* ------------------------------------------------------------------------ - * DBus handlers -@@ -110,6 +111,7 @@ struct iface_dp { - int (*hostHandler)(struct sbus_request *req, void *data, uint32_t arg_dp_flags, const char *arg_name, const char *arg_alias); - int (*getDomains)(struct sbus_request *req, void *data, const char *arg_domain_hint); - int (*getAccountInfo)(struct sbus_request *req, void *data, uint32_t arg_dp_flags, uint32_t arg_entry_type, const char *arg_filter, const char *arg_domain, const char *arg_extra); -+ int (*getAccountDomain)(struct sbus_request *req, void *data, uint32_t arg_entry_type, const char *arg_filter); - }; - - /* finish function for autofsHandler */ -@@ -124,6 +126,9 @@ int iface_dp_getDomains_finish(struct sbus_request *req, uint16_t arg_dp_error, - /* finish function for getAccountInfo */ - int iface_dp_getAccountInfo_finish(struct sbus_request *req, uint16_t arg_dp_error, uint32_t arg_error, const char *arg_error_message); - -+/* finish function for getAccountDomain */ -+int iface_dp_getAccountDomain_finish(struct sbus_request *req, uint16_t arg_dp_error, uint32_t arg_error, const char *arg_domain_name); -+ - /* ------------------------------------------------------------------------ - * DBus Interface Metadata - * -diff --git a/src/providers/data_provider/dp_target_id.c b/src/providers/data_provider/dp_target_id.c -index 820a6574cb3a224cce4b7d8286af306f234454a3..11a36e9ce9b1aefcabb04dfe51395b6f4e4bc899 100644 ---- a/src/providers/data_provider/dp_target_id.c -+++ b/src/providers/data_provider/dp_target_id.c -@@ -490,3 +490,116 @@ done: - - return ret; - } -+ -+static bool -+check_and_parse_acct_domain_filter(struct dp_get_acct_domain_data *data, -+ const char *filter) -+{ -+ /* We will use sizeof() to determine the length of a string so we don't -+ * call strlen over and over again with each request. Not a bottleneck, -+ * but unnecessary and simple to avoid. */ -+ static struct { -+ const char *name; -+ size_t lenght; -+ uint32_t type; -+ } types[] = {FILTER_TYPE("idnumber", BE_FILTER_IDNUM), -+ {0, 0, 0}}; -+ int i; -+ -+ if (SBUS_IS_STRING_EMPTY(filter)) { -+ return false; -+ } -+ -+ for (i = 0; types[i].name != NULL; i++) { -+ if (strncmp(filter, types[i].name, types[i].lenght) == 0) { -+ data->filter_type = types[i].type; -+ data->filter_value = SBUS_SET_STRING(&filter[types[i].lenght]); -+ return true; -+ } -+ } -+ -+ if (strcmp(filter, ENUM_INDICATOR) == 0) { -+ data->filter_type = BE_FILTER_ENUM; -+ data->filter_value = NULL; -+ return true; -+ } -+ -+ return false; -+} -+ -+errno_t dp_get_account_domain_handler(struct sbus_request *sbus_req, -+ void *dp_cli, -+ uint32_t entry_type, -+ const char *filter) -+{ -+ struct dp_get_acct_domain_data *data; -+ const char *key = NULL; -+ errno_t ret; -+ -+ data = talloc_zero(sbus_req, struct dp_get_acct_domain_data); -+ if (data == NULL) { -+ return ENOMEM; -+ } -+ data->entry_type = entry_type; -+ -+ if (!check_and_parse_acct_domain_filter(data, filter)) { -+ ret = EINVAL; -+ goto done; -+ } -+ -+ dp_req_with_reply(dp_cli, NULL, "AccountDomain", key, sbus_req, -+ DPT_ID, DPM_ACCT_DOMAIN_HANDLER, 0, data, -+ dp_req_reply_std, struct dp_reply_std); -+ -+ ret = EOK; -+ -+done: -+ if (ret != EOK) { -+ talloc_free(data); -+ } -+ -+ return ret; -+} -+ -+struct default_account_domain_state { -+ struct dp_reply_std reply; -+}; -+ -+struct tevent_req * -+default_account_domain_send(TALLOC_CTX *mem_ctx, -+ void *unused_ctx, -+ struct dp_get_acct_domain_data *data, -+ struct dp_req_params *params) -+{ -+ struct default_account_domain_state *state; -+ struct tevent_req *req; -+ -+ req = tevent_req_create(mem_ctx, &state, -+ struct default_account_domain_state); -+ if (req == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); -+ return NULL; -+ } -+ -+ dp_reply_std_set(&state->reply, -+ DP_ERR_DECIDE, ERR_GET_ACCT_DOM_NOT_SUPPORTED, -+ NULL); -+ tevent_req_done(req); -+ tevent_req_post(req, params->ev); -+ return req; -+} -+ -+errno_t default_account_domain_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ struct dp_reply_std *data) -+{ -+ struct default_account_domain_state *state = NULL; -+ -+ state = tevent_req_data(req, struct default_account_domain_state); -+ -+ TEVENT_REQ_RETURN_ON_ERROR(req); -+ -+ *data = state->reply; -+ -+ return EOK; -+} -diff --git a/src/providers/files/files_init.c b/src/providers/files/files_init.c -index b91dfbac9bf9d4b678ebdfa6b1cb0971b4477dd9..8e5cd4cf913b79653616120d6ed6540e62ade932 100644 ---- a/src/providers/files/files_init.c -+++ b/src/providers/files/files_init.c -@@ -88,5 +88,11 @@ int sssm_files_id_init(TALLOC_CTX *mem_ctx, - ctx, struct files_id_ctx, - struct dp_id_data, struct dp_reply_std); - -+ dp_set_method(dp_methods, DPM_ACCT_DOMAIN_HANDLER, -+ default_account_domain_send, -+ default_account_domain_recv, -+ NULL, void, -+ struct dp_get_acct_domain_data, struct dp_reply_std); -+ - return EOK; - } -diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c -index f335d51fd65959d256c54a5d92c594a24e895b7c..754e5315c3a7f84ac2901986ecdda73e4dad26bc 100644 ---- a/src/providers/ipa/ipa_init.c -+++ b/src/providers/ipa/ipa_init.c -@@ -754,6 +754,10 @@ errno_t sssm_ipa_id_init(TALLOC_CTX *mem_ctx, - sdap_online_check_handler_send, sdap_online_check_handler_recv, id_ctx->sdap_id_ctx, - struct sdap_id_ctx, void, struct dp_reply_std); - -+ dp_set_method(dp_methods, DPM_ACCT_DOMAIN_HANDLER, -+ default_account_domain_send, default_account_domain_recv, NULL, -+ void, struct dp_get_acct_domain_data, struct dp_reply_std); -+ - return EOK; - } - -diff --git a/src/providers/ldap/ldap_init.c b/src/providers/ldap/ldap_init.c -index 43d905893081c31ed659fd1ef8343f965bdc5af0..c0ede8941ee8480c2ec4765f89d12e903edcf012 100644 ---- a/src/providers/ldap/ldap_init.c -+++ b/src/providers/ldap/ldap_init.c -@@ -531,6 +531,10 @@ errno_t sssm_ldap_id_init(TALLOC_CTX *mem_ctx, - sdap_online_check_handler_send, sdap_online_check_handler_recv, id_ctx, - struct sdap_id_ctx, void, struct dp_reply_std); - -+ dp_set_method(dp_methods, DPM_ACCT_DOMAIN_HANDLER, -+ default_account_domain_send, default_account_domain_recv, NULL, -+ void, struct dp_get_acct_domain_data, struct dp_reply_std); -+ - return EOK; - } - -diff --git a/src/providers/proxy/proxy_init.c b/src/providers/proxy/proxy_init.c -index 7c9d3dafbdf1f9448cc8f8b473aea15cf4206afc..7d997cb16ee62f10f4b86c9c3ab373a48676fe75 100644 ---- a/src/providers/proxy/proxy_init.c -+++ b/src/providers/proxy/proxy_init.c -@@ -351,6 +351,10 @@ errno_t sssm_proxy_id_init(TALLOC_CTX *mem_ctx, - proxy_account_info_handler_send, proxy_account_info_handler_recv, ctx, - struct proxy_id_ctx, struct dp_id_data, struct dp_reply_std); - -+ dp_set_method(dp_methods, DPM_ACCT_DOMAIN_HANDLER, -+ default_account_domain_send, default_account_domain_recv, NULL, -+ void, struct dp_get_acct_domain_data, struct dp_reply_std); -+ - ret = EOK; - - done: -diff --git a/src/util/util_errors.c b/src/util/util_errors.c -index 5a92a2dcf6e65f93bc9732cebf562756357123b6..9a9ba3f3063cab4afb538c3a58527a2d2ed3fffd 100644 ---- a/src/util/util_errors.c -+++ b/src/util/util_errors.c -@@ -115,6 +115,7 @@ struct err_string error_to_str[] = { - { "Unable to initialize SSL" }, /* ERR_SSL_FAILURE */ - { "Unable to verify peer" }, /* ERR_UNABLE_TO_VERIFY_PEER */ - { "Unable to resolve host" }, /* ERR_UNABLE_TO_RESOLVE_HOST */ -+ { "GetAccountDomain() not supported" }, /* ERR_GET_ACCT_DOM_NOT_SUPPORTED */ - { "ERR_LAST" } /* ERR_LAST */ - }; - -diff --git a/src/util/util_errors.h b/src/util/util_errors.h -index 509ccb805fb97e59f9da0ea2f991ece2f2030ca4..5ee9862c3f2f60c078693b1b85a40f15436e818c 100644 ---- a/src/util/util_errors.h -+++ b/src/util/util_errors.h -@@ -137,6 +137,7 @@ enum sssd_errors { - ERR_SSL_FAILURE, - ERR_UNABLE_TO_VERIFY_PEER, - ERR_UNABLE_TO_RESOLVE_HOST, -+ ERR_GET_ACCT_DOM_NOT_SUPPORTED, - ERR_LAST /* ALWAYS LAST */ - }; - --- -2.14.3 - diff --git a/SOURCES/0074-AD-Implement-a-real-getAccountDomain-handler-for-the.patch b/SOURCES/0074-AD-Implement-a-real-getAccountDomain-handler-for-the.patch deleted file mode 100644 index 980917f..0000000 --- a/SOURCES/0074-AD-Implement-a-real-getAccountDomain-handler-for-the.patch +++ /dev/null @@ -1,553 +0,0 @@ -From 427a1f162e0ceb97e4e9491f81048646bd144910 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 7 Nov 2017 17:01:34 +0100 -Subject: [PATCH 74/83] AD: Implement a real getAccountDomain handler for the - AD provider -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -After this patch, the AD provider drops the default getAccountDomain -handler in favor of the handler added in this patch. - -The handler first checks if the domain is eligible for locating -the domain of an ID with the help of the Global Catalog at all, which -only happens if: - - the Global Catalog is enabled - - POSIX IDs are used, not ID-mapping - - the Global catalog contains some POSIX IDs - -If all these hold true, then the Global Catalog is searched with -an empty search base, which searches the whole GC. If a single entry -is returned, its original DN is converted to a domain name and returned. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit 095844d6b48aef483c33e5a369a405ae686e044d) ---- - src/providers/ad/ad_id.c | 469 +++++++++++++++++++++++++++++++++++++++++++++ - src/providers/ad/ad_id.h | 10 + - src/providers/ad/ad_init.c | 4 +- - 3 files changed, 481 insertions(+), 2 deletions(-) - -diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c -index e14ada386f16851a65097952c85e57b7acda14aa..0b8f49819405c7dbbfa18b5359f7743441dc65e5 100644 ---- a/src/providers/ad/ad_id.c -+++ b/src/providers/ad/ad_id.c -@@ -27,6 +27,7 @@ - #include "providers/ad/ad_pac.h" - #include "providers/ldap/sdap_async_enum.h" - #include "providers/ldap/sdap_idmap.h" -+#include "providers/ldap/sdap_async.h" - - static void - disable_gc(struct ad_options *ad_options) -@@ -1076,3 +1077,471 @@ ad_enumeration_recv(struct tevent_req *req) - return EOK; - } - -+static errno_t ad_get_account_domain_prepare_search(struct tevent_req *req); -+static errno_t ad_get_account_domain_connect_retry(struct tevent_req *req); -+static void ad_get_account_domain_connect_done(struct tevent_req *subreq); -+static void ad_get_account_domain_posix_check_done(struct tevent_req *subreq); -+static void ad_get_account_domain_search(struct tevent_req *req); -+static void ad_get_account_domain_search_done(struct tevent_req *subreq); -+static void ad_get_account_domain_evaluate(struct tevent_req *req); -+ -+struct ad_get_account_domain_state { -+ struct tevent_context *ev; -+ struct ad_id_ctx *id_ctx; -+ struct sdap_id_ctx *sdap_id_ctx; -+ struct sdap_domain *sdom; -+ uint32_t entry_type; -+ uint32_t filter_type; -+ char *clean_filter; -+ -+ bool twopass; -+ -+ struct sdap_search_base **search_bases; -+ size_t base_iter; -+ const char *base_filter; -+ char *filter; -+ const char **attrs; -+ int dp_error; -+ struct dp_reply_std reply; -+ struct sdap_id_op *op; -+ struct sysdb_attrs **objects; -+ size_t count; -+ -+ const char *found_domain_name; -+}; -+ -+struct tevent_req * -+ad_get_account_domain_send(TALLOC_CTX *mem_ctx, -+ struct ad_id_ctx *id_ctx, -+ struct dp_get_acct_domain_data *data, -+ struct dp_req_params *params) -+{ -+ struct ad_get_account_domain_state *state; -+ struct tevent_req *req; -+ errno_t ret; -+ bool use_id_mapping; -+ -+ req = tevent_req_create(mem_ctx, &state, -+ struct ad_get_account_domain_state); -+ if (req == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); -+ return NULL; -+ } -+ state->ev = params->ev; -+ state->id_ctx = id_ctx; -+ state->sdap_id_ctx = id_ctx->sdap_id_ctx; -+ state->entry_type = data->entry_type & BE_REQ_TYPE_MASK; -+ state->filter_type = data->filter_type; -+ state->attrs = talloc_array(state, const char *, 2); -+ if (state->attrs == NULL) { -+ ret = ENOMEM; -+ goto immediately; -+ } -+ state->attrs[0] = "objectclass"; -+ state->attrs[1] = NULL; -+ -+ if (params->be_ctx->domain->mpg == true -+ || state->entry_type == BE_REQ_USER_AND_GROUP) { -+ state->twopass = true; -+ if (state->entry_type == BE_REQ_USER_AND_GROUP) { -+ state->entry_type = BE_REQ_GROUP; -+ } -+ } -+ -+ /* The get-account-domain request only works with GC */ -+ if (dp_opt_get_bool(id_ctx->ad_options->basic, AD_ENABLE_GC) == false) { -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "Global catalog support is not enabled, " -+ "cannot locate the account domain\n"); -+ ret = ERR_GET_ACCT_DOM_NOT_SUPPORTED; -+ goto immediately; -+ } -+ -+ state->sdom = sdap_domain_get(id_ctx->sdap_id_ctx->opts, -+ params->be_ctx->domain); -+ if (state->sdom == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find sdap_domain\n"); -+ ret = EIO; -+ goto immediately; -+ } -+ -+ /* Currently we only support locating the account domain -+ * if ID mapping is disabled. With ID mapping enabled, we can -+ * already shortcut the 'real' ID request -+ */ -+ use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( -+ state->sdap_id_ctx->opts->idmap_ctx, -+ state->sdom->dom->name, -+ state->sdom->dom->domain_id); -+ if (use_id_mapping == true) { -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "No point in locating domain with GC if ID-mapping " -+ "is enabled\n"); -+ ret = ERR_GET_ACCT_DOM_NOT_SUPPORTED; -+ goto immediately; -+ } -+ -+ ret = sss_filter_sanitize(state, data->filter_value, &state->clean_filter); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Cannot sanitize filter [%d]: %s\n", ret, sss_strerror(ret)); -+ goto immediately; -+ } -+ -+ ret = ad_get_account_domain_prepare_search(req); -+ if (ret != EOK) { -+ goto immediately; -+ } -+ -+ /* FIXME - should gc_ctx always default to ignore_offline on creation -+ * time rather than setting the flag on first use? -+ */ -+ id_ctx->gc_ctx->ignore_mark_offline = true; -+ state->op = sdap_id_op_create(state, id_ctx->gc_ctx->conn_cache); -+ if (state->op == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create failed\n"); -+ ret = ENOMEM; -+ goto immediately; -+ } -+ -+ ret = ad_get_account_domain_connect_retry(req); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Connection error"); -+ goto immediately; -+ } -+ -+ return req; -+ -+immediately: -+ dp_reply_std_set(&state->reply, DP_ERR_DECIDE, ret, NULL); -+ -+ /* TODO For backward compatibility we always return EOK to DP now. */ -+ tevent_req_done(req); -+ tevent_req_post(req, params->ev); -+ -+ return req; -+} -+ -+static errno_t ad_get_account_domain_prepare_search(struct tevent_req *req) -+{ -+ struct ad_get_account_domain_state *state = tevent_req_data(req, -+ struct ad_get_account_domain_state); -+ const char *attr_name = NULL; -+ const char *objectclass = NULL; -+ -+ switch (state->entry_type) { -+ case BE_REQ_USER: -+ state->search_bases = state->sdom->user_search_bases; -+ attr_name = state->sdap_id_ctx->opts->user_map[SDAP_AT_USER_UID].name; -+ objectclass = state->sdap_id_ctx->opts->user_map[SDAP_OC_USER].name; -+ break; -+ case BE_REQ_GROUP: -+ state->search_bases = state->sdom->group_search_bases; -+ attr_name = state->sdap_id_ctx->opts->group_map[SDAP_AT_GROUP_GID].name; -+ objectclass = state->sdap_id_ctx->opts->group_map[SDAP_OC_GROUP].name; -+ break; -+ default: -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Unsupported request type %X\n", -+ state->entry_type & BE_REQ_TYPE_MASK); -+ return EINVAL; -+ } -+ -+ switch (state->filter_type) { -+ case BE_FILTER_IDNUM: -+ break; -+ default: -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Unsupported filter type %X\n", state->filter_type); -+ return EINVAL; -+ } -+ -+ talloc_zfree(state->base_filter); -+ state->base_filter = talloc_asprintf(state, -+ "(&(%s=%s)(objectclass=%s))", -+ attr_name, -+ state->clean_filter, -+ objectclass); -+ if (state->base_filter == NULL) { -+ return ENOMEM; -+ } -+ -+ return EOK; -+} -+ -+static errno_t ad_get_account_domain_connect_retry(struct tevent_req *req) -+{ -+ struct ad_get_account_domain_state *state = tevent_req_data(req, -+ struct ad_get_account_domain_state); -+ struct tevent_req *subreq; -+ errno_t ret; -+ -+ subreq = sdap_id_op_connect_send(state->op, state, &ret); -+ if (subreq == NULL) { -+ return ENOMEM; -+ } -+ -+ tevent_req_set_callback(subreq, ad_get_account_domain_connect_done, req); -+ return ret; -+} -+ -+static void ad_get_account_domain_connect_done(struct tevent_req *subreq) -+{ -+ struct tevent_req *req = tevent_req_callback_data(subreq, -+ struct tevent_req); -+ struct ad_get_account_domain_state *state = tevent_req_data(req, -+ struct ad_get_account_domain_state); -+ int dp_error = DP_ERR_FATAL; -+ errno_t ret; -+ -+ ret = sdap_id_op_connect_recv(subreq, &dp_error); -+ talloc_zfree(subreq); -+ -+ if (ret != EOK) { -+ state->dp_error = dp_error; -+ tevent_req_error(req, ret); -+ return; -+ } -+ -+ /* If POSIX attributes have been requested with an AD server and we -+ * have no idea about POSIX attributes support, run a one-time check -+ */ -+ if (state->sdap_id_ctx->srv_opts && -+ state->sdap_id_ctx->srv_opts->posix_checked == false) { -+ subreq = sdap_gc_posix_check_send(state, -+ state->ev, -+ state->sdap_id_ctx->opts, -+ sdap_id_op_handle(state->op), -+ dp_opt_get_int( -+ state->sdap_id_ctx->opts->basic, -+ SDAP_SEARCH_TIMEOUT)); -+ if (subreq == NULL) { -+ tevent_req_error(req, ENOMEM); -+ return; -+ } -+ tevent_req_set_callback(subreq, ad_get_account_domain_posix_check_done, req); -+ return; -+ } -+ -+ ad_get_account_domain_search(req); -+} -+ -+static void ad_get_account_domain_posix_check_done(struct tevent_req *subreq) -+{ -+ struct tevent_req *req = tevent_req_callback_data(subreq, -+ struct tevent_req); -+ struct ad_get_account_domain_state *state = tevent_req_data(req, -+ struct ad_get_account_domain_state); -+ int dp_error = DP_ERR_FATAL; -+ bool has_posix; -+ errno_t ret; -+ errno_t ret2; -+ -+ ret = sdap_gc_posix_check_recv(subreq, &has_posix); -+ talloc_zfree(subreq); -+ if (ret != EOK) { -+ /* We can only finish the id_op on error as the connection -+ * is re-used by the real search -+ */ -+ ret2 = sdap_id_op_done(state->op, ret, &dp_error); -+ if (dp_error == DP_ERR_OK && ret2 != EOK) { -+ /* retry */ -+ ret = ad_get_account_domain_connect_retry(req); -+ if (ret != EOK) { -+ tevent_req_error(req, ret); -+ } -+ return; -+ } -+ -+ tevent_req_error(req, ret); -+ return; -+ } -+ -+ state->sdap_id_ctx->srv_opts->posix_checked = true; -+ -+ /* -+ * If the GC has no POSIX attributes, there is nothing we can do. -+ * Return an error and let the responders disable the functionality -+ * from now on. -+ */ -+ if (has_posix == false) { -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "The Global Catalog has no POSIX attributes\n"); -+ -+ disable_gc(state->id_ctx->ad_options); -+ dp_reply_std_set(&state->reply, -+ DP_ERR_DECIDE, ERR_GET_ACCT_DOM_NOT_SUPPORTED, -+ NULL); -+ tevent_req_done(req); -+ return; -+ } -+ -+ ad_get_account_domain_search(req); -+} -+ -+static void ad_get_account_domain_search(struct tevent_req *req) -+{ -+ struct ad_get_account_domain_state *state = tevent_req_data(req, -+ struct ad_get_account_domain_state); -+ struct tevent_req *subreq; -+ -+ talloc_zfree(state->filter); -+ state->filter = sdap_combine_filters(state, state->base_filter, -+ state->search_bases[state->base_iter]->filter); -+ if (state->filter == NULL) { -+ tevent_req_error(req, ENOMEM); -+ return; -+ } -+ -+ subreq = sdap_get_generic_send(state, state->ev, state->sdap_id_ctx->opts, -+ sdap_id_op_handle(state->op), -+ "", -+ LDAP_SCOPE_SUBTREE, -+ state->filter, -+ state->attrs, NULL, 0, -+ dp_opt_get_int(state->sdap_id_ctx->opts->basic, -+ SDAP_SEARCH_TIMEOUT), -+ false); -+ -+ if (subreq == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n"); -+ tevent_req_error(req, EIO); -+ return; -+ } -+ -+ tevent_req_set_callback(subreq, ad_get_account_domain_search_done, req); -+} -+ -+static void ad_get_account_domain_search_done(struct tevent_req *subreq) -+{ -+ struct tevent_req *req = tevent_req_callback_data(subreq, -+ struct tevent_req); -+ struct ad_get_account_domain_state *state = tevent_req_data(req, -+ struct ad_get_account_domain_state); -+ size_t count; -+ struct sysdb_attrs **objects; -+ errno_t ret; -+ -+ ret = sdap_get_generic_recv(subreq, state, -+ &count, &objects); -+ talloc_zfree(subreq); -+ if (ret) { -+ tevent_req_error(req, ret); -+ return; -+ } -+ -+ DEBUG(SSSDBG_TRACE_FUNC, -+ "Search returned %zu results.\n", count); -+ -+ if (count > 0) { -+ size_t copied; -+ -+ state->objects = -+ talloc_realloc(state, -+ state->objects, -+ struct sysdb_attrs *, -+ state->count + count + 1); -+ if (!state->objects) { -+ tevent_req_error(req, ENOMEM); -+ return; -+ } -+ -+ copied = sdap_steal_objects_in_dom(state->sdap_id_ctx->opts, -+ state->objects, -+ state->count, -+ NULL, -+ objects, count, -+ false); -+ -+ state->count += copied; -+ state->objects[state->count] = NULL; -+ } -+ -+ /* Even though we search with an empty search base (=across all domains) -+ * the reason we iterate over search bases is that the search bases can -+ * also contain a filter which might restrict the IDs we find -+ */ -+ state->base_iter++; -+ if (state->search_bases[state->base_iter]) { -+ /* There are more search bases to try */ -+ ad_get_account_domain_search(req); -+ return; -+ } -+ -+ /* No more searches, evaluate results */ -+ ad_get_account_domain_evaluate(req); -+} -+ -+static void ad_get_account_domain_evaluate(struct tevent_req *req) -+{ -+ struct ad_get_account_domain_state *state = tevent_req_data(req, -+ struct ad_get_account_domain_state); -+ struct sss_domain_info *obj_dom; -+ errno_t ret; -+ -+ if (state->count == 0) { -+ if (state->twopass -+ && state->entry_type != BE_REQ_USER) { -+ DEBUG(SSSDBG_TRACE_FUNC, "Retrying search\n"); -+ -+ state->entry_type = BE_REQ_USER; -+ state->base_iter = 0; -+ ret = ad_get_account_domain_prepare_search(req); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "Cannot retry search\n"); -+ tevent_req_error(req, ret); -+ return; -+ } -+ -+ ad_get_account_domain_search(req); -+ return; -+ } -+ -+ DEBUG(SSSDBG_TRACE_FUNC, "Not found\n"); -+ dp_reply_std_set(&state->reply, DP_ERR_DECIDE, ERR_NOT_FOUND, NULL); -+ tevent_req_done(req); -+ return; -+ } else if (state->count > 1) { -+ /* FIXME: If more than one entry was found, return error for now -+ * as the account requsts have no way of returning multiple -+ * messages back until we switch to the rdp_* requests -+ * from the responder side -+ */ -+ DEBUG(SSSDBG_OP_FAILURE, "Multiple entries found, error!\n"); -+ dp_reply_std_set(&state->reply, DP_ERR_DECIDE, ERANGE, NULL); -+ tevent_req_done(req); -+ return; -+ } -+ -+ /* Exactly one entry was found */ -+ obj_dom = sdap_get_object_domain(state->sdap_id_ctx->opts, -+ state->objects[0], -+ state->sdom->dom); -+ if (obj_dom == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Could not match entry with domain!\n"); -+ dp_reply_std_set(&state->reply, DP_ERR_DECIDE, ERR_NOT_FOUND, NULL); -+ tevent_req_done(req); -+ return; -+ } -+ -+ DEBUG(SSSDBG_TRACE_INTERNAL, -+ "Found object in domain %s\n", obj_dom->name); -+ dp_reply_std_set(&state->reply, DP_ERR_DECIDE, EOK, obj_dom->name); -+ tevent_req_done(req); -+} -+ -+errno_t ad_get_account_domain_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ struct dp_reply_std *data) -+{ -+ struct ad_get_account_domain_state *state = NULL; -+ -+ state = tevent_req_data(req, struct ad_get_account_domain_state); -+ -+ TEVENT_REQ_RETURN_ON_ERROR(req); -+ -+ *data = state->reply; -+ -+ return EOK; -+} -diff --git a/src/providers/ad/ad_id.h b/src/providers/ad/ad_id.h -index 145fdc8f2dfdeda5a17b0ce5892a547da934c244..5154393c5f125f472c92155006aac14d04bbca1a 100644 ---- a/src/providers/ad/ad_id.h -+++ b/src/providers/ad/ad_id.h -@@ -54,4 +54,14 @@ ad_enumeration_send(TALLOC_CTX *mem_ctx, - errno_t - ad_enumeration_recv(struct tevent_req *req); - -+struct tevent_req * -+ad_get_account_domain_send(TALLOC_CTX *mem_ctx, -+ struct ad_id_ctx *id_ctx, -+ struct dp_get_acct_domain_data *data, -+ struct dp_req_params *params); -+ -+errno_t ad_get_account_domain_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ struct dp_reply_std *data); -+ - #endif /* AD_ID_H_ */ -diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c -index 7efb6aa71cbd2551422c87e0b0c5c1fe91390375..22a3ecf7e5a020da88b6c9164f5999d13a9aa5e3 100644 ---- a/src/providers/ad/ad_init.c -+++ b/src/providers/ad/ad_init.c -@@ -511,8 +511,8 @@ errno_t sssm_ad_id_init(TALLOC_CTX *mem_ctx, - struct sdap_id_ctx, void, struct dp_reply_std); - - dp_set_method(dp_methods, DPM_ACCT_DOMAIN_HANDLER, -- default_account_domain_send, default_account_domain_recv, NULL, -- void, struct dp_get_acct_domain_data, struct dp_reply_std); -+ ad_get_account_domain_send, ad_get_account_domain_recv, id_ctx, -+ struct ad_id_ctx, struct dp_get_acct_domain_data, struct dp_reply_std); - - return EOK; - } --- -2.14.3 - diff --git a/SOURCES/0075-RESP-Expose-DP-method-getAccountDomain-to-responders.patch b/SOURCES/0075-RESP-Expose-DP-method-getAccountDomain-to-responders.patch deleted file mode 100644 index 208b5dd..0000000 --- a/SOURCES/0075-RESP-Expose-DP-method-getAccountDomain-to-responders.patch +++ /dev/null @@ -1,239 +0,0 @@ -From cac78825ba2fcb2efcd7ff2e58b562b370bbb28c Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 30 Oct 2017 20:51:40 +0100 -Subject: [PATCH 75/83] RESP: Expose DP method getAccountDomain() to responders -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adds a tevent request that calls the getAccountDomain DP method. -This request will be used by responders to locate an object's domain. - -At the moment, only looking up UIDs and GIDs is supported. - -Internally, until we switch to the rdp_ interface everywhere, this -interface hooks into the sss_dp_issue_request(). When we switch to -the rdp_ interface, we'll be able to provide a nicer method parameters -as well. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit 95fd82a4d7b50e64fed6906bc5345f271e8247d9) ---- - src/responder/common/responder.h | 36 +++++++ - src/responder/common/responder_get_domains.c | 155 +++++++++++++++++++++++++++ - 2 files changed, 191 insertions(+) - -diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h -index 9a57df558994c418d440eabf4a29f69c4a47faa5..9400e4b60d9fc77c23710174e4c00a83f6395985 100644 ---- a/src/responder/common/responder.h -+++ b/src/responder/common/responder.h -@@ -375,6 +375,42 @@ struct tevent_req *sss_dp_get_domains_send(TALLOC_CTX *mem_ctx, - - errno_t sss_dp_get_domains_recv(struct tevent_req *req); - -+/* -+ * Call a getAccountDomain request -+ * -+ * Only requests by ID are supported. -+ * -+ * @param mem_ctx Parent memory context -+ * @param rctx Responder context -+ * @param domain The SSSD domain we're querying. The response can -+ * be either NULL or come from any of domain's subdomains -+ * or domain itself -+ * @param type Either SSS_DP_USER or SSS_DP_GROUP, other types -+ * are not supported at the moment -+ * @param opt_id The ID number we're trying to locate -+ * -+ * @return A tevent request or NULL if allocating the request fails. -+ */ -+struct tevent_req *sss_dp_get_account_domain_send(TALLOC_CTX *mem_ctx, -+ struct resp_ctx *rctx, -+ struct sss_domain_info *domain, -+ enum sss_dp_acct_type type, -+ uint32_t opt_id); -+ -+/* Receive a getAccountDomain request result -+ * -+ * @param mem_ctx The memory context that will own the contents of _domain -+ * @param req The request that had finished -+ * @para _domain Either NULL (the request did not match any domain) or -+ * a string that corresponds to either the input domain -+ * or any of its subdomains -+ * -+ * @return EOK on success, errno otherwise -+ */ -+errno_t sss_dp_get_account_domain_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ char **_domain); -+ - errno_t schedule_get_domains_task(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct resp_ctx *rctx, -diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c -index 4955af064040e03372e9a47fb264499d9a23b828..d69bce2300580beb42d3af8e66ff467db890f284 100644 ---- a/src/responder/common/responder_get_domains.c -+++ b/src/responder/common/responder_get_domains.c -@@ -642,3 +642,158 @@ errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - - return state->error; - } -+ -+/* ========== Get domain of an ccount ================= */ -+struct sss_dp_get_account_domain_info { -+ struct sss_domain_info *dom; -+ enum sss_dp_acct_type type; -+ uint32_t opt_id; -+}; -+ -+static DBusMessage *sss_dp_get_account_domain_msg(void *pvt); -+ -+struct tevent_req *sss_dp_get_account_domain_send(TALLOC_CTX *mem_ctx, -+ struct resp_ctx *rctx, -+ struct sss_domain_info *dom, -+ enum sss_dp_acct_type type, -+ uint32_t opt_id) -+{ -+ struct tevent_req *req; -+ struct sss_dp_get_account_domain_info *info; -+ struct sss_dp_req_state *state; -+ char *key; -+ errno_t ret; -+ -+ req = tevent_req_create(mem_ctx, &state, struct sss_dp_req_state); -+ if (!req) { -+ return NULL; -+ } -+ -+ info = talloc_zero(state, struct sss_dp_get_account_domain_info); -+ if (info == NULL) { -+ ret = ENOMEM; -+ goto immediately; -+ } -+ info->type = type; -+ info->opt_id = opt_id; -+ info->dom = dom; -+ -+ key = talloc_asprintf(state, "%d: %"SPRIuid"@%s", type, opt_id, dom->name); -+ if (key == NULL) { -+ ret = ENOMEM; -+ goto immediately; -+ } -+ -+ ret = sss_dp_issue_request(state, rctx, key, dom, -+ sss_dp_get_account_domain_msg, -+ info, req); -+ talloc_free(key); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Could not issue DP request [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ goto immediately; -+ } -+ -+ return req; -+ -+immediately: -+ if (ret == EOK) { -+ tevent_req_done(req); -+ } else { -+ tevent_req_error(req, ret); -+ } -+ tevent_req_post(req, rctx->ev); -+ return req; -+} -+ -+static DBusMessage * -+sss_dp_get_account_domain_msg(void *pvt) -+{ -+ DBusMessage *msg; -+ dbus_bool_t dbret; -+ struct sss_dp_get_account_domain_info *info; -+ uint32_t entry_type; -+ char *filter; -+ -+ info = talloc_get_type(pvt, struct sss_dp_get_account_domain_info); -+ -+ switch (info->type) { -+ case SSS_DP_USER: -+ entry_type = BE_REQ_USER; -+ break; -+ case SSS_DP_GROUP: -+ entry_type = BE_REQ_GROUP; -+ break; -+ case SSS_DP_USER_AND_GROUP: -+ entry_type = BE_REQ_USER_AND_GROUP; -+ break; -+ default: -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Unsupported lookup type %X for this request\n", info->type); -+ return NULL; -+ } -+ -+ filter = talloc_asprintf(info, "idnumber=%u", info->opt_id); -+ if (!filter) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); -+ return NULL; -+ } -+ -+ msg = dbus_message_new_method_call(NULL, -+ DP_PATH, -+ IFACE_DP, -+ IFACE_DP_GETACCOUNTDOMAIN); -+ if (msg == NULL) { -+ talloc_free(filter); -+ DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory?!\n"); -+ return NULL; -+ } -+ -+ /* create the message */ -+ DEBUG(SSSDBG_TRACE_FUNC, -+ "Creating request for [%s][%#x][%s][%s:-]\n", -+ info->dom->name, entry_type, be_req2str(entry_type), filter); -+ -+ dbret = dbus_message_append_args(msg, -+ DBUS_TYPE_UINT32, &entry_type, -+ DBUS_TYPE_STRING, &filter, -+ DBUS_TYPE_INVALID); -+ talloc_free(filter); -+ if (!dbret) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to build message\n"); -+ dbus_message_unref(msg); -+ return NULL; -+ } -+ -+ return msg; -+} -+ -+errno_t sss_dp_get_account_domain_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ char **_domain) -+{ -+ errno_t ret; -+ dbus_uint16_t err_maj; -+ dbus_uint32_t err_min; -+ char *msg; -+ -+ ret = sss_dp_req_recv(mem_ctx, req, &err_maj, &err_min, &msg); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Could not get account info [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ return ret; -+ } -+ -+ if (err_maj != DP_ERR_OK) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Data Provider Error: %u, %u\n", -+ (unsigned int)err_maj, (unsigned int)err_min); -+ talloc_free(msg); -+ return err_min ? err_min : EIO; -+ } -+ -+ *_domain = msg; -+ return EOK; -+} --- -2.14.3 - diff --git a/SOURCES/0076-NEGCACHE-Add-API-for-setting-and-checking-locate-acc.patch b/SOURCES/0076-NEGCACHE-Add-API-for-setting-and-checking-locate-acc.patch deleted file mode 100644 index 4d554a2..0000000 --- a/SOURCES/0076-NEGCACHE-Add-API-for-setting-and-checking-locate-acc.patch +++ /dev/null @@ -1,371 +0,0 @@ -From 72fdce0007af1baa0504c2d11be8b19e1a3296f1 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 6 Nov 2017 10:09:16 +0100 -Subject: [PATCH 76/83] NEGCACHE: Add API for setting and checking - locate-account-domain requests -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Extends the negative cache API with several request getsetters: - - sss_ncache_set/check_domain_locate_type - check if this request - type supports locating account domain or set that this request - type does not support the locator. - - - sss_ncache_set/check_locate_gid/uid - check if it is time to call - the locator again or set that the locator should not be called - for IDs again for the duration of the negative cache. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit 07452697a67902dc6876d2f40d364cf1eadf2431) ---- - src/responder/common/negcache.c | 155 +++++++++++++++++++++++++++++++++++++++ - src/responder/common/negcache.h | 64 ++++++++++++++++ - src/tests/cmocka/test_negcache.c | 75 +++++++++++++++++++ - 3 files changed, 294 insertions(+) - -diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c -index b751d89ee9e67eea32ec4ed0935fcd67d3e92f47..bd3c9d36805adc5cca5621c815576ac21cfbec38 100644 ---- a/src/responder/common/negcache.c -+++ b/src/responder/common/negcache.c -@@ -37,6 +37,8 @@ - #define NC_GID_PREFIX NC_ENTRY_PREFIX"GID" - #define NC_SID_PREFIX NC_ENTRY_PREFIX"SID" - #define NC_CERT_PREFIX NC_ENTRY_PREFIX"CERT" -+#define NC_DOMAIN_ACCT_LOCATE_PREFIX NC_ENTRY_PREFIX"DOM_LOCATE" -+#define NC_DOMAIN_ACCT_LOCATE_TYPE_PREFIX NC_ENTRY_PREFIX"DOM_LOCATE_TYPE" - - struct sss_nc_ctx { - struct tdb_context *tdb; -@@ -665,6 +667,159 @@ int sss_ncache_set_cert(struct sss_nc_ctx *ctx, bool permanent, - return ret; - } - -+static char *domain_lookup_type_str(TALLOC_CTX *mem_ctx, -+ struct sss_domain_info *dom, -+ const char *lookup_type) -+{ -+ return talloc_asprintf(mem_ctx, -+ "%s/%s/%s", -+ NC_DOMAIN_ACCT_LOCATE_TYPE_PREFIX, -+ dom->name, -+ lookup_type); -+} -+ -+int sss_ncache_set_domain_locate_type(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ const char *lookup_type) -+{ -+ char *str; -+ int ret; -+ -+ str = domain_lookup_type_str(ctx, dom, lookup_type); -+ if (!str) return ENOMEM; -+ -+ /* Permanent cache is always used here, because whether the lookup -+ * type (getgrgid, getpwuid, ..) supports locating an entry's domain -+ * doesn't change -+ */ -+ ret = sss_ncache_set_str(ctx, str, true, false); -+ talloc_free(str); -+ return ret; -+} -+ -+int sss_ncache_check_domain_locate_type(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ const char *lookup_type) -+{ -+ char *str; -+ int ret; -+ -+ str = domain_lookup_type_str(ctx, dom, lookup_type); -+ if (!str) return ENOMEM; -+ -+ ret = sss_ncache_check_str(ctx, str); -+ talloc_free(str); -+ return ret; -+} -+ -+static char *locate_gid_str(TALLOC_CTX *mem_ctx, -+ struct sss_domain_info *dom, -+ gid_t gid) -+{ -+ return talloc_asprintf(mem_ctx, -+ "%s/%s/%s/%"SPRIgid, -+ NC_DOMAIN_ACCT_LOCATE_PREFIX, -+ NC_GID_PREFIX, -+ dom->name, -+ gid); -+} -+ -+int sss_ncache_set_locate_gid(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ gid_t gid) -+{ -+ char *str; -+ int ret; -+ -+ if (dom == NULL) { -+ return EINVAL; -+ } -+ -+ str = locate_gid_str(ctx, dom, gid); -+ if (str == NULL) { -+ return ENOMEM; -+ } -+ -+ ret = sss_ncache_set_str(ctx, str, false, false); -+ talloc_free(str); -+ return ret; -+} -+ -+int sss_ncache_check_locate_gid(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ gid_t gid) -+{ -+ char *str; -+ int ret; -+ -+ if (dom == NULL) { -+ return EINVAL; -+ } -+ -+ str = locate_gid_str(ctx, dom, gid); -+ if (str == NULL) { -+ return ENOMEM; -+ } -+ -+ ret = sss_ncache_check_str(ctx, str); -+ talloc_free(str); -+ return ret; -+} -+ -+static char *locate_uid_str(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ uid_t uid) -+{ -+ return talloc_asprintf(ctx, -+ "%s/%s/%s/%"SPRIuid, -+ NC_DOMAIN_ACCT_LOCATE_PREFIX, -+ NC_UID_PREFIX, -+ dom->name, -+ uid); -+} -+ -+int sss_ncache_set_locate_uid(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ uid_t uid) -+{ -+ char *str; -+ int ret; -+ -+ if (dom == NULL) { -+ return EINVAL; -+ } -+ -+ str = locate_uid_str(ctx, dom, uid); -+ if (str == NULL) { -+ return ENOMEM; -+ } -+ -+ ret = sss_ncache_set_str(ctx, str, false, false); -+ talloc_free(str); -+ return ret; -+} -+ -+int sss_ncache_check_locate_uid(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ uid_t uid) -+{ -+ char *str; -+ int ret; -+ -+ if (dom == NULL) { -+ return EINVAL; -+ } -+ -+ str = locate_uid_str(ctx, dom, uid); -+ if (str == NULL) { -+ return ENOMEM; -+ } -+ -+ ret = sss_ncache_check_str(ctx, str); -+ talloc_free(str); -+ return ret; -+} -+ - static int delete_permanent(struct tdb_context *tdb, - TDB_DATA key, TDB_DATA data, void *state) - { -diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h -index 782ec140fb7dfe3ec82bed8d25290c0f7b8a36ea..2ed38e5b9a64d3393513ea2110a7c6fcb7675623 100644 ---- a/src/responder/common/negcache.h -+++ b/src/responder/common/negcache.h -@@ -80,6 +80,70 @@ int sss_ncache_set_service_name(struct sss_nc_ctx *ctx, bool permanent, - int sss_ncache_set_service_port(struct sss_nc_ctx *ctx, bool permanent, - struct sss_domain_info *dom, - uint16_t port, const char *proto); -+/* -+ * Mark the lookup_type as not supporting the negative cache. This -+ * would be used by the corresponding checker to avoid needless -+ * subsequent calls to the locator for configurations that do not -+ * support the locator plugin. -+ * -+ * @param ctx The negative cache -+ * @param dom The top-level domain. It is expected that the caller -+ * would use the top-level domain head here, because -+ * this negative cache is "per-request-type" which is the -+ * same for all subdomains of a domain -+ * @param lookup_type Lookup type, e.g. getpwuid, getgrnam. -+ * -+ * @return EOK on success, errno on failure. -+ */ -+int sss_ncache_set_domain_locate_type(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ const char *lookup_type); -+/* -+ * Check if the lookup_type supports the domain locator request. -+ * -+ * @param ctx The negative cache -+ * @param dom The top-level domain. It is expected that the caller -+ * would use the top-level domain head here, because -+ * this negative cache is "per-request-type" which is the -+ * same for all subdomains of a domain -+ * @param lookup_type Lookup type, e.g. getpwuid, getgrnam. -+ * -+ * @return ENOENT if the request supports the locator (or we -+ * haven't checked yet), EEXIST if the request does -+ * not support the domain locator request. -+ */ -+int sss_ncache_check_domain_locate_type(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ const char *key); -+ -+/* -+ * Call these two functions to mark a GID as checked until the negative -+ * cache expires. This function is used to avoid a situation where -+ * GID would be found in a subsequent domain, so any request that -+ * searches for this GID again (even if it was cached) would first -+ * run the locator again. -+ * -+ * While this negative cache entry is valid, it is expected that -+ * the negatively cached entries in the domain's GID negative -+ * cache (if any) are valid -+ * -+ * The sss_ncache_set_locate_gid() is called by the locator request -+ * when it finishes, the sss_ncache_check_locate_gid() is called -+ * by the caller of the locator request to find if the locator -+ * should be called at all. -+ */ -+int sss_ncache_set_locate_gid(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ gid_t gid); -+int sss_ncache_check_locate_gid(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ gid_t gid); -+int sss_ncache_check_locate_uid(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ uid_t uid); -+int sss_ncache_set_locate_uid(struct sss_nc_ctx *ctx, -+ struct sss_domain_info *dom, -+ uid_t uid); - - int sss_ncache_reset_permanent(struct sss_nc_ctx *ctx); - int sss_ncache_reset_users(struct sss_nc_ctx *ctx); -diff --git a/src/tests/cmocka/test_negcache.c b/src/tests/cmocka/test_negcache.c -index ba39f778d5ddc6a4e1708aef66fc2aa1c809f150..a0210928bd60e364c60717c8b37b2405730f34ab 100644 ---- a/src/tests/cmocka/test_negcache.c -+++ b/src/tests/cmocka/test_negcache.c -@@ -883,6 +883,77 @@ static void test_sss_ncache_reset(void **state) - assert_int_equal(ret, ENOENT); - } - -+static void test_sss_ncache_locate_uid_gid(void **state) -+{ -+ uid_t uid; -+ gid_t gid; -+ int ret; -+ struct test_state *ts; -+ struct sss_domain_info *dom; -+ struct sss_domain_info *dom2; -+ -+ ts = talloc_get_type_abort(*state, struct test_state); -+ -+ uid = getuid(); -+ gid = getgid(); -+ -+ dom = talloc(ts, struct sss_domain_info); -+ assert_non_null(dom); -+ dom->name = discard_const_p(char, TEST_DOM_NAME); -+ -+ dom2 = talloc(ts, struct sss_domain_info); -+ assert_non_null(dom2); -+ dom2->name = discard_const_p(char, TEST_DOM_NAME"2"); -+ -+ ret = sss_ncache_check_locate_gid(ts->ctx, dom, gid); -+ assert_int_equal(ret, ENOENT); -+ ret = sss_ncache_check_locate_uid(ts->ctx, dom, uid); -+ assert_int_equal(ret, ENOENT); -+ -+ ret = sss_ncache_set_locate_gid(ts->ctx, dom, gid); -+ assert_int_equal(ret, EOK); -+ ret = sss_ncache_set_locate_uid(ts->ctx, dom, uid); -+ assert_int_equal(ret, EOK); -+ -+ ret = sss_ncache_check_locate_gid(ts->ctx, dom, gid); -+ assert_int_equal(ret, EEXIST); -+ ret = sss_ncache_check_locate_uid(ts->ctx, dom, uid); -+ assert_int_equal(ret, EEXIST); -+ -+ ret = sss_ncache_check_locate_gid(ts->ctx, dom2, gid); -+ assert_int_equal(ret, ENOENT); -+ ret = sss_ncache_check_locate_uid(ts->ctx, dom2, uid); -+ assert_int_equal(ret, ENOENT); -+} -+ -+static void test_sss_ncache_domain_locate_type(void **state) -+{ -+ int ret; -+ struct test_state *ts; -+ struct sss_domain_info *dom; -+ struct sss_domain_info *dom2; -+ -+ ts = talloc_get_type_abort(*state, struct test_state); -+ -+ dom = talloc(ts, struct sss_domain_info); -+ assert_non_null(dom); -+ dom->name = discard_const_p(char, TEST_DOM_NAME); -+ -+ dom2 = talloc(ts, struct sss_domain_info); -+ assert_non_null(dom2); -+ dom2->name = discard_const_p(char, TEST_DOM_NAME"2"); -+ -+ ret = sss_ncache_check_domain_locate_type(ts->ctx, dom, "foo"); -+ assert_int_equal(ret, ENOENT); -+ ret = sss_ncache_set_domain_locate_type(ts->ctx, dom, "foo"); -+ assert_int_equal(ret, EOK); -+ ret = sss_ncache_check_domain_locate_type(ts->ctx, dom, "foo"); -+ assert_int_equal(ret, EEXIST); -+ -+ ret = sss_ncache_check_domain_locate_type(ts->ctx, dom2, "foo"); -+ assert_int_equal(ret, ENOENT); -+} -+ - int main(void) - { - int rv; -@@ -909,6 +980,10 @@ int main(void) - setup, teardown), - cmocka_unit_test_setup_teardown(test_sss_ncache_reset, - setup, teardown), -+ cmocka_unit_test_setup_teardown(test_sss_ncache_locate_uid_gid, -+ setup, teardown), -+ cmocka_unit_test_setup_teardown(test_sss_ncache_domain_locate_type, -+ setup, teardown), - }; - - tests_set_cwd(); --- -2.14.3 - diff --git a/SOURCES/0077-TESTS-Add-tests-for-the-object-by-id-cache_req-inter.patch b/SOURCES/0077-TESTS-Add-tests-for-the-object-by-id-cache_req-inter.patch deleted file mode 100644 index 178e22e..0000000 --- a/SOURCES/0077-TESTS-Add-tests-for-the-object-by-id-cache_req-inter.patch +++ /dev/null @@ -1,439 +0,0 @@ -From 9a4c06ddf5ec8d610f49acf5d3e231d36b37c50b Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Sun, 19 Nov 2017 17:25:02 +0100 -Subject: [PATCH 77/83] TESTS: Add tests for the object-by-id cache_req - interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This interface will be extended in later patches, but had no tests at -all. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit 6cd367da68ff56eb48b8b4167dbdd5e53992d194) ---- - src/tests/cmocka/test_responder_cache_req.c | 385 ++++++++++++++++++++++++++++ - 1 file changed, 385 insertions(+) - -diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c -index 80086232fd437876c2b190fb972c2ee3194d9efd..f075480a019e476407a3081a795c3c289455aca8 100644 ---- a/src/tests/cmocka/test_responder_cache_req.c -+++ b/src/tests/cmocka/test_responder_cache_req.c -@@ -197,6 +197,18 @@ static void cache_req_object_by_sid_test_done(struct tevent_req *req) - ctx->tctx->done = true; - } - -+static void cache_req_object_by_id_test_done(struct tevent_req *req) -+{ -+ struct cache_req_test_ctx *ctx = NULL; -+ -+ ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); -+ -+ ctx->tctx->error = cache_req_object_by_id_recv(ctx, req, &ctx->result); -+ talloc_zfree(req); -+ -+ ctx->tctx->done = true; -+} -+ - static void prepare_user(struct sss_domain_info *domain, - struct test_user *user, - uint64_t timeout, -@@ -417,6 +429,33 @@ static void run_object_by_sid(struct cache_req_test_ctx *test_ctx, - talloc_free(req_mem_ctx); - } - -+static void run_object_by_id(struct cache_req_test_ctx *test_ctx, -+ struct sss_domain_info *domain, -+ id_t id, -+ const char **attrs, -+ int cache_refresh_percent, -+ errno_t exp_ret) -+{ -+ TALLOC_CTX *req_mem_ctx; -+ struct tevent_req *req; -+ errno_t ret; -+ -+ req_mem_ctx = talloc_new(global_talloc_context); -+ check_leaks_push(req_mem_ctx); -+ -+ req = cache_req_object_by_id_send(req_mem_ctx, test_ctx->tctx->ev, -+ test_ctx->rctx, test_ctx->ncache, cache_refresh_percent, -+ (domain == NULL ? NULL : domain->name), id, attrs); -+ assert_non_null(req); -+ tevent_req_set_callback(req, cache_req_object_by_id_test_done, test_ctx); -+ -+ ret = test_ev_loop(test_ctx->tctx); -+ assert_int_equal(ret, exp_ret); -+ assert_true(check_leaks_pop(req_mem_ctx)); -+ -+ talloc_free(req_mem_ctx); -+} -+ - struct tevent_req * - __wrap_sss_dp_get_account_send(TALLOC_CTX *mem_ctx, - struct resp_ctx *rctx, -@@ -2132,6 +2171,334 @@ void test_object_by_sid_group_multiple_domains_notfound(void **state) - assert_true(test_ctx->dp_called); - } - -+void test_object_by_id_user_cache_valid(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Setup user. */ -+ prepare_user(test_ctx->tctx->dom, &users[0], 1000, time(NULL)); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); -+ check_user(test_ctx, &users[0], test_ctx->tctx->dom); -+} -+ -+void test_object_by_id_user_cache_expired(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Setup user. */ -+ prepare_user(test_ctx->tctx->dom, &users[0], -1000, time(NULL)); -+ -+ /* Mock values. */ -+ /* DP should be contacted */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ mock_account_recv_simple(); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], test_ctx->tctx->dom); -+} -+ -+void test_object_by_id_user_cache_midpoint(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Setup user. */ -+ prepare_user(test_ctx->tctx->dom, &users[0], 50, time(NULL) - 26); -+ -+ /* Mock values. */ -+ /* DP should be contacted without callback */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 50, ERR_OK); -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], test_ctx->tctx->dom); -+} -+ -+void test_object_by_id_user_ncache(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ errno_t ret; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Setup user. We explicitly add the UID into BOTH UID and GID -+ * namespaces, because otherwise the cache_req plugin would -+ * search the Data Provider anyway, becase it can't be sure -+ * the object can be of the other type or not -+ */ -+ ret = sss_ncache_set_uid(test_ctx->ncache, -+ false, -+ test_ctx->tctx->dom, -+ users[0].uid); -+ assert_int_equal(ret, EOK); -+ -+ ret = sss_ncache_set_gid(test_ctx->ncache, -+ false, -+ test_ctx->tctx->dom, -+ users[0].uid); -+ assert_int_equal(ret, EOK); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ENOENT); -+ assert_false(test_ctx->dp_called); -+} -+ -+void test_object_by_id_user_missing_found(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Mock values. */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ mock_account_recv_simple(); -+ -+ test_ctx->create_user1 = true; -+ test_ctx->create_user2 = false; -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], test_ctx->tctx->dom); -+} -+ -+void test_object_by_id_user_missing_notfound(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Mock values. */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ mock_account_recv_simple(); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ENOENT); -+ assert_true(test_ctx->dp_called); -+} -+ -+void test_object_by_id_user_multiple_domains_found(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ "responder_cache_req_test_d", true); -+ assert_non_null(domain); -+ -+ prepare_user(domain, &users[0], 1000, time(NULL)); -+ -+ /* Mock values. */ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+} -+ -+void test_object_by_id_user_multiple_domains_notfound(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Mock values. */ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ENOENT); -+ assert_true(test_ctx->dp_called); -+} -+ -+void test_object_by_id_group_cache_valid(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_GRSRC_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Setup user. */ -+ prepare_group(test_ctx->tctx->dom, &groups[0], 1000, time(NULL)); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); -+ check_group(test_ctx, &groups[0], test_ctx->tctx->dom); -+} -+ -+void test_object_by_id_group_cache_expired(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_GRSRC_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Setup user. */ -+ prepare_group(test_ctx->tctx->dom, &groups[0], -1000, time(NULL)); -+ -+ /* Mock values. */ -+ /* DP should be contacted */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ mock_account_recv_simple(); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], test_ctx->tctx->dom); -+} -+ -+void test_object_by_id_group_cache_midpoint(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_GRSRC_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Setup user. */ -+ prepare_group(test_ctx->tctx->dom, &groups[0], 50, time(NULL) - 26); -+ -+ /* Mock values. */ -+ /* DP should be contacted without callback */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 50, ERR_OK); -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], test_ctx->tctx->dom); -+} -+ -+void test_object_by_id_group_ncache(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_GRSRC_ATTRS; -+ errno_t ret; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Setup group. We explicitly add the UID into BOTH UID and GID -+ * namespaces, because otherwise the cache_req plugin would -+ * search the Data Provider anyway, becase it can't be sure -+ * the object can be of the other type or not -+ */ -+ ret = sss_ncache_set_uid(test_ctx->ncache, -+ false, -+ test_ctx->tctx->dom, -+ groups[0].gid); -+ assert_int_equal(ret, EOK); -+ -+ ret = sss_ncache_set_gid(test_ctx->ncache, -+ false, -+ test_ctx->tctx->dom, -+ groups[0].gid); -+ assert_int_equal(ret, EOK); -+ -+ assert_int_equal(ret, EOK); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ENOENT); -+ assert_false(test_ctx->dp_called); -+} -+ -+void test_object_by_id_group_missing_found(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_GRSRC_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Mock values. */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ mock_account_recv_simple(); -+ -+ test_ctx->create_group1 = true; -+ test_ctx->create_group2 = false; -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], test_ctx->tctx->dom); -+} -+ -+void test_object_by_id_group_missing_notfound(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_GRSRC_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Mock values. */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ mock_account_recv_simple(); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ENOENT); -+ assert_true(test_ctx->dp_called); -+} -+ -+void test_object_by_id_group_multiple_domains_found(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *attrs[] = SYSDB_GRSRC_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ "responder_cache_req_test_d", true); -+ assert_non_null(domain); -+ -+ prepare_group(domain, &groups[0], 1000, time(NULL)); -+ -+ /* Mock values. */ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+} -+ -+void test_object_by_id_group_multiple_domains_notfound(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_GRSRC_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Mock values. */ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ENOENT); -+ assert_true(test_ctx->dp_called); -+} -+ - int main(int argc, const char *argv[]) - { - poptContext pc; -@@ -2218,6 +2585,24 @@ int main(int argc, const char *argv[]) - new_single_domain_test(object_by_sid_group_missing_notfound), - new_multi_domain_test(object_by_sid_group_multiple_domains_found), - new_multi_domain_test(object_by_sid_group_multiple_domains_notfound), -+ -+ new_single_domain_test(object_by_id_user_cache_valid), -+ new_single_domain_test(object_by_id_user_cache_expired), -+ new_single_domain_test(object_by_id_user_cache_midpoint), -+ new_single_domain_test(object_by_id_user_ncache), -+ new_single_domain_test(object_by_id_user_missing_found), -+ new_single_domain_test(object_by_id_user_missing_notfound), -+ new_multi_domain_test(object_by_id_user_multiple_domains_found), -+ new_multi_domain_test(object_by_id_user_multiple_domains_notfound), -+ -+ new_single_domain_test(object_by_id_group_cache_valid), -+ new_single_domain_test(object_by_id_group_cache_expired), -+ new_single_domain_test(object_by_id_group_cache_midpoint), -+ new_single_domain_test(object_by_id_group_ncache), -+ new_single_domain_test(object_by_id_group_missing_found), -+ new_single_domain_test(object_by_id_group_missing_notfound), -+ new_multi_domain_test(object_by_id_group_multiple_domains_found), -+ new_multi_domain_test(object_by_id_group_multiple_domains_notfound), - }; - - /* Set debug level to invalid value so we can deside if -d 0 was used. */ --- -2.14.3 - diff --git a/SOURCES/0078-CACHE_REQ-Export-cache_req_search_ncache_add-as-cach.patch b/SOURCES/0078-CACHE_REQ-Export-cache_req_search_ncache_add-as-cach.patch deleted file mode 100644 index cf3ca1f..0000000 --- a/SOURCES/0078-CACHE_REQ-Export-cache_req_search_ncache_add-as-cach.patch +++ /dev/null @@ -1,77 +0,0 @@ -From 26ba3d0b033e52e63d6ec438d7be0df97cb4ce1b Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 30 Oct 2017 20:18:36 +0100 -Subject: [PATCH 78/83] CACHE_REQ: Export cache_req_search_ncache_add() as - cache_req private interface -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Previously, it was enough to add an entry to the negative cache of the -domain being processed in cache_req (cr->domain). But the locator plugin -can return any domain from the processed domain's subdomain list as -well. - -Therefore, this patch extends the internal API for the possibility of -setting the negative cache in another domain as well. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit 800b1a27543fa83bc6cd73d8e2789f3cdbaf584a) ---- - src/responder/common/cache_req/cache_req_private.h | 3 +++ - src/responder/common/cache_req/cache_req_search.c | 10 ++++++++-- - 2 files changed, 11 insertions(+), 2 deletions(-) - -diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h -index 0f630542d38a277d1819063fa4134bd7d2525c90..a156fc65fed80693cdd0473613aeaaa3f5bb2269 100644 ---- a/src/responder/common/cache_req/cache_req_private.h -+++ b/src/responder/common/cache_req/cache_req_private.h -@@ -116,6 +116,9 @@ cache_req_steal_data_and_send(TALLOC_CTX *mem_ctx, - const char *domain, - struct cache_req_data *data); - -+void cache_req_search_ncache_add_to_domain(struct cache_req *cr, -+ struct sss_domain_info *domain); -+ - errno_t - cache_req_add_result(TALLOC_CTX *mem_ctx, - struct cache_req_result *new_result, -diff --git a/src/responder/common/cache_req/cache_req_search.c b/src/responder/common/cache_req/cache_req_search.c -index 56d0345cd8f98de574961d3c9628ae7a4c24f9be..9d5ad8056cda0284b1cc32cd51d7cb0ec12ad667 100644 ---- a/src/responder/common/cache_req/cache_req_search.c -+++ b/src/responder/common/cache_req/cache_req_search.c -@@ -60,7 +60,8 @@ static errno_t cache_req_search_ncache(struct cache_req *cr) - return EOK; - } - --static void cache_req_search_ncache_add(struct cache_req *cr) -+void cache_req_search_ncache_add_to_domain(struct cache_req *cr, -+ struct sss_domain_info *domain) - { - errno_t ret; - -@@ -73,7 +74,7 @@ static void cache_req_search_ncache_add(struct cache_req *cr) - CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, "Adding [%s] to negative cache\n", - cr->debugobj); - -- ret = cr->plugin->ncache_add_fn(cr->ncache, cr->domain, cr->data); -+ ret = cr->plugin->ncache_add_fn(cr->ncache, domain, cr->data); - if (ret != EOK) { - CACHE_REQ_DEBUG(SSSDBG_MINOR_FAILURE, cr, - "Cannot set negative cache for [%s] [%d]: %s\n", -@@ -84,6 +85,11 @@ static void cache_req_search_ncache_add(struct cache_req *cr) - return; - } - -+static void cache_req_search_ncache_add(struct cache_req *cr) -+{ -+ return cache_req_search_ncache_add_to_domain(cr, cr->domain); -+} -+ - static errno_t cache_req_search_ncache_filter(TALLOC_CTX *mem_ctx, - struct cache_req *cr, - struct ldb_result **_result) --- -2.14.3 - diff --git a/SOURCES/0079-CACHE_REQ-Add-plugin-methods-required-for-the-domain.patch b/SOURCES/0079-CACHE_REQ-Add-plugin-methods-required-for-the-domain.patch deleted file mode 100644 index 50c6e3c..0000000 --- a/SOURCES/0079-CACHE_REQ-Add-plugin-methods-required-for-the-domain.patch +++ /dev/null @@ -1,458 +0,0 @@ -From 4127348220f6b32886fcc1e3f890a2e9fdedf7ed Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 30 Oct 2017 20:52:42 +0100 -Subject: [PATCH 79/83] CACHE_REQ: Add plugin methods required for the - domain-locator request -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adds three new cache_req plugin methods: - - cache_req_dp_get_domain_check_fn - check if it is time to run the - locator request again - - cache_req_dp_get_domain_send/recv_fn - run the locator itself - -The reason we added also the checker is that when the locator runs, -we add a temporary entry into the negative cache that would denote that -the locator ran and the ordinary domain negative cache (UID negcache, -GID negcache, ..) were set for the domains and can be still used to -skip domains that we know do not contain the account without calling -the getAccountDomain handler again. - -If we didn't have this checker, requesting an entry from a domain -further down the domain list would always call the locator, only -to always receive the same results. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit 2856dac5818265a6b4e42d768b73c65e333d14ff) ---- - src/responder/common/cache_req/cache_req_plugin.h | 69 ++++++++++++++++++++++ - .../cache_req/plugins/cache_req_enum_groups.c | 5 +- - .../common/cache_req/plugins/cache_req_enum_svc.c | 5 +- - .../cache_req/plugins/cache_req_enum_users.c | 5 +- - .../cache_req/plugins/cache_req_group_by_filter.c | 5 +- - .../cache_req/plugins/cache_req_group_by_id.c | 5 +- - .../cache_req/plugins/cache_req_group_by_name.c | 5 +- - .../cache_req/plugins/cache_req_host_by_name.c | 5 +- - .../plugins/cache_req_initgroups_by_name.c | 5 +- - .../plugins/cache_req_initgroups_by_upn.c | 5 +- - .../cache_req/plugins/cache_req_netgroup_by_name.c | 5 +- - .../cache_req/plugins/cache_req_object_by_id.c | 5 +- - .../cache_req/plugins/cache_req_object_by_name.c | 5 +- - .../cache_req/plugins/cache_req_object_by_sid.c | 5 +- - .../cache_req/plugins/cache_req_svc_by_name.c | 5 +- - .../cache_req/plugins/cache_req_svc_by_port.c | 5 +- - .../cache_req/plugins/cache_req_user_by_cert.c | 5 +- - .../cache_req/plugins/cache_req_user_by_filter.c | 5 +- - .../cache_req/plugins/cache_req_user_by_id.c | 5 +- - .../cache_req/plugins/cache_req_user_by_name.c | 5 +- - .../cache_req/plugins/cache_req_user_by_upn.c | 5 +- - 21 files changed, 149 insertions(+), 20 deletions(-) - -diff --git a/src/responder/common/cache_req/cache_req_plugin.h b/src/responder/common/cache_req/cache_req_plugin.h -index 8117325506b2951c3966fa50506ed0d55273ee81..803d0f4fa5a54900a458d170177e89f82b398bd9 100644 ---- a/src/responder/common/cache_req/cache_req_plugin.h -+++ b/src/responder/common/cache_req/cache_req_plugin.h -@@ -153,6 +153,72 @@ typedef bool - (*cache_req_dp_recv_fn)(struct tevent_req *subreq, - struct cache_req *cr); - -+/** -+ * Check whether the results of the domain locator can still -+ * be considered valid or whether it is time to call the request -+ * again. -+ * -+ * @param resp_ctx The responder context -+ * @param domain The domain to check. This should be the domain-head, -+ * because the locator works across a domain and its -+ * subdomains. -+ * @param data The cache req data that contain primarily the key -+ * to look for. -+ * -+ * @return True if the locator plugin should be ran again, false if -+ * @return False false ifthe lookup should just proceed with the -+ * data that is already in the negative cache. -+ */ -+typedef bool -+(*cache_req_dp_get_domain_check_fn)(struct resp_ctx *rctx, -+ struct sss_domain_info *domain, -+ struct cache_req_data *data); -+/** -+ * Send Data Provider request to locate the domain -+ * of an entry -+ * -+ * @param resp_ctx The responder context -+ * @param domain The domain to check. This should be the domain-head, -+ * because the locator works across a domain and its -+ * subdomains. -+ * @param data The cache req data that contain primarily the key -+ * to look for. -+ * -+ * -+ * @return Tevent request on success. -+ * @return NULL on error. -+ */ -+typedef struct tevent_req * -+(*cache_req_dp_get_domain_send_fn)(TALLOC_CTX *mem_ctx, -+ struct resp_ctx *rctx, -+ struct sss_domain_info *domain, -+ struct cache_req_data *data); -+ -+/** -+ * Process result of Data Provider find-domain request. -+ * -+ * Do not free subreq! It will be freed in the caller. -+ * -+ * @param mem_ctx The memory context that owns the _found_domain -+ * result parameter -+ * @param subreq The request to finish -+ * @param cr The cache_req being processed -+ * @param _found_domain The domain the request account belongs to. This -+ * parameter can be NULL even on success, in that -+ * case the account was not found and no lookups are -+ * needed, all domains can be skipped in this case. -+ * -+ * @return EOK if the request did not encounter any error. In this -+ * case, the _found_domain parameter can be considered authoritative, -+ * regarless of its value -+ * @return errno on error. _found_domain should be NULL in this case. -+ */ -+typedef errno_t -+(*cache_req_dp_get_domain_recv_fn)(TALLOC_CTX *mem_ctx, -+ struct tevent_req *subreq, -+ struct cache_req *cr, -+ char **_found_domain); -+ - struct cache_req_plugin { - /** - * Plugin name. -@@ -223,6 +289,9 @@ struct cache_req_plugin { - cache_req_lookup_fn lookup_fn; - cache_req_dp_send_fn dp_send_fn; - cache_req_dp_recv_fn dp_recv_fn; -+ cache_req_dp_get_domain_check_fn dp_get_domain_check_fn; -+ cache_req_dp_get_domain_send_fn dp_get_domain_send_fn; -+ cache_req_dp_get_domain_recv_fn dp_get_domain_recv_fn; - }; - - extern const struct cache_req_plugin cache_req_user_by_name; -diff --git a/src/responder/common/cache_req/plugins/cache_req_enum_groups.c b/src/responder/common/cache_req/plugins/cache_req_enum_groups.c -index 15350ca8279bc77c73bcc4abe51c97a8a37cb8c8..d302994e8903dea1e25b3da3762aa2ed783daebd 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_enum_groups.c -+++ b/src/responder/common/cache_req/plugins/cache_req_enum_groups.c -@@ -86,7 +86,10 @@ const struct cache_req_plugin cache_req_enum_groups = { - .ncache_filter_fn = cache_req_enum_groups_ncache_filter, - .lookup_fn = cache_req_enum_groups_lookup, - .dp_send_fn = cache_req_enum_groups_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_enum_svc.c b/src/responder/common/cache_req/plugins/cache_req_enum_svc.c -index 72b2f1a7d2d2e02ce1a995098d1f26003444bddb..282dc1cc83b1fda91d4c4937f99598fbdd6ec625 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_enum_svc.c -+++ b/src/responder/common/cache_req/plugins/cache_req_enum_svc.c -@@ -79,7 +79,10 @@ const struct cache_req_plugin cache_req_enum_svc = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_enum_svc_lookup, - .dp_send_fn = cache_req_enum_svc_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_enum_users.c b/src/responder/common/cache_req/plugins/cache_req_enum_users.c -index a3ddcdd45548a2fa7c367f3fb3be103c115dedb4..f83ff30fdbbaacdb3bfb605a65ce70fbd8eb3a89 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_enum_users.c -+++ b/src/responder/common/cache_req/plugins/cache_req_enum_users.c -@@ -86,7 +86,10 @@ const struct cache_req_plugin cache_req_enum_users = { - .ncache_filter_fn = cache_req_enum_users_ncache_filter, - .lookup_fn = cache_req_enum_users_lookup, - .dp_send_fn = cache_req_enum_users_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c b/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c -index aa89953b88313605041cce599999fc5bbc741525..009f0f88523c8c4c02a25f0f5d6a83187e0a17f8 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c -+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_filter.c -@@ -134,7 +134,10 @@ const struct cache_req_plugin cache_req_group_by_filter = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_group_by_filter_lookup, - .dp_send_fn = cache_req_group_by_filter_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c -index 5ca64283a781318bc4e4d6920fff989c3f3919b4..70381266712d2c27c95027b54efab201c5df7690 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c -+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c -@@ -155,7 +155,10 @@ const struct cache_req_plugin cache_req_group_by_id = { - .ncache_filter_fn = cache_req_group_by_id_ncache_filter, - .lookup_fn = cache_req_group_by_id_lookup, - .dp_send_fn = cache_req_group_by_id_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_name.c b/src/responder/common/cache_req/plugins/cache_req_group_by_name.c -index 7706051818590af77da75d3e4c7f671c89170f82..3be0d5ea557bad11529b897be1d7706a8809acb1 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_group_by_name.c -+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_name.c -@@ -197,7 +197,10 @@ const struct cache_req_plugin cache_req_group_by_name = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_group_by_name_lookup, - .dp_send_fn = cache_req_group_by_name_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_host_by_name.c b/src/responder/common/cache_req/plugins/cache_req_host_by_name.c -index 56048c5e4bcadfb341f4b42d978d53484abd65d2..696d9e50d94e824d2664ed5a8fe3150b821d570e 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_host_by_name.c -+++ b/src/responder/common/cache_req/plugins/cache_req_host_by_name.c -@@ -99,7 +99,10 @@ const struct cache_req_plugin cache_req_host_by_name = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_host_by_name_lookup, - .dp_send_fn = cache_req_host_by_name_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c b/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c -index 75ac44e1ad36238f01342eced9188d07daa50720..c5bea9d84921cc567bf794d3ba5a57fadb81695b 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c -+++ b/src/responder/common/cache_req/plugins/cache_req_initgroups_by_name.c -@@ -212,7 +212,10 @@ const struct cache_req_plugin cache_req_initgroups_by_name = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_initgroups_by_name_lookup, - .dp_send_fn = cache_req_initgroups_by_name_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_initgroups_by_upn.c b/src/responder/common/cache_req/plugins/cache_req_initgroups_by_upn.c -index dfb21ac1a0090a3ef9029b38f5b1e8bdda3440c6..9bd00f357c630bae4a52e356577000bd8de94013 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_initgroups_by_upn.c -+++ b/src/responder/common/cache_req/plugins/cache_req_initgroups_by_upn.c -@@ -123,5 +123,8 @@ const struct cache_req_plugin cache_req_initgroups_by_upn = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_initgroups_by_upn_lookup, - .dp_send_fn = cache_req_initgroups_by_upn_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; -diff --git a/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c b/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c -index ef0775d0b8eac4d679450f436d8427cff9c04582..d370d342ec5b2c0e0e9f1f4ea90b34b59bff60b6 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c -+++ b/src/responder/common/cache_req/plugins/cache_req_netgroup_by_name.c -@@ -131,7 +131,10 @@ const struct cache_req_plugin cache_req_netgroup_by_name = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_netgroup_by_name_lookup, - .dp_send_fn = cache_req_netgroup_by_name_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c -index 339bd4f5fef827acc1aa3c123d041e426d9e4782..2af95313cb2df0f46a61519ac962074033f34a12 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c -+++ b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c -@@ -129,7 +129,10 @@ const struct cache_req_plugin cache_req_object_by_id = { - .ncache_filter_fn = cache_req_object_by_id_ncache_filter, - .lookup_fn = cache_req_object_by_id_lookup, - .dp_send_fn = cache_req_object_by_id_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_name.c b/src/responder/common/cache_req/plugins/cache_req_object_by_name.c -index 854d0b83c420ebebcb5e0e079c707081fa313632..a740fbb8d05efb4601e8e40d2a07896ecb251d4e 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_object_by_name.c -+++ b/src/responder/common/cache_req/plugins/cache_req_object_by_name.c -@@ -207,7 +207,10 @@ const struct cache_req_plugin cache_req_object_by_name = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_object_by_name_lookup, - .dp_send_fn = cache_req_object_by_name_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_sid.c b/src/responder/common/cache_req/plugins/cache_req_object_by_sid.c -index 039a79df7bb1ab213ce4334835e9fc18e6d0faac..1af638ff9d94ffa3bf6e418433d5c4e98acfb2b8 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_object_by_sid.c -+++ b/src/responder/common/cache_req/plugins/cache_req_object_by_sid.c -@@ -123,7 +123,10 @@ const struct cache_req_plugin cache_req_object_by_sid = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_object_by_sid_lookup, - .dp_send_fn = cache_req_object_by_sid_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c b/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c -index 4c32d9977cc06e43eed3a90e7dcf107e91efefb5..5b17051031e35c5767d27b19c922325cee4b6eac 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c -+++ b/src/responder/common/cache_req/plugins/cache_req_svc_by_name.c -@@ -155,7 +155,10 @@ const struct cache_req_plugin cache_req_svc_by_name = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_svc_by_name_lookup, - .dp_send_fn = cache_req_svc_by_name_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c b/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c -index 1e998f642c766d15d3f6fe777aa5c789629508e2..4c005df3972386fef3c5a858a2b691cb2a63fd57 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c -+++ b/src/responder/common/cache_req/plugins/cache_req_svc_by_port.c -@@ -128,7 +128,10 @@ const struct cache_req_plugin cache_req_svc_by_port = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_svc_by_port_lookup, - .dp_send_fn = cache_req_svc_by_port_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_cert.c b/src/responder/common/cache_req/plugins/cache_req_user_by_cert.c -index 7a0c7d8ce1644f1c41b64c6903e4e20eb3c2c081..a2dc1fad28ca09eeba77c563f17518671095ab42 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_user_by_cert.c -+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_cert.c -@@ -97,7 +97,10 @@ const struct cache_req_plugin cache_req_user_by_cert = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_user_by_cert_lookup, - .dp_send_fn = cache_req_user_by_cert_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c b/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c -index dd3f42e855389ecc73690e4d18c4977253b108a6..42b6e816372c51623f29e8a7e28859a9dfca640f 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c -+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_filter.c -@@ -134,7 +134,10 @@ const struct cache_req_plugin cache_req_user_by_filter = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_user_by_filter_lookup, - .dp_send_fn = cache_req_user_by_filter_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c -index 913f9be5bcc2dfd074b52cb3b15fb6948826e831..254330e92cc801b84bfb5e308d6d90ac54507d77 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c -+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c -@@ -155,7 +155,10 @@ const struct cache_req_plugin cache_req_user_by_id = { - .ncache_filter_fn = cache_req_user_by_id_ncache_filter, - .lookup_fn = cache_req_user_by_id_lookup, - .dp_send_fn = cache_req_user_by_id_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_name.c b/src/responder/common/cache_req/plugins/cache_req_user_by_name.c -index 2e49de938d0af50089d0cf49860441c2b6ea679c..d24a2221b2a69d24d360c46c41073e19dc79036b 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_user_by_name.c -+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_name.c -@@ -202,7 +202,10 @@ const struct cache_req_plugin cache_req_user_by_name = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_user_by_name_lookup, - .dp_send_fn = cache_req_user_by_name_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c b/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c -index b8bcd241ed79c510aca214ad3788215ae2997d20..e08ab70ae081a5d532d7ab436687978416e7c493 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c -+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_upn.c -@@ -128,5 +128,8 @@ const struct cache_req_plugin cache_req_user_by_upn = { - .ncache_filter_fn = NULL, - .lookup_fn = cache_req_user_by_upn_lookup, - .dp_send_fn = cache_req_user_by_upn_dp_send, -- .dp_recv_fn = cache_req_common_dp_recv -+ .dp_recv_fn = cache_req_common_dp_recv, -+ .dp_get_domain_check_fn = NULL, -+ .dp_get_domain_send_fn = NULL, -+ .dp_get_domain_recv_fn = NULL, - }; --- -2.14.3 - diff --git a/SOURCES/0080-CACHE_REQ-Add-a-private-request-cache_req_locate_dom.patch b/SOURCES/0080-CACHE_REQ-Add-a-private-request-cache_req_locate_dom.patch deleted file mode 100644 index f00f399..0000000 --- a/SOURCES/0080-CACHE_REQ-Add-a-private-request-cache_req_locate_dom.patch +++ /dev/null @@ -1,177 +0,0 @@ -From d30dd0f52d452562e47f9a30b1630eff2f817792 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 30 Oct 2017 20:21:05 +0100 -Subject: [PATCH 80/83] CACHE_REQ: Add a private request - cache_req_locate_domain() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adds a new request cache_req_locate_domain_send/recv. This request, if the -plugin that is being processed supports the locator, will call the plugin's -dp_get_domain_send_fn(). On any error, the request returns just the error -code. On success, the request returns the domain the object was found at. - -If the getAccountDomain() method returns that the back end does not support -the locator method, all further getAccountDomain() calls are disabled for -that domain. - -Related: -https://pagure.io/SSSD/sssd/issue/3468 - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit 0a0b34f5fbe8f4a8c533a7d65f0f2961ee264054) ---- - src/responder/common/cache_req/cache_req_private.h | 7 ++ - src/responder/common/cache_req/cache_req_search.c | 93 ++++++++++++++++++++++ - src/util/util_errors.c | 1 + - src/util/util_errors.h | 1 + - 4 files changed, 102 insertions(+) - -diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h -index a156fc65fed80693cdd0473613aeaaa3f5bb2269..9586e3788045ff44eb2a4b626dc7fcaf11ec8028 100644 ---- a/src/responder/common/cache_req/cache_req_private.h -+++ b/src/responder/common/cache_req/cache_req_private.h -@@ -106,6 +106,13 @@ errno_t cache_req_search_recv(TALLOC_CTX *mem_ctx, - struct ldb_result **_result, - bool *_dp_success); - -+struct tevent_req *cache_req_locate_domain_send(TALLOC_CTX *mem_ctx, -+ struct tevent_context *ev, -+ struct cache_req *cr); -+errno_t cache_req_locate_domain_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ char **_found_domain); -+ - struct tevent_req * - cache_req_steal_data_and_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, -diff --git a/src/responder/common/cache_req/cache_req_search.c b/src/responder/common/cache_req/cache_req_search.c -index 9d5ad8056cda0284b1cc32cd51d7cb0ec12ad667..3365962d473b0982945de2541e44ba86b43a0db5 100644 ---- a/src/responder/common/cache_req/cache_req_search.c -+++ b/src/responder/common/cache_req/cache_req_search.c -@@ -485,3 +485,96 @@ errno_t cache_req_search_recv(TALLOC_CTX *mem_ctx, - - return EOK; - } -+ -+struct cache_req_locate_domain_state { -+ struct cache_req *cr; -+ -+ char *found_domain; -+}; -+ -+static void cache_req_locate_domain_done(struct tevent_req *subreq); -+ -+struct tevent_req *cache_req_locate_domain_send(TALLOC_CTX *mem_ctx, -+ struct tevent_context *ev, -+ struct cache_req *cr) -+{ -+ struct cache_req_locate_domain_state *state; -+ struct tevent_req *req; -+ struct tevent_req *subreq; -+ errno_t ret; -+ bool should_run; -+ -+ req = tevent_req_create(mem_ctx, &state, struct cache_req_locate_domain_state); -+ if (req == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); -+ return NULL; -+ } -+ state->cr = cr; -+ -+ should_run = cr->plugin->dp_get_domain_check_fn(cr->rctx, -+ get_domains_head(cr->domain), -+ cr->data); -+ if (should_run == false) { -+ /* The request was tried too recently, don't issue a new one -+ * as its results are still valid -+ */ -+ ret = ERR_GET_ACCT_DOM_CACHED; -+ goto immediate; -+ } -+ -+ subreq = cr->plugin->dp_get_domain_send_fn(state, -+ cr->rctx, -+ get_domains_head(cr->domain), -+ cr->data); -+ if (subreq == NULL) { -+ ret = ENOMEM; -+ goto immediate; -+ } -+ tevent_req_set_callback(subreq, cache_req_locate_domain_done, req); -+ return req; -+ -+immediate: -+ if (ret == EOK) { -+ tevent_req_done(req); -+ } else { -+ tevent_req_error(req, ret); -+ } -+ tevent_req_post(req, ev); -+ return req; -+} -+ -+static void cache_req_locate_domain_done(struct tevent_req *subreq) -+{ -+ struct tevent_req *req; -+ struct cache_req_locate_domain_state *state; -+ errno_t ret; -+ -+ req = tevent_req_callback_data(subreq, struct tevent_req); -+ state = tevent_req_data(req, struct cache_req_locate_domain_state); -+ -+ ret = state->cr->plugin->dp_get_domain_recv_fn(state, -+ subreq, -+ state->cr, -+ &state->found_domain); -+ talloc_zfree(subreq); -+ if (ret != EOK) { -+ tevent_req_error(req, ret); -+ return; -+ } -+ -+ tevent_req_done(req); -+} -+ -+errno_t cache_req_locate_domain_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ char **_found_domain) -+{ -+ struct cache_req_locate_domain_state *state = NULL; -+ -+ state = tevent_req_data(req, struct cache_req_locate_domain_state); -+ -+ TEVENT_REQ_RETURN_ON_ERROR(req); -+ -+ *_found_domain = talloc_steal(mem_ctx, state->found_domain); -+ return EOK; -+} -diff --git a/src/util/util_errors.c b/src/util/util_errors.c -index 9a9ba3f3063cab4afb538c3a58527a2d2ed3fffd..06c620b40aaa00d6ce58ace3a28449ffbdf8da88 100644 ---- a/src/util/util_errors.c -+++ b/src/util/util_errors.c -@@ -116,6 +116,7 @@ struct err_string error_to_str[] = { - { "Unable to verify peer" }, /* ERR_UNABLE_TO_VERIFY_PEER */ - { "Unable to resolve host" }, /* ERR_UNABLE_TO_RESOLVE_HOST */ - { "GetAccountDomain() not supported" }, /* ERR_GET_ACCT_DOM_NOT_SUPPORTED */ -+ { "The last GetAccountDomain() result is still valid" }, /* ERR_GET_ACCT_DOM_CACHED */ - { "ERR_LAST" } /* ERR_LAST */ - }; - -diff --git a/src/util/util_errors.h b/src/util/util_errors.h -index 5ee9862c3f2f60c078693b1b85a40f15436e818c..bebd6e198fc0077891a602f80182a993ce3f789b 100644 ---- a/src/util/util_errors.h -+++ b/src/util/util_errors.h -@@ -138,6 +138,7 @@ enum sssd_errors { - ERR_UNABLE_TO_VERIFY_PEER, - ERR_UNABLE_TO_RESOLVE_HOST, - ERR_GET_ACCT_DOM_NOT_SUPPORTED, -+ ERR_GET_ACCT_DOM_CACHED, - ERR_LAST /* ALWAYS LAST */ - }; - --- -2.14.3 - diff --git a/SOURCES/0081-CACHE_REQ-Implement-the-plugin-methods-that-utilize-.patch b/SOURCES/0081-CACHE_REQ-Implement-the-plugin-methods-that-utilize-.patch deleted file mode 100644 index 6c0f694..0000000 --- a/SOURCES/0081-CACHE_REQ-Implement-the-plugin-methods-that-utilize-.patch +++ /dev/null @@ -1,413 +0,0 @@ -From 7482c6affd4dfa77a8d465ff0283617792847725 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 6 Nov 2017 15:52:11 +0100 -Subject: [PATCH 81/83] CACHE_REQ: Implement the plugin methods that utilize - the domain locator API -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Mainly, this patch adds handlers for the dp_get_domain_check_fn(), -dp_get_domain_send_fn() and dp_get_domain_recv_fn() functions to -requests that resolve objects by ID. - -This patch also adds domain-local negcache setter for by-id methods -Previously, the by-ID methods only used global negative cache setters -because the ID space is global and we always iterated over all domains. - -However, with addition of the domain locator plugin, we want also -to skip only certain domains and the easiest way to to so is to add -the IDs for domains that do not contain these IDs to the negative cache -with the get-account-domain request. - -Therefore this patch also adds per-domain negative cache setters for -the three plugins that search by ID. - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit a6eb9c4c3ff68d134bc745e8374f182737e9696b) ---- - src/responder/common/cache_req/cache_req_private.h | 5 ++ - .../common/cache_req/plugins/cache_req_common.c | 17 +++++ - .../cache_req/plugins/cache_req_group_by_id.c | 62 +++++++++++++++-- - .../cache_req/plugins/cache_req_object_by_id.c | 77 ++++++++++++++++++++-- - .../cache_req/plugins/cache_req_user_by_id.c | 63 ++++++++++++++++-- - src/tests/cmocka/common_mock_resp_dp.c | 23 +++++++ - 6 files changed, 235 insertions(+), 12 deletions(-) - -diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h -index 9586e3788045ff44eb2a4b626dc7fcaf11ec8028..95f24c0e5b9ab1150591d308c7288c57fe478c5d 100644 ---- a/src/responder/common/cache_req/cache_req_private.h -+++ b/src/responder/common/cache_req/cache_req_private.h -@@ -187,4 +187,9 @@ bool - cache_req_common_dp_recv(struct tevent_req *subreq, - struct cache_req *cr); - -+errno_t -+cache_reg_common_get_acct_domain_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *subreq, -+ struct cache_req *cr, -+ char **_domain); - #endif /* _CACHE_REQ_PRIVATE_H_ */ -diff --git a/src/responder/common/cache_req/plugins/cache_req_common.c b/src/responder/common/cache_req/plugins/cache_req_common.c -index 1f86258bc14c7a382712959f24a4ec4c153572d4..408c91949ceb3ecaf743f270f58f4e3fcfc3ccb1 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_common.c -+++ b/src/responder/common/cache_req/plugins/cache_req_common.c -@@ -147,3 +147,20 @@ done: - talloc_free(err_msg); - return bret; - } -+ -+errno_t -+cache_reg_common_get_acct_domain_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *subreq, -+ struct cache_req *cr, -+ char **_domain) -+{ -+ errno_t ret; -+ -+ ret = sss_dp_get_account_domain_recv(mem_ctx, subreq, _domain); -+ if (ret != EOK) { -+ CACHE_REQ_DEBUG(SSSDBG_MINOR_FAILURE, cr, -+ "Could not get account domain [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ } -+ return ret; -+} -diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c -index 70381266712d2c27c95027b54efab201c5df7690..ce84b1b4458b447ff6b4b036c6e8fe8f4d7758c8 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c -+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c -@@ -39,6 +39,15 @@ cache_req_group_by_id_ncache_check(struct sss_nc_ctx *ncache, - struct sss_domain_info *domain, - struct cache_req_data *data) - { -+ errno_t ret; -+ -+ if (domain != NULL) { -+ ret = sss_ncache_check_gid(ncache, domain, data->id); -+ if (ret == EEXIST) { -+ return ret; -+ } -+ } -+ - return sss_ncache_check_gid(ncache, NULL, data->id); - } - -@@ -57,6 +66,14 @@ cache_req_group_by_id_global_ncache_add(struct sss_nc_ctx *ncache, - return sss_ncache_set_gid(ncache, false, NULL, data->id); - } - -+static errno_t -+cache_req_group_by_id_ncache_add(struct sss_nc_ctx *ncache, -+ struct sss_domain_info *domain, -+ struct cache_req_data *data) -+{ -+ return sss_ncache_set_gid(ncache, false, domain, data->id); -+} -+ - static errno_t - cache_req_group_by_id_lookup(TALLOC_CTX *mem_ctx, - struct cache_req *cr, -@@ -132,6 +149,43 @@ cache_req_group_by_id_dp_send(TALLOC_CTX *mem_ctx, - SSS_DP_GROUP, string, id, flag); - } - -+static bool -+cache_req_group_by_id_get_domain_check(struct resp_ctx *rctx, -+ struct sss_domain_info *domain, -+ struct cache_req_data *data) -+{ -+ int nret; -+ -+ nret = sss_ncache_check_locate_gid(rctx->ncache, domain, data->id); -+ if (nret == EEXIST) { -+ return false; -+ } -+ -+ return true; -+} -+ -+static struct tevent_req * -+cache_req_group_by_id_get_domain_send(TALLOC_CTX *mem_ctx, -+ struct resp_ctx *rctx, -+ struct sss_domain_info *domain, -+ struct cache_req_data *data) -+{ -+ int nret; -+ -+ nret = sss_ncache_set_locate_gid(rctx->ncache, domain, data->id); -+ if (nret != EOK) { -+ DEBUG(SSSDBG_MINOR_FAILURE, -+ "Cannot set negative cache, this might result in performance degradation\n"); -+ /* Not fatal */ -+ } -+ -+ return sss_dp_get_account_domain_send(mem_ctx, -+ rctx, -+ domain, -+ SSS_DP_GROUP, -+ data->id); -+} -+ - const struct cache_req_plugin cache_req_group_by_id = { - .name = "Group by ID", - .attr_expiration = SYSDB_CACHE_EXPIRE, -@@ -151,14 +205,14 @@ const struct cache_req_plugin cache_req_group_by_id = { - .create_debug_name_fn = cache_req_group_by_id_create_debug_name, - .global_ncache_add_fn = cache_req_group_by_id_global_ncache_add, - .ncache_check_fn = cache_req_group_by_id_ncache_check, -- .ncache_add_fn = NULL, -+ .ncache_add_fn = cache_req_group_by_id_ncache_add, - .ncache_filter_fn = cache_req_group_by_id_ncache_filter, - .lookup_fn = cache_req_group_by_id_lookup, - .dp_send_fn = cache_req_group_by_id_dp_send, - .dp_recv_fn = cache_req_common_dp_recv, -- .dp_get_domain_check_fn = NULL, -- .dp_get_domain_send_fn = NULL, -- .dp_get_domain_recv_fn = NULL, -+ .dp_get_domain_check_fn = cache_req_group_by_id_get_domain_check, -+ .dp_get_domain_send_fn = cache_req_group_by_id_get_domain_send, -+ .dp_get_domain_recv_fn = cache_reg_common_get_acct_domain_recv, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c -index 2af95313cb2df0f46a61519ac962074033f34a12..1327b480c1b1b68f9826fa229c9b001f2d92b79b 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c -+++ b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c -@@ -83,6 +83,26 @@ cache_req_object_by_id_global_ncache_add(struct sss_nc_ctx *ncache, - return EOK; - } - -+static errno_t -+cache_req_object_by_id_ncache_add(struct sss_nc_ctx *ncache, -+ struct sss_domain_info *domain, -+ struct cache_req_data *data) -+{ -+ errno_t ret; -+ -+ ret = sss_ncache_set_uid(ncache, false, domain, data->id); -+ if (ret != EOK) { -+ return ret; -+ } -+ -+ ret = sss_ncache_set_gid(ncache, false, domain, data->id); -+ if (ret != EOK) { -+ return ret; -+ } -+ -+ return EOK; -+} -+ - static errno_t - cache_req_object_by_id_lookup(TALLOC_CTX *mem_ctx, - struct cache_req *cr, -@@ -106,6 +126,55 @@ cache_req_object_by_id_dp_send(TALLOC_CTX *mem_ctx, - cr->data->id, NULL); - } - -+static bool -+cache_req_object_by_id_get_domain_check(struct resp_ctx *rctx, -+ struct sss_domain_info *domain, -+ struct cache_req_data *data) -+{ -+ int nret; -+ -+ nret = sss_ncache_check_locate_uid(rctx->ncache, domain, data->id); -+ if (nret == EEXIST) { -+ nret = sss_ncache_check_locate_gid(rctx->ncache, domain, data->id); -+ if (nret == EEXIST) { -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+static struct tevent_req * -+cache_req_object_by_id_get_domain_send(TALLOC_CTX *mem_ctx, -+ struct resp_ctx *rctx, -+ struct sss_domain_info *domain, -+ struct cache_req_data *data) -+{ -+ int nret; -+ -+ nret = sss_ncache_set_locate_uid(rctx->ncache, domain, data->id); -+ if (nret != EOK) { -+ DEBUG(SSSDBG_MINOR_FAILURE, -+ "Cannot set negative cache, this might result in " -+ "performance degradation\n"); -+ /* Not fatal */ -+ } -+ -+ nret = sss_ncache_set_locate_gid(rctx->ncache, domain, data->id); -+ if (nret != EOK) { -+ DEBUG(SSSDBG_MINOR_FAILURE, -+ "Cannot set negative cache, this might result in " -+ "performance degradation\n"); -+ /* Not fatal */ -+ } -+ -+ return sss_dp_get_account_domain_send(mem_ctx, -+ rctx, -+ domain, -+ SSS_DP_USER_AND_GROUP, -+ data->id); -+} -+ - const struct cache_req_plugin cache_req_object_by_id = { - .name = "Object by ID", - .attr_expiration = SYSDB_CACHE_EXPIRE, -@@ -125,14 +194,14 @@ const struct cache_req_plugin cache_req_object_by_id = { - .create_debug_name_fn = cache_req_object_by_id_create_debug_name, - .global_ncache_add_fn = cache_req_object_by_id_global_ncache_add, - .ncache_check_fn = cache_req_object_by_id_ncache_check, -- .ncache_add_fn = NULL, -+ .ncache_add_fn = cache_req_object_by_id_ncache_add, - .ncache_filter_fn = cache_req_object_by_id_ncache_filter, - .lookup_fn = cache_req_object_by_id_lookup, - .dp_send_fn = cache_req_object_by_id_dp_send, - .dp_recv_fn = cache_req_common_dp_recv, -- .dp_get_domain_check_fn = NULL, -- .dp_get_domain_send_fn = NULL, -- .dp_get_domain_recv_fn = NULL, -+ .dp_get_domain_check_fn = cache_req_object_by_id_get_domain_check, -+ .dp_get_domain_send_fn = cache_req_object_by_id_get_domain_send, -+ .dp_get_domain_recv_fn = cache_reg_common_get_acct_domain_recv, - }; - - struct tevent_req * -diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c -index 254330e92cc801b84bfb5e308d6d90ac54507d77..656fa41af5f39f68c64e241aa97c4eaf3ec57395 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c -+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c -@@ -39,6 +39,15 @@ cache_req_user_by_id_ncache_check(struct sss_nc_ctx *ncache, - struct sss_domain_info *domain, - struct cache_req_data *data) - { -+ errno_t ret; -+ -+ if (domain != NULL) { -+ ret = sss_ncache_check_uid(ncache, domain, data->id); -+ if (ret == EEXIST) { -+ return ret; -+ } -+ } -+ - return sss_ncache_check_uid(ncache, NULL, data->id); - } - -@@ -57,6 +66,14 @@ cache_req_user_by_id_global_ncache_add(struct sss_nc_ctx *ncache, - return sss_ncache_set_uid(ncache, false, NULL, data->id); - } - -+static errno_t -+cache_req_user_by_id_ncache_add(struct sss_nc_ctx *ncache, -+ struct sss_domain_info *domain, -+ struct cache_req_data *data) -+{ -+ return sss_ncache_set_uid(ncache, false, domain, data->id); -+} -+ - static errno_t - cache_req_user_by_id_lookup(TALLOC_CTX *mem_ctx, - struct cache_req *cr, -@@ -132,6 +149,44 @@ cache_req_user_by_id_dp_send(TALLOC_CTX *mem_ctx, - SSS_DP_USER, string, id, flag); - } - -+static bool -+cache_req_user_by_id_get_domain_check(struct resp_ctx *rctx, -+ struct sss_domain_info *domain, -+ struct cache_req_data *data) -+{ -+ int nret; -+ -+ nret = sss_ncache_check_locate_uid(rctx->ncache, domain, data->id); -+ if (nret == EEXIST) { -+ return false; -+ } -+ -+ return true; -+} -+ -+static struct tevent_req * -+cache_req_user_by_id_get_domain_send(TALLOC_CTX *mem_ctx, -+ struct resp_ctx *rctx, -+ struct sss_domain_info *domain, -+ struct cache_req_data *data) -+{ -+ int nret; -+ -+ nret = sss_ncache_set_locate_uid(rctx->ncache, domain, data->id); -+ if (nret != EOK) { -+ DEBUG(SSSDBG_MINOR_FAILURE, -+ "Cannot set negative cache, this might result in " -+ "performance degradation\n"); -+ /* Not fatal */ -+ } -+ -+ return sss_dp_get_account_domain_send(mem_ctx, -+ rctx, -+ domain, -+ SSS_DP_USER, -+ data->id); -+} -+ - const struct cache_req_plugin cache_req_user_by_id = { - .name = "User by ID", - .attr_expiration = SYSDB_CACHE_EXPIRE, -@@ -151,14 +206,14 @@ const struct cache_req_plugin cache_req_user_by_id = { - .create_debug_name_fn = cache_req_user_by_id_create_debug_name, - .global_ncache_add_fn = cache_req_user_by_id_global_ncache_add, - .ncache_check_fn = cache_req_user_by_id_ncache_check, -- .ncache_add_fn = NULL, -+ .ncache_add_fn = cache_req_user_by_id_ncache_add, - .ncache_filter_fn = cache_req_user_by_id_ncache_filter, - .lookup_fn = cache_req_user_by_id_lookup, - .dp_send_fn = cache_req_user_by_id_dp_send, - .dp_recv_fn = cache_req_common_dp_recv, -- .dp_get_domain_check_fn = NULL, -- .dp_get_domain_send_fn = NULL, -- .dp_get_domain_recv_fn = NULL, -+ .dp_get_domain_check_fn = cache_req_user_by_id_get_domain_check, -+ .dp_get_domain_send_fn = cache_req_user_by_id_get_domain_send, -+ .dp_get_domain_recv_fn = cache_reg_common_get_acct_domain_recv, - }; - - struct tevent_req * -diff --git a/src/tests/cmocka/common_mock_resp_dp.c b/src/tests/cmocka/common_mock_resp_dp.c -index 4b38a38e6f53499132f9fe14a0ec0af157cf85ca..f21ca53ad0d6b7f4ed28d0c1d9e491af31355d43 100644 ---- a/src/tests/cmocka/common_mock_resp_dp.c -+++ b/src/tests/cmocka/common_mock_resp_dp.c -@@ -179,3 +179,26 @@ errno_t sss_dp_get_domains_recv(struct tevent_req *req) - { - return test_request_recv(req); - } -+ -+struct tevent_req * -+sss_dp_get_account_domain_send(TALLOC_CTX *mem_ctx, -+ struct resp_ctx *rctx, -+ struct sss_domain_info *domain, -+ enum sss_dp_acct_type type, -+ uint32_t opt_id) -+{ -+ return test_req_succeed_send(mem_ctx, rctx->ev); -+} -+ -+errno_t sss_dp_get_account_domain_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ char **_domain) -+{ -+ errno_t ret; -+ -+ ret = sss_mock_type(errno_t); -+ if (ret == EOK) { -+ *_domain = sss_mock_ptr_type(char *); -+ } -+ return ret; -+} --- -2.14.3 - diff --git a/SOURCES/0082-CACHE_REQ-Use-the-domain-locator-request-to-only-sea.patch b/SOURCES/0082-CACHE_REQ-Use-the-domain-locator-request-to-only-sea.patch deleted file mode 100644 index 713322a..0000000 --- a/SOURCES/0082-CACHE_REQ-Use-the-domain-locator-request-to-only-sea.patch +++ /dev/null @@ -1,2048 +0,0 @@ -From 1b4b03720c409b183debe0e0532b1009301e9cb2 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Sun, 19 Nov 2017 22:47:00 +0100 -Subject: [PATCH 82/83] CACHE_REQ: Use the domain-locator request to only - search domains where the entry was found -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Uses the internal cache_req interface around the getAccountDomain to only -search the domain returned by the cache_req_locate_domain_recv() request. - -If that request returns that no domain matched, all domains (belonging -to the currently processed main domain) are skipped by setting the -per-type negative cache. - -if a domain is reported as containing an object, all domains except that -one are marked with the negative cache entries. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3468 - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit f2a5e29f063f9d623c1336d76f4b2bc500c1a5e2) ---- - src/responder/common/cache_req/cache_req.c | 402 +++++- - src/responder/common/cache_req/cache_req_domain.h | 1 + - src/tests/cmocka/test_responder_cache_req.c | 1373 +++++++++++++++++++++ - 3 files changed, 1758 insertions(+), 18 deletions(-) - -diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c -index 110df561101be538e3f0496addfa2e14e42ea918..ad9bc040dd999a205713141e6a1512e47b69c45e 100644 ---- a/src/responder/common/cache_req/cache_req.c -+++ b/src/responder/common/cache_req/cache_req.c -@@ -363,6 +363,53 @@ static void cache_req_global_ncache_add(struct cache_req *cr) - return; - } - -+static bool cache_req_check_acct_domain_lookup_type(struct cache_req *cr, -+ struct sss_domain_info *dom) -+{ -+ struct sss_domain_info *head; -+ int nret; -+ -+ head = get_domains_head(dom); -+ if (head == NULL) { -+ return false; -+ } -+ -+ nret = sss_ncache_check_domain_locate_type(cr->rctx->ncache, -+ head, -+ cr->plugin->name); -+ if (nret == ENOENT) { -+ return true; -+ } -+ return false; -+} -+ -+static errno_t cache_req_set_acct_domain_lookup_type(struct cache_req *cr, -+ struct sss_domain_info *dom) -+{ -+ struct sss_domain_info *head; -+ -+ head = get_domains_head(dom); -+ if (head == NULL) { -+ return EINVAL; -+ } -+ -+ return sss_ncache_set_domain_locate_type(cr->rctx->ncache, -+ head, -+ cr->plugin->name); -+} -+ -+static void cache_req_domain_set_locate_flag(struct cache_req_domain *domains, -+ struct cache_req *cr) -+{ -+ struct cache_req_domain *crd_iter; -+ -+ DLIST_FOR_EACH(crd_iter, domains) { -+ if (cache_req_check_acct_domain_lookup_type(cr, crd_iter->domain)) { -+ crd_iter->locate_domain = true; -+ } -+ } -+} -+ - static bool - cache_req_assume_upn(struct cache_req *cr) - { -@@ -391,6 +438,227 @@ cache_req_assume_upn(struct cache_req *cr) - return true; - } - -+struct cache_req_locate_dom_state { -+ /* input data */ -+ struct tevent_context *ev; -+ struct cache_req *cr; -+ struct cache_req_domain *req_domains; -+ -+ /* Return values in case the first cache lookup succeeds */ -+ struct ldb_result *result; -+ bool dp_success; -+}; -+ -+static void cache_req_locate_dom_cache_done(struct tevent_req *subreq); -+static void cache_req_locate_dom_done(struct tevent_req *subreq); -+static void cache_req_locate_dom_mark_neg_all( -+ struct cache_req_locate_dom_state *state); -+static void cache_req_locate_dom_mark_neg_domains( -+ struct cache_req_locate_dom_state *state, -+ const char *found_domain_name); -+ -+static struct tevent_req *cache_req_locate_dom_send(TALLOC_CTX *mem_ctx, -+ struct tevent_context *ev, -+ struct cache_req *cr, -+ struct cache_req_domain *req_domains) -+{ -+ struct tevent_req *req; -+ struct tevent_req *subreq; -+ struct cache_req_locate_dom_state *state = NULL; -+ errno_t ret; -+ -+ req = tevent_req_create(mem_ctx, &state, -+ struct cache_req_locate_dom_state); -+ if (req == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n"); -+ return NULL; -+ } -+ state->ev = ev; -+ state->cr = cr; -+ state->req_domains = req_domains; -+ -+ /* It is wasteful to run the domain locator request if the results are -+ * present in the cache, because the domain locator always contacts -+ * the DP. Therefore, first run a cache-only search and only if the -+ * requested data is not available, run the locator -+ * -+ * FIXME - this could be optimized further if we are running the -+ * second iteration with cache_first, then we don't need to search -+ * again -+ */ -+ subreq = cache_req_search_send(state, -+ state->ev, -+ state->cr, -+ false, /* Don't bypass cache */ -+ true); /* Do bypass DP */ -+ if (subreq == NULL) { -+ ret = ENOMEM; -+ goto immediately; -+ } -+ tevent_req_set_callback(subreq, cache_req_locate_dom_cache_done, req); -+ -+ return req; -+ -+immediately: -+ tevent_req_error(req, ret); -+ tevent_req_post(req, ev); -+ return req; -+} -+ -+static void cache_req_locate_dom_cache_done(struct tevent_req *subreq) -+{ -+ struct cache_req_locate_dom_state *state = NULL; -+ struct tevent_req *req; -+ errno_t ret; -+ -+ req = tevent_req_callback_data(subreq, struct tevent_req); -+ state = tevent_req_data(req, struct cache_req_locate_dom_state); -+ -+ ret = cache_req_search_recv(state, subreq, &state->result, &state->dp_success); -+ talloc_zfree(subreq); -+ -+ switch (ret) { -+ case EOK: -+ /* Just finish the request and let the caller handle the result */ -+ DEBUG(SSSDBG_TRACE_INTERNAL, "Result found in the cache\n"); -+ tevent_req_done(req); -+ return; -+ case ENOENT: -+ /* Not cached and locator was requested, run the locator -+ * DP request plugin -+ */ -+ subreq = cache_req_locate_domain_send(state, -+ state->ev, -+ state->cr); -+ if (subreq == NULL) { -+ tevent_req_error(req, ENOMEM); -+ return; -+ } -+ tevent_req_set_callback(subreq, cache_req_locate_dom_done, req); -+ return; -+ default: -+ DEBUG(SSSDBG_OP_FAILURE, -+ "cache_req_search_recv returned [%d]: %s\n", ret, sss_strerror(ret)); -+ break; -+ } -+ -+ tevent_req_error(req, ret); -+ return; -+} -+ -+static void cache_req_locate_dom_done(struct tevent_req *subreq) -+{ -+ struct cache_req_locate_dom_state *state; -+ struct tevent_req *req; -+ errno_t ret; -+ char *found_domain_name; -+ int nret; -+ -+ req = tevent_req_callback_data(subreq, struct tevent_req); -+ state = tevent_req_data(req, struct cache_req_locate_dom_state); -+ -+ ret = cache_req_locate_domain_recv(state, subreq, &found_domain_name); -+ talloc_zfree(subreq); -+ switch (ret) { -+ case ERR_GET_ACCT_DOM_NOT_SUPPORTED: -+ nret = cache_req_set_acct_domain_lookup_type(state->cr, -+ state->cr->domain); -+ if (nret != EOK) { -+ DEBUG(SSSDBG_MINOR_FAILURE, -+ "Failed to disable domain locating functionality for %s\n", -+ state->cr->plugin->name); -+ } -+ DEBUG(SSSDBG_CONF_SETTINGS, -+ "Disabled domain locating functionality for %s\n", -+ state->cr->plugin->name); -+ break; -+ case ERR_NOT_FOUND: -+ cache_req_locate_dom_mark_neg_all(state); -+ break; -+ case EOK: -+ cache_req_locate_dom_mark_neg_domains(state, found_domain_name); -+ break; -+ default: -+ /* We explicitly ignore errors here */ -+ break; -+ } -+ -+ tevent_req_done(req); -+ return; -+} -+ -+static void cache_req_locate_dom_mark_neg_all( -+ struct cache_req_locate_dom_state *state) -+{ -+ struct cache_req_domain *iter; -+ -+ DLIST_FOR_EACH(iter, state->req_domains) { -+ if (get_domains_head(state->cr->domain) != get_domains_head(iter->domain)) { -+ /* Only add to negative cache for domains from the same "main" -+ * domain" */ -+ continue; -+ } -+ cache_req_search_ncache_add_to_domain(state->cr, iter->domain); -+ } -+} -+ -+static void cache_req_locate_dom_mark_neg_domains( -+ struct cache_req_locate_dom_state *state, -+ const char *found_domain_name) -+{ -+ struct sss_domain_info *found_domain; -+ struct cache_req_domain *iter; -+ -+ found_domain = find_domain_by_name(get_domains_head(state->cr->domain), -+ found_domain_name, -+ true); -+ if (found_domain == NULL) { -+ DEBUG(SSSDBG_MINOR_FAILURE, -+ "Cannot find domain %s\n", found_domain_name); -+ return; -+ } -+ -+ /* Set negcache in all subdomains of the one being examined -+ * except the found one */ -+ DLIST_FOR_EACH(iter, state->req_domains) { -+ if (strcasecmp(found_domain_name, -+ iter->domain->name) == 0) { -+ continue; -+ } -+ -+ if (get_domains_head(found_domain) != get_domains_head(iter->domain)) { -+ /* Don't set negative cache for domains outside the main -+ * domain/subdomain tree b/c the locator request is not -+ * authoritative for them -+ */ -+ continue; -+ } -+ cache_req_search_ncache_add_to_domain(state->cr, iter->domain); -+ } -+} -+ -+static errno_t cache_req_locate_dom_cache_recv(TALLOC_CTX *mem_ctx, -+ struct tevent_req *req, -+ struct ldb_result **_result, -+ bool *_dp_success) -+{ -+ struct cache_req_locate_dom_state *state; -+ -+ state = tevent_req_data(req, struct cache_req_locate_dom_state); -+ -+ if (_dp_success != NULL) { -+ *_dp_success = state->dp_success; -+ } -+ -+ TEVENT_REQ_RETURN_ON_ERROR(req); -+ -+ if (_result != NULL) { -+ *_result = talloc_steal(mem_ctx, state->result); -+ } -+ -+ return EOK; -+} -+ - struct cache_req_search_domains_state { - /* input data */ - struct tevent_context *ev; -@@ -398,6 +666,7 @@ struct cache_req_search_domains_state { - - /* work data */ - struct cache_req_domain *cr_domain; -+ struct cache_req_domain *req_domains; - struct sss_domain_info *selected_domain; - struct cache_req_result **results; - size_t num_results; -@@ -408,6 +677,10 @@ struct cache_req_search_domains_state { - }; - - static errno_t cache_req_search_domains_next(struct tevent_req *req); -+static errno_t cache_req_handle_result(struct tevent_req *req, -+ struct ldb_result *result); -+ -+static void cache_req_search_domains_locate_done(struct tevent_req *subreq); - - static void cache_req_search_domains_done(struct tevent_req *subreq); - -@@ -417,6 +690,7 @@ cache_req_search_domains_send(TALLOC_CTX *mem_ctx, - struct cache_req *cr, - struct cache_req_domain *cr_domain, - bool check_next, -+ bool first_iteration, - bool bypass_cache, - bool bypass_dp) - { -@@ -435,11 +709,23 @@ cache_req_search_domains_send(TALLOC_CTX *mem_ctx, - state->cr = cr; - - state->cr_domain = cr_domain; -+ state->req_domains = cr_domain; - state->check_next = check_next; - state->dp_success = true; - state->bypass_cache = bypass_cache; - state->bypass_dp = bypass_dp; - -+ if (cr->plugin->dp_get_domain_send_fn != NULL -+ && ((state->check_next && cr_domain->next != NULL) -+ || (state->bypass_cache && !first_iteration))) { -+ /* If the request is not qualified with a domain name AND -+ * there are multiple domains to search OR if this is the second -+ * pass during the "check-cache-first" schema, it makes sense -+ * to try to run the domain-locator plugin -+ */ -+ cache_req_domain_set_locate_flag(cr_domain, cr); -+ } -+ - ret = cache_req_search_domains_next(req); - if (ret == EAGAIN) { - return req; -@@ -510,12 +796,23 @@ static errno_t cache_req_search_domains_next(struct tevent_req *req) - return ret; - } - -+ if (state->cr_domain->locate_domain) { -+ subreq = cache_req_locate_dom_send(state, -+ state->ev, -+ cr, -+ state->req_domains); -+ if (subreq == NULL) { -+ return ENOMEM; -+ } -+ tevent_req_set_callback(subreq, cache_req_search_domains_locate_done, req); -+ return EAGAIN; -+ } -+ - subreq = cache_req_search_send(state, state->ev, cr, - state->bypass_cache, state->bypass_dp); - if (subreq == NULL) { - return ENOMEM; - } -- - tevent_req_set_callback(subreq, cache_req_search_domains_done, req); - - /* we will continue with the following domain the next time */ -@@ -549,6 +846,89 @@ static errno_t cache_req_search_domains_next(struct tevent_req *req) - return ENOENT; - } - -+static void cache_req_search_domains_locate_done(struct tevent_req *subreq) -+{ -+ struct cache_req_search_domains_state *state; -+ struct ldb_result *result = NULL; -+ struct tevent_req *req; -+ bool dp_success; -+ errno_t ret; -+ -+ req = tevent_req_callback_data(subreq, struct tevent_req); -+ state = tevent_req_data(req, struct cache_req_search_domains_state); -+ -+ ret = cache_req_locate_dom_cache_recv(state, subreq, &result, &dp_success); -+ talloc_zfree(subreq); -+ -+ /* Remember if any DP request fails, but here it shouldn't matter -+ * as the only DP request that should realistically happen is midpoint -+ * refresh */ -+ state->dp_success = !dp_success ? false : state->dp_success; -+ -+ /* Don't locate the domain again */ -+ state->cr_domain->locate_domain = false; -+ -+ switch (ret) { -+ case EOK: -+ if (result != NULL) { -+ /* Handle result as normally */ -+ ret = cache_req_handle_result(req, result); -+ if (ret != EAGAIN) { -+ goto done; -+ } -+ } -+ break; -+ default: -+ /* Some serious error has happened. Finish. */ -+ goto done; -+ } -+ -+ /* This is a domain less search, continue with the next domain. */ -+ ret = cache_req_search_domains_next(req); -+ -+done: -+ switch (ret) { -+ case EOK: -+ tevent_req_done(req); -+ break; -+ case EAGAIN: -+ break; -+ default: -+ tevent_req_error(req, ret); -+ break; -+ } -+ return; -+} -+ -+static errno_t cache_req_handle_result(struct tevent_req *req, -+ struct ldb_result *result) -+{ -+ struct cache_req_search_domains_state *state; -+ errno_t ret; -+ -+ state = tevent_req_data(req, struct cache_req_search_domains_state); -+ -+ /* We got some data from this search. Save it. */ -+ ret = cache_req_create_and_add_result(state, -+ state->cr, -+ state->selected_domain, -+ result, -+ state->cr->data->name.lookup, -+ &state->results, -+ &state->num_results); -+ if (ret != EOK) { -+ /* We were unable to save data. */ -+ return ret; -+ } -+ -+ if (!state->check_next || !state->cr->plugin->search_all_domains) { -+ /* We are not interested in more results. */ -+ return EOK; -+ } -+ -+ return EAGAIN; -+} -+ - static void cache_req_search_domains_done(struct tevent_req *subreq) - { - struct cache_req_search_domains_state *state; -@@ -568,25 +948,10 @@ static void cache_req_search_domains_done(struct tevent_req *subreq) - - switch (ret) { - case EOK: -- /* We got some data from this search. Save it. */ -- ret = cache_req_create_and_add_result(state, -- state->cr, -- state->selected_domain, -- result, -- state->cr->data->name.lookup, -- &state->results, -- &state->num_results); -- if (ret != EOK) { -- /* We were unable to save data. */ -+ ret = cache_req_handle_result(req, result); -+ if (ret != EAGAIN) { - goto done; - } -- -- if (!state->check_next || !state->cr->plugin->search_all_domains) { -- /* We are not interested in more results. */ -- ret = EOK; -- goto done; -- } -- - break; - case ENOENT: - if (state->check_next == false) { -@@ -1030,6 +1395,7 @@ cache_req_search_domains(struct tevent_req *req, - - subreq = cache_req_search_domains_send(state, state->ev, state->cr, - cr_domain, check_next, -+ state->first_iteration, - bypass_cache, bypass_dp); - if (subreq == NULL) { - return ENOMEM; -diff --git a/src/responder/common/cache_req/cache_req_domain.h b/src/responder/common/cache_req/cache_req_domain.h -index ebdc71dd635d5d8a5d06e30e96c5d4101b6d98bf..5769b6aee309d9ba3edd5bb73a3cef6dc3193fdc 100644 ---- a/src/responder/common/cache_req/cache_req_domain.h -+++ b/src/responder/common/cache_req/cache_req_domain.h -@@ -26,6 +26,7 @@ - struct cache_req_domain { - struct sss_domain_info *domain; - bool fqnames; -+ bool locate_domain; - - struct cache_req_domain *prev; - struct cache_req_domain *next; -diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c -index f075480a019e476407a3081a795c3c289455aca8..0ee0070d0c9fbb89020f522b2f7613f1076a8cbb 100644 ---- a/src/tests/cmocka/test_responder_cache_req.c -+++ b/src/tests/cmocka/test_responder_cache_req.c -@@ -27,6 +27,7 @@ - #include "tests/cmocka/common_mock_resp.h" - #include "db/sysdb.h" - #include "responder/common/cache_req/cache_req.h" -+#include "db/sysdb_private.h" /* new_subdomain() */ - - #define TESTS_PATH "tp_" BASE_FILE_STEM - #define TEST_CONF_DB "test_responder_cache_req_conf.ldb" -@@ -63,6 +64,11 @@ struct test_group { - test_multi_domain_setup, \ - test_multi_domain_teardown) - -+#define new_subdomain_test(test) \ -+ cmocka_unit_test_setup_teardown(test_ ## test, \ -+ test_subdomain_setup, \ -+ test_subdomain_teardown) -+ - #define run_cache_req(ctx, send_fn, done_fn, dom, crp, lookup, expret) do { \ - TALLOC_CTX *req_mem_ctx; \ - struct tevent_req *req; \ -@@ -110,6 +116,7 @@ struct cache_req_test_ctx { - struct sss_test_ctx *tctx; - struct resp_ctx *rctx; - struct sss_nc_ctx *ncache; -+ struct sss_domain_info *subdomain; - - struct cache_req_result *result; - bool dp_called; -@@ -120,6 +127,8 @@ struct cache_req_test_ctx { - bool create_user2; - bool create_group1; - bool create_group2; -+ bool create_subgroup1; -+ bool create_subuser1; - }; - - const char *domains[] = {"responder_cache_req_test_a", -@@ -128,6 +137,8 @@ const char *domains[] = {"responder_cache_req_test_a", - "responder_cache_req_test_d", - NULL}; - -+const char *subdomain_name = "responder_cache_req_test_a_sub"; -+ - struct cli_protocol_version *register_cli_protocol_version(void) - { - static struct cli_protocol_version version[] = { -@@ -487,6 +498,26 @@ __wrap_sss_dp_get_account_send(TALLOC_CTX *mem_ctx, - prepare_group(ctx->tctx->dom, &groups[1], 1000, time(NULL)); - } - -+ if (ctx->create_subgroup1) { -+ struct sss_domain_info *domain = NULL; -+ -+ domain = find_domain_by_name(ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_group(domain, &groups[0], 1000, time(NULL)); -+ } -+ -+ if (ctx->create_subuser1) { -+ struct sss_domain_info *domain = NULL; -+ -+ domain = find_domain_by_name(ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_user(domain, &users[0], 1000, time(NULL)); -+ } -+ - return test_req_succeed_send(mem_ctx, rctx->ev); - } - -@@ -581,6 +612,67 @@ static int test_multi_domain_teardown(void **state) - return 0; - } - -+static int test_subdomain_setup(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ int ret; -+ const char *const testdom[4] = { subdomain_name, "TEST_A.SUB", "test_a", "S-3" }; -+ -+ assert_true(leak_check_setup()); -+ -+ test_dom_suite_setup(TESTS_PATH); -+ -+ test_ctx = talloc_zero(global_talloc_context, struct cache_req_test_ctx); -+ assert_non_null(test_ctx); -+ *state = test_ctx; -+ -+ test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, -+ TEST_DOM_NAME, TEST_ID_PROVIDER, NULL); -+ assert_non_null(test_ctx->tctx); -+ -+ test_ctx->rctx = mock_rctx(test_ctx, test_ctx->tctx->ev, -+ test_ctx->tctx->dom, NULL); -+ assert_non_null(test_ctx->rctx); -+ -+ ret = sss_ncache_init(test_ctx, 10, 0, &test_ctx->ncache); -+ assert_int_equal(ret, EOK); -+ -+ test_ctx->subdomain = new_subdomain(test_ctx, test_ctx->tctx->dom, -+ testdom[0], testdom[1], testdom[2], testdom[3], -+ false, false, NULL, NULL, 0, -+ test_ctx->tctx->confdb); -+ assert_non_null(test_ctx->subdomain); -+ -+ ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, -+ testdom[0], testdom[1], testdom[2], testdom[3], -+ false, false, NULL, 0, NULL); -+ assert_int_equal(ret, EOK); -+ -+ ret = sysdb_update_subdomains(test_ctx->tctx->dom, -+ test_ctx->tctx->confdb); -+ assert_int_equal(ret, EOK); -+ -+ *state = test_ctx; -+ check_leaks_push(test_ctx); -+ return 0; -+} -+ -+static int test_subdomain_teardown(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ talloc_zfree(test_ctx->result); -+ talloc_zfree(test_ctx->rctx->cr_domains); -+ -+ assert_true(check_leaks_pop(test_ctx)); -+ talloc_zfree(test_ctx); -+ test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); -+ assert_true(leak_check_teardown()); -+ return 0; -+} -+ - void test_user_by_name_multiple_domains_found(void **state) - { - struct cache_req_test_ctx *test_ctx = NULL; -@@ -974,6 +1066,7 @@ void test_user_by_id_multiple_domains_found(void **state) - /* Mock values. */ - will_return_always(__wrap_sss_dp_get_account_send, test_ctx); - will_return_always(sss_dp_req_recv, 0); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); - - /* Test. */ - run_user_by_id(test_ctx, NULL, 0, ERR_OK); -@@ -990,12 +1083,317 @@ void test_user_by_id_multiple_domains_notfound(void **state) - /* Mock values. */ - will_return_always(__wrap_sss_dp_get_account_send, test_ctx); - will_return_always(sss_dp_req_recv, 0); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); - - /* Test. */ - run_user_by_id(test_ctx, NULL, 0, ENOENT); - assert_true(test_ctx->dp_called); - } - -+void test_user_by_id_multiple_domains_locator_cache_valid(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ "responder_cache_req_test_d", true); -+ assert_non_null(domain); -+ prepare_user(domain, &users[0], 1000, time(NULL)); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); -+ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, EOK); -+ -+ /* Test. */ -+ run_user_by_id(test_ctx, NULL, 0, ERR_OK); -+ /* Even though the locator tells us to skip all domains except d, the domains -+ * are standalone and the result of the locator request is only valid within -+ * the subdomains -+ */ -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_user_by_id_multiple_domains_locator_cache_expired(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ "responder_cache_req_test_d", true); -+ assert_non_null(domain); -+ prepare_user(domain, &users[0], -1000, time(NULL)); -+ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, EOK); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); -+ -+ /* Test. */ -+ run_user_by_id(test_ctx, NULL, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_user_by_id_sub_domains_locator_cache_valid(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_user(domain, &users[0], 1000, time(NULL)); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_user_by_id(test_ctx, NULL, 0, ERR_OK); -+ -+ /* Even though the ID is present in the last domain, -+ * we're not calling sss_dp_get_account_send, -+ * because the locator will cause cache_req to skip -+ * all domains except _d -+ */ -+ assert_false(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_user_by_id_sub_domains_locator_cache_expired(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_user(domain, &users[0], -1000, time(NULL)); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_user_by_id(test_ctx, NULL, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_user_by_id_sub_domains_locator_cache_midpoint(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_user(domain, &users[0], 50, time(NULL) - 26); -+ -+ /* Note - DP will only be called once and we're not waiting -+ * for the results (so, we're not mocking _recv) -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_user_by_id(test_ctx, NULL, 50, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_user_by_id_sub_domains_locator_missing_found(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ test_ctx->create_subuser1 = true; -+ run_user_by_id(test_ctx, NULL, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_user_by_id_sub_domains_locator_missing_notfound(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ will_return(sss_dp_get_account_domain_recv, ERR_NOT_FOUND); -+ -+ /* Test. */ -+ run_user_by_id(test_ctx, NULL, 0, ENOENT); -+ assert_false(test_ctx->dp_called); -+} -+ -+void test_user_by_id_sub_domains_locator_cache_expired_two_calls(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ test_ctx->create_subuser1 = true; -+ prepare_user(domain, &users[0], -1000, time(NULL)); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_user_by_id(test_ctx, NULL, 0, ERR_OK); -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ /* Request the same user again */ -+ test_ctx->tctx->done = false; -+ talloc_zfree(test_ctx->result); -+ -+ run_user_by_id(test_ctx, NULL, 0, ERR_OK); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ - void test_user_by_id_cache_valid(void **state) - { - struct cache_req_test_ctx *test_ctx = NULL; -@@ -1332,6 +1730,7 @@ void test_group_by_id_multiple_domains_found(void **state) - /* Mock values. */ - will_return_always(__wrap_sss_dp_get_account_send, test_ctx); - will_return_always(sss_dp_req_recv, 0); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); - - /* Test. */ - run_group_by_id(test_ctx, NULL, 0, ERR_OK); -@@ -1348,12 +1747,318 @@ void test_group_by_id_multiple_domains_notfound(void **state) - /* Mock values. */ - will_return_always(__wrap_sss_dp_get_account_send, test_ctx); - will_return_always(sss_dp_req_recv, 0); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); - - /* Test. */ - run_group_by_id(test_ctx, NULL, 0, ENOENT); - assert_true(test_ctx->dp_called); - } - -+void test_group_by_id_multiple_domains_locator_cache_valid(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ "responder_cache_req_test_d", true); -+ assert_non_null(domain); -+ prepare_group(domain, &groups[0], 1000, time(NULL)); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); -+ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, EOK); -+ -+ /* Test. */ -+ run_group_by_id(test_ctx, NULL, 0, ERR_OK); -+ -+ /* Even though the locator tells us to skip all domains except d, the domains -+ * are standalone and the result of the locator request is only valid within -+ * the subdomains -+ */ -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_group_by_id_multiple_domains_locator_cache_expired(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ "responder_cache_req_test_d", true); -+ assert_non_null(domain); -+ prepare_group(domain, &groups[0], -1000, time(NULL)); -+ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, EOK); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); -+ -+ /* Test. */ -+ run_group_by_id(test_ctx, NULL, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_group_by_id_sub_domains_locator_cache_valid(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_group(domain, &groups[0], 1000, time(NULL)); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_group_by_id(test_ctx, NULL, 0, ERR_OK); -+ -+ /* Even though the ID is present in the last domain, -+ * we're not calling sss_dp_get_account_send, -+ * because the locator will cause cache_req to skip -+ * all domains except _d -+ */ -+ assert_false(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_group_by_id_sub_domains_locator_cache_expired(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_group(domain, &groups[0], -1000, time(NULL)); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_group_by_id(test_ctx, NULL, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_group_by_id_sub_domains_locator_cache_midpoint(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_group(domain, &groups[0], 50, time(NULL) - 26); -+ -+ /* Note - DP will only be called once and we're not waiting -+ * for the results (so, we're not mocking _recv) -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_group_by_id(test_ctx, NULL, 50, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_group_by_id_sub_domains_locator_missing_found(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ test_ctx->create_subgroup1 = true; -+ run_group_by_id(test_ctx, NULL, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_group_by_id_sub_domains_locator_missing_notfound(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ will_return(sss_dp_get_account_domain_recv, ERR_NOT_FOUND); -+ -+ /* Test. */ -+ run_group_by_id(test_ctx, NULL, 0, ENOENT); -+ assert_false(test_ctx->dp_called); -+} -+ -+void test_group_by_id_sub_domains_locator_cache_expired_two_calls(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ test_ctx->create_subgroup1 = true; -+ prepare_group(domain, &groups[0], -1000, time(NULL)); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_group_by_id(test_ctx, NULL, 0, ERR_OK); -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ /* Request the same group again */ -+ test_ctx->tctx->done = false; -+ talloc_zfree(test_ctx->result); -+ -+ run_group_by_id(test_ctx, NULL, 0, ERR_OK); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ - void test_group_by_id_cache_valid(void **state) - { - struct cache_req_test_ctx *test_ctx = NULL; -@@ -2311,6 +3016,7 @@ void test_object_by_id_user_multiple_domains_found(void **state) - /* Mock values. */ - will_return_always(__wrap_sss_dp_get_account_send, test_ctx); - will_return_always(sss_dp_req_recv, 0); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); - - /* Test. */ - run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); -@@ -2328,6 +3034,7 @@ void test_object_by_id_user_multiple_domains_notfound(void **state) - /* Mock values. */ - will_return_always(__wrap_sss_dp_get_account_send, test_ctx); - will_return_always(sss_dp_req_recv, 0); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); - - /* Test. */ - run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ENOENT); -@@ -2476,6 +3183,7 @@ void test_object_by_id_group_multiple_domains_found(void **state) - /* Mock values. */ - will_return_always(__wrap_sss_dp_get_account_send, test_ctx); - will_return_always(sss_dp_req_recv, 0); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); - - /* Test. */ - run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); -@@ -2493,12 +3201,641 @@ void test_object_by_id_group_multiple_domains_notfound(void **state) - /* Mock values. */ - will_return_always(__wrap_sss_dp_get_account_send, test_ctx); - will_return_always(sss_dp_req_recv, 0); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); - - /* Test. */ - run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ENOENT); - assert_true(test_ctx->dp_called); - } - -+void test_object_by_id_user_multiple_domains_locator_cache_valid(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ "responder_cache_req_test_d", true); -+ assert_non_null(domain); -+ prepare_user(domain, &users[0], 1000, time(NULL)); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); -+ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, EOK); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); -+ /* Even though the locator tells us to skip all domains except d, the domains -+ * are standalone and the result of the locator request is only valid within -+ * the subdomains -+ */ -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_user_multiple_domains_locator_cache_expired(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ "responder_cache_req_test_d", true); -+ assert_non_null(domain); -+ prepare_user(domain, &users[0], -1000, time(NULL)); -+ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, EOK); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_user_sub_domains_locator_cache_valid(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_user(domain, &users[0], 1000, time(NULL)); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); -+ -+ /* Even though the ID is present in the last domain, -+ * we're not calling sss_dp_get_account_send, -+ * because the locator will cause cache_req to skip -+ * all domains except _d -+ */ -+ assert_false(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_user_sub_domains_locator_cache_expired(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_user(domain, &users[0], -1000, time(NULL)); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_user_sub_domains_locator_cache_midpoint(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_user(domain, &users[0], 50, time(NULL) - 26); -+ -+ /* Note - DP will only be called once and we're not waiting -+ * for the results (so, we're not mocking _recv) -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 50, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_user_sub_domains_locator_missing_found(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ test_ctx->create_subuser1 = true; -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_user_sub_domains_locator_missing_notfound(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ will_return(sss_dp_get_account_domain_recv, ERR_NOT_FOUND); -+ -+ /* The test won't even ask the DP for the object, just iterate -+ * over the domains using the negative cache and quit -+ */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ENOENT); -+ assert_false(test_ctx->dp_called); -+} -+ -+void test_object_by_id_user_sub_domains_locator_cache_expired_two_calls(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup user. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ test_ctx->create_subuser1 = true; -+ prepare_user(domain, &users[0], -1000, time(NULL)); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, EOK); -+ assert_true(test_ctx->dp_called); -+ check_user(test_ctx, &users[0], domain); -+ -+ /* Request the same user again */ -+ test_ctx->tctx->done = false; -+ talloc_zfree(test_ctx->result); -+ -+ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, EOK); -+ check_user(test_ctx, &users[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_group_multiple_domains_locator_cache_valid(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ "responder_cache_req_test_d", true); -+ assert_non_null(domain); -+ prepare_group(domain, &groups[0], 1000, time(NULL)); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); -+ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, EOK); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); -+ /* Even though the locator tells us to skip all domains except d, the domains -+ * are standalone and the result of the locator request is only valid within -+ * the subdomains -+ */ -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_group_multiple_domains_locator_cache_expired(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ "responder_cache_req_test_d", true); -+ assert_non_null(domain); -+ prepare_group(domain, &groups[0], -1000, time(NULL)); -+ -+ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, EOK); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_group_sub_domains_locator_cache_valid(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_group(domain, &groups[0], 1000, time(NULL)); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); -+ -+ /* Even though the ID is present in the last domain, -+ * we're not calling sss_dp_get_account_send, -+ * because the locator will cause cache_req to skip -+ * all domains except _d -+ */ -+ assert_false(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_group_sub_domains_locator_cache_expired(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_group(domain, &groups[0], -1000, time(NULL)); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_group_sub_domains_locator_cache_midpoint(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ prepare_group(domain, &groups[0], 50, time(NULL) - 26); -+ -+ /* Note - DP will only be called once and we're not waiting -+ * for the results (so, we're not mocking _recv) -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 50, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_group_sub_domains_locator_missing_found(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ test_ctx->create_subgroup1 = true; -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); -+ -+ assert_true(test_ctx->dp_called); -+ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ -+void test_object_by_id_group_sub_domains_locator_missing_notfound(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ will_return(sss_dp_get_account_domain_recv, ERR_NOT_FOUND); -+ -+ /* The test won't even ask the DP for the object, just iterate -+ * over the domains using the negative cache and quit -+ */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ENOENT); -+ assert_false(test_ctx->dp_called); -+} -+ -+void test_object_by_id_group_sub_domains_locator_cache_expired_two_calls(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ struct sss_domain_info *domain = NULL; -+ const char *locator_domain; -+ TALLOC_CTX *tmp_ctx; -+ const char *attrs[] = SYSDB_PW_ATTRS; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ tmp_ctx = talloc_new(test_ctx); -+ assert_non_null(tmp_ctx); -+ -+ /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ -+ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); -+ assert_non_null(locator_domain); -+ -+ /* Setup group. */ -+ domain = find_domain_by_name(test_ctx->tctx->dom, -+ subdomain_name, -+ true); -+ assert_non_null(domain); -+ test_ctx->create_subgroup1 = true; -+ prepare_group(domain, &groups[0], -1000, time(NULL)); -+ -+ /* Note - DP will only be called once (so, we're not using will_return_always) -+ * because the locator will tell us which domain to look into. For the recv -+ * function, we use always b/c internally it mocks several values. -+ */ -+ will_return(__wrap_sss_dp_get_account_send, test_ctx); -+ will_return_always(sss_dp_req_recv, 0); -+ -+ will_return(sss_dp_get_account_domain_recv, EOK); -+ will_return(sss_dp_get_account_domain_recv, locator_domain); -+ -+ /* Test. */ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, EOK); -+ assert_true(test_ctx->dp_called); -+ check_group(test_ctx, &groups[0], domain); -+ -+ /* Request the same group again */ -+ test_ctx->tctx->done = false; -+ talloc_zfree(test_ctx->result); -+ -+ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, EOK); -+ check_group(test_ctx, &groups[0], domain); -+ -+ talloc_free(tmp_ctx); -+} -+ - int main(int argc, const char *argv[]) - { - poptContext pc; -@@ -2557,6 +3894,24 @@ int main(int argc, const char *argv[]) - new_multi_domain_test(group_by_id_multiple_domains_found), - new_multi_domain_test(group_by_id_multiple_domains_notfound), - -+ new_multi_domain_test(group_by_id_multiple_domains_locator_cache_valid), -+ new_multi_domain_test(group_by_id_multiple_domains_locator_cache_expired), -+ new_subdomain_test(group_by_id_sub_domains_locator_cache_valid), -+ new_subdomain_test(group_by_id_sub_domains_locator_cache_expired), -+ new_subdomain_test(group_by_id_sub_domains_locator_cache_midpoint), -+ new_subdomain_test(group_by_id_sub_domains_locator_missing_found), -+ new_subdomain_test(group_by_id_sub_domains_locator_missing_notfound), -+ new_subdomain_test(group_by_id_sub_domains_locator_cache_expired_two_calls), -+ -+ new_multi_domain_test(user_by_id_multiple_domains_locator_cache_valid), -+ new_multi_domain_test(user_by_id_multiple_domains_locator_cache_expired), -+ new_subdomain_test(user_by_id_sub_domains_locator_cache_valid), -+ new_subdomain_test(user_by_id_sub_domains_locator_cache_expired), -+ new_subdomain_test(user_by_id_sub_domains_locator_cache_midpoint), -+ new_subdomain_test(user_by_id_sub_domains_locator_missing_found), -+ new_subdomain_test(user_by_id_sub_domains_locator_missing_notfound), -+ new_subdomain_test(user_by_id_sub_domains_locator_cache_expired_two_calls), -+ - new_single_domain_test(user_by_recent_filter_valid), - new_single_domain_test(users_by_recent_filter_valid), - new_single_domain_test(group_by_recent_filter_valid), -@@ -2603,6 +3958,24 @@ int main(int argc, const char *argv[]) - new_single_domain_test(object_by_id_group_missing_notfound), - new_multi_domain_test(object_by_id_group_multiple_domains_found), - new_multi_domain_test(object_by_id_group_multiple_domains_notfound), -+ -+ new_multi_domain_test(object_by_id_user_multiple_domains_locator_cache_valid), -+ new_multi_domain_test(object_by_id_user_multiple_domains_locator_cache_expired), -+ new_subdomain_test(object_by_id_user_sub_domains_locator_cache_valid), -+ new_subdomain_test(object_by_id_user_sub_domains_locator_cache_expired), -+ new_subdomain_test(object_by_id_user_sub_domains_locator_cache_midpoint), -+ new_subdomain_test(object_by_id_user_sub_domains_locator_missing_found), -+ new_subdomain_test(object_by_id_user_sub_domains_locator_missing_notfound), -+ new_subdomain_test(object_by_id_user_sub_domains_locator_cache_expired_two_calls), -+ -+ new_multi_domain_test(object_by_id_group_multiple_domains_locator_cache_valid), -+ new_multi_domain_test(object_by_id_group_multiple_domains_locator_cache_expired), -+ new_subdomain_test(object_by_id_group_sub_domains_locator_cache_valid), -+ new_subdomain_test(object_by_id_group_sub_domains_locator_cache_expired), -+ new_subdomain_test(object_by_id_group_sub_domains_locator_cache_midpoint), -+ new_subdomain_test(object_by_id_group_sub_domains_locator_missing_found), -+ new_subdomain_test(object_by_id_group_sub_domains_locator_missing_notfound), -+ new_subdomain_test(object_by_id_group_sub_domains_locator_cache_expired_two_calls), - }; - - /* Set debug level to invalid value so we can deside if -d 0 was used. */ --- -2.14.3 - diff --git a/SOURCES/0083-MAN-Document-how-the-Global-Catalog-is-used-currentl.patch b/SOURCES/0083-MAN-Document-how-the-Global-Catalog-is-used-currentl.patch deleted file mode 100644 index 4a339e0..0000000 --- a/SOURCES/0083-MAN-Document-how-the-Global-Catalog-is-used-currentl.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 251e4914e55c6b66ab6eabd3b3e2e2b7b49029e3 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Sun, 19 Nov 2017 22:31:44 +0100 -Subject: [PATCH 83/83] MAN: Document how the Global Catalog is used currently -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The existing documentation was outdated. Remove it and document what the -current patchset adds. - -Related: -https://pagure.io/SSSD/sssd/issue/3468 - -Reviewed-by: Pavel Březina -Reviewed-by: Sumit Bose -(cherry picked from commit a72919af8347b5bbc65a3b1fb3e5d31447240b24) ---- - src/man/sssd-ad.5.xml | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml -index 649042d587de3d3600fff59866681e302c721af8..c4a3fc2b5780eb0f15935a2c38f48418c5f7bb52 100644 ---- a/src/man/sssd-ad.5.xml -+++ b/src/man/sssd-ad.5.xml -@@ -84,9 +84,16 @@ - - ldap_id_mapping = False - -- In order to retrieve users and groups using POSIX attributes from trusted -- domains, the AD administrator must make sure that the POSIX attributes -- are replicated to the Global Catalog. -+ If POSIX attributes should be used, it is recommended for -+ performance reasons that the attributes are also replicated -+ to the Global Catalog. If POSIX attributes are replicated, -+ SSSD will attempt to locate the domain of a requested -+ numerical ID with the help of the Global Catalog and only -+ search that domain. In contrast, if POSIX attributes are not -+ replicated to the Global Catalog, SSSD must search all the -+ domains in the forest sequentially. Please note that that the -+ cache_first option might be also helpful in -+ speeding up domainless searches. - - - Users, groups and other entities served by SSSD are always treated as --- -2.14.3 - diff --git a/SOURCES/0084-p11_child-make-sure-OCSP-checks-are-done.patch b/SOURCES/0084-p11_child-make-sure-OCSP-checks-are-done.patch deleted file mode 100644 index e2b497f..0000000 --- a/SOURCES/0084-p11_child-make-sure-OCSP-checks-are-done.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 62275e72ff0b9849c899f0fecea90731fff9da0a Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 7 Dec 2017 17:08:33 +0100 -Subject: [PATCH 84/86] p11_child: make sure OCSP checks are done -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If CERT_VerifyCertificateNow() is used with -'certificateUsageCheckAllUsages' OCSP checks are skipped even if OCSP -was enabled. - -This patch calls CERT_CheckOCSPStatus() explicitly if OCSP checks are -enabled. - -Related to https://pagure.io/SSSD/sssd/issue/3560 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 2297cc7d6cd5c38a7d64027165e4e82ca497f418) ---- - src/p11_child/p11_child_nss.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index 21c508eb1b1b68b3606d0a5eed36573b01f27a19..bf533f3efe4d680f4c6dbd10a0d2c5a5da371c67 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -338,6 +338,23 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - PR_GetError(), PORT_ErrorToString(PR_GetError())); - continue; - } -+ -+ /* with 'certificateUsageCheckAllUsages' set -+ * CERT_VerifyCertificateNow() does not do OCSP so it must be done -+ * explicitly */ -+ if (cert_verify_opts->do_ocsp) { -+ rv = CERT_CheckOCSPStatus(handle, cert_list_node->cert, -+ PR_Now(), NULL); -+ if (rv != SECSuccess) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Certificate [%s][%s] failed OCSP check [%d][%s], " -+ "skipping.\n", -+ cert_list_node->cert->nickname, -+ cert_list_node->cert->subjectName, -+ PR_GetError(), PORT_ErrorToString(PR_GetError())); -+ continue; -+ } -+ } - } - - if (key_id_in != NULL) { --- -2.14.3 - diff --git a/SOURCES/0085-IPA-Include-SYSDB_OBJECTCATEGORY-not-OBJECTCLASS-in-.patch b/SOURCES/0085-IPA-Include-SYSDB_OBJECTCATEGORY-not-OBJECTCLASS-in-.patch deleted file mode 100644 index 49fffa3..0000000 --- a/SOURCES/0085-IPA-Include-SYSDB_OBJECTCATEGORY-not-OBJECTCLASS-in-.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0f707b5f99f4cc17b61026e7a0e7787e776fae87 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Wed, 6 Dec 2017 15:45:13 +0100 -Subject: [PATCH 85/86] IPA: Include SYSDB_OBJECTCATEGORY, not OBJECTCLASS in - cache search results -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The function get_object_from_cache() returns an ldb_message that is -passed to apply_subdomain_homedir() which expects SYSDB_OBJECTCATEGORY -to be present in the message, otherwise it errors out. - -However, get_object_from_cache() was reading only SYSDB_OBJECTCLASS. - -This patch changes get_object_from_cache() to ready -SYSDB_OBJECTCATEGORY. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3599 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit dc49e07a0dbbbf3d69d09a7c6f236d82c86c7def) ---- - src/providers/ipa/ipa_subdomains_id.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c -index 2ba9813a44b4d914d9c2ef7a1a7504546f52954c..d40671086854f9c1a3f8bc7fc711009298dc31c8 100644 ---- a/src/providers/ipa/ipa_subdomains_id.c -+++ b/src/providers/ipa/ipa_subdomains_id.c -@@ -965,7 +965,7 @@ errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, - const char *attrs[] = { SYSDB_NAME, - SYSDB_UIDNUM, - SYSDB_SID_STR, -- SYSDB_OBJECTCLASS, -+ SYSDB_OBJECTCATEGORY, - SYSDB_UUID, - SYSDB_GHOST, - SYSDB_HOMEDIR, --- -2.14.3 - diff --git a/SOURCES/0086-nss-idmap-allow-NULL-result-in-_timeout-calls.patch b/SOURCES/0086-nss-idmap-allow-NULL-result-in-_timeout-calls.patch deleted file mode 100644 index 95bdd75..0000000 --- a/SOURCES/0086-nss-idmap-allow-NULL-result-in-_timeout-calls.patch +++ /dev/null @@ -1,113 +0,0 @@ -From 2a3accc78bb9658401b33ad5a3a2f1bc4bc3c269 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 7 Dec 2017 17:42:45 +0100 -Subject: [PATCH 86/86] nss-idmap: allow NULL result in *_timeout calls -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -To make the *_timeout calls more resilient checks are added if the -result parameter is NULL. It will not be used in this case. - -Related to https://pagure.io/SSSD/sssd/issue/2478 - -Reviewed-by: Fabiano Fidêncio -Reviewed-by: Alexander Bokovoy -(cherry picked from commit bba068c535d23eebff61f592bddb3a6438446d6f) ---- - src/sss_client/idmap/sss_nss_ex.c | 46 +++++++++++++++++++++++++++------------ - 1 file changed, 32 insertions(+), 14 deletions(-) - -diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c -index dcd9619a8b07ced7498f61b7e809fa46ebffe09e..861b1e1e92db4f7e6e8d74a812dc3c9220711773 100644 ---- a/src/sss_client/idmap/sss_nss_ex.c -+++ b/src/sss_client/idmap/sss_nss_ex.c -@@ -367,13 +367,17 @@ int sss_nss_getpwnam_timeout(const char *name, struct passwd *pwd, - return ret; - } - -- *result = NULL; -- - ret = sss_get_ex(&inp, flags, timeout); - free(discard_const(inp.rd.data)); -- if (ret == 0) { -- *result = inp.result.pwrep.result; -+ -+ if (result != NULL) { -+ if (ret == 0) { -+ *result = inp.result.pwrep.result; -+ } else { -+ *result = NULL; -+ } - } -+ - return ret; - } - -@@ -395,12 +399,17 @@ int sss_nss_getpwuid_timeout(uid_t uid, struct passwd *pwd, - - SAFEALIGN_COPY_UINT32(&req_data[0], &uid, NULL); - SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL); -- *result = NULL; - - ret = sss_get_ex(&inp, flags, timeout); -- if (ret == 0) { -- *result = inp.result.pwrep.result; -+ -+ if (result != NULL) { -+ if (ret == 0) { -+ *result = inp.result.pwrep.result; -+ } else { -+ *result = NULL; -+ } - } -+ - return ret; - } - -@@ -421,13 +430,17 @@ int sss_nss_getgrnam_timeout(const char *name, struct group *grp, - return ret; - } - -- *result = NULL; -- - ret = sss_get_ex(&inp, flags, timeout); - free(discard_const(inp.rd.data)); -- if (ret == 0) { -- *result = inp.result.grrep.result; -+ -+ if (result != NULL) { -+ if (ret == 0) { -+ *result = inp.result.grrep.result; -+ } else { -+ *result = NULL; -+ } - } -+ - return ret; - } - -@@ -448,12 +461,17 @@ int sss_nss_getgrgid_timeout(gid_t gid, struct group *grp, - - SAFEALIGN_COPY_UINT32(&req_data[0], &gid, NULL); - SAFEALIGN_COPY_UINT32(&req_data[1], &flags, NULL); -- *result = NULL; - - ret = sss_get_ex(&inp, flags, timeout); -- if (ret == 0) { -- *result = inp.result.grrep.result; -+ -+ if (result != NULL) { -+ if (ret == 0) { -+ *result = inp.result.grrep.result; -+ } else { -+ *result = NULL; -+ } - } -+ - return ret; - } - --- -2.14.3 - diff --git a/SOURCES/0087-cache-Check-for-max_id-min_id-in-cache_req.patch b/SOURCES/0087-cache-Check-for-max_id-min_id-in-cache_req.patch deleted file mode 100644 index 04860c2..0000000 --- a/SOURCES/0087-cache-Check-for-max_id-min_id-in-cache_req.patch +++ /dev/null @@ -1,353 +0,0 @@ -From 2f712c8fe0ecaa07f7b15ebeae5213978d033278 Mon Sep 17 00:00:00 2001 -From: amitkuma -Date: Thu, 30 Nov 2017 22:18:39 +0530 -Subject: [PATCH 87/87] cache: Check for max_id/min_id in cache_req -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The cache_req code doesn't check the min_id/max_id -boundaries for requests by ID. -Extending the .lookup_fn function in each plugin -that searches by ID for a check that returns non-zero -if the entry is out of the range and 0 if not. - -Resolves: https://pagure.io/SSSD/sssd/issue/3569 - -Reviewed-by: Jakub Hrozek -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 2af80640f18966d65cf82106059ce3c060df93bf) ---- - src/responder/common/cache_req/cache_req.c | 1 + - src/responder/common/cache_req/cache_req_private.h | 3 + - src/responder/common/cache_req/cache_req_search.c | 5 + - .../common/cache_req/plugins/cache_req_common.c | 11 ++ - .../cache_req/plugins/cache_req_group_by_id.c | 6 + - .../cache_req/plugins/cache_req_object_by_id.c | 6 + - .../cache_req/plugins/cache_req_user_by_id.c | 5 + - src/tests/cmocka/test_responder_cache_req.c | 127 +++++++++++++++++---- - src/util/util_errors.c | 1 + - src/util/util_errors.h | 1 + - 10 files changed, 141 insertions(+), 25 deletions(-) - -diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c -index ad9bc040dd999a205713141e6a1512e47b69c45e..134688b0f62c6546763d91468af3f54b73b6073a 100644 ---- a/src/responder/common/cache_req/cache_req.c -+++ b/src/responder/common/cache_req/cache_req.c -@@ -953,6 +953,7 @@ static void cache_req_search_domains_done(struct tevent_req *subreq) - goto done; - } - break; -+ case ERR_ID_OUTSIDE_RANGE: - case ENOENT: - if (state->check_next == false) { - /* Not found. */ -diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h -index 95f24c0e5b9ab1150591d308c7288c57fe478c5d..9538b9568ca7f77e377cfee67235c8a52ebbe454 100644 ---- a/src/responder/common/cache_req/cache_req_private.h -+++ b/src/responder/common/cache_req/cache_req_private.h -@@ -192,4 +192,7 @@ cache_reg_common_get_acct_domain_recv(TALLOC_CTX *mem_ctx, - struct tevent_req *subreq, - struct cache_req *cr, - char **_domain); -+ -+errno_t cache_req_idminmax_check(struct cache_req_data *data, -+ struct sss_domain_info *domain); - #endif /* _CACHE_REQ_PRIVATE_H_ */ -diff --git a/src/responder/common/cache_req/cache_req_search.c b/src/responder/common/cache_req/cache_req_search.c -index 3365962d473b0982945de2541e44ba86b43a0db5..7423feb6305df87d368bcc10ba28b9b29d57ecf0 100644 ---- a/src/responder/common/cache_req/cache_req_search.c -+++ b/src/responder/common/cache_req/cache_req_search.c -@@ -203,6 +203,11 @@ static errno_t cache_req_search_cache(TALLOC_CTX *mem_ctx, - - *_result = result; - break; -+ case ERR_ID_OUTSIDE_RANGE: -+ CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, -+ "ID [%s] was filtered out\n", -+ cr->debugobj); -+ break; - case ENOENT: - CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, cr, - "Object [%s] was not found in cache\n", -diff --git a/src/responder/common/cache_req/plugins/cache_req_common.c b/src/responder/common/cache_req/plugins/cache_req_common.c -index 408c91949ceb3ecaf743f270f58f4e3fcfc3ccb1..bb11eaa86a8bca3f9d15afe48dab9921319d184e 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_common.c -+++ b/src/responder/common/cache_req/plugins/cache_req_common.c -@@ -26,6 +26,17 @@ - #include "providers/data_provider.h" - #include "responder/common/cache_req/cache_req_plugin.h" - -+errno_t cache_req_idminmax_check(struct cache_req_data *data, -+ struct sss_domain_info *domain) -+{ -+ if (((domain->id_min != 0) && (data->id < domain->id_min)) || -+ ((domain->id_max != 0) && (data->id > domain->id_max))) { -+ DEBUG(SSSDBG_FUNC_DATA, "id exceeds min/max boundaries\n"); -+ return ERR_ID_OUTSIDE_RANGE; -+ } -+ return EOK; -+} -+ - static struct ldb_message * - cache_req_well_known_sid_msg(TALLOC_CTX *mem_ctx, - const char *sid, -diff --git a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c -index ce84b1b4458b447ff6b4b036c6e8fe8f4d7758c8..d178283c33c84e277b83772d04973aa6069af967 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_group_by_id.c -+++ b/src/responder/common/cache_req/plugins/cache_req_group_by_id.c -@@ -81,6 +81,12 @@ cache_req_group_by_id_lookup(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - struct ldb_result **_result) - { -+ errno_t ret; -+ -+ ret = cache_req_idminmax_check(data, domain); -+ if (ret != EOK) { -+ return ret; -+ } - return sysdb_getgrgid_with_views(mem_ctx, domain, data->id, _result); - } - -diff --git a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c -index 1327b480c1b1b68f9826fa229c9b001f2d92b79b..be9488d298885320139ccfcd3c59a83ff088e77d 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_object_by_id.c -+++ b/src/responder/common/cache_req/plugins/cache_req_object_by_id.c -@@ -110,6 +110,12 @@ cache_req_object_by_id_lookup(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - struct ldb_result **_result) - { -+ errno_t ret; -+ -+ ret = cache_req_idminmax_check(data, domain); -+ if (ret != EOK) { -+ return ret; -+ } - return sysdb_search_object_by_id(mem_ctx, domain, data->id, - data->attrs, _result); - } -diff --git a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c -index 656fa41af5f39f68c64e241aa97c4eaf3ec57395..151c3e17acf6ef0d958d5a73a36e1c93b9e7a9a9 100644 ---- a/src/responder/common/cache_req/plugins/cache_req_user_by_id.c -+++ b/src/responder/common/cache_req/plugins/cache_req_user_by_id.c -@@ -81,6 +81,11 @@ cache_req_user_by_id_lookup(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - struct ldb_result **_result) - { -+ errno_t ret; -+ ret = cache_req_idminmax_check(data, domain); -+ if (ret != EOK) { -+ return ret; -+ } - return sysdb_getpwuid_with_views(mem_ctx, domain, data->id, _result); - } - -diff --git a/src/tests/cmocka/test_responder_cache_req.c b/src/tests/cmocka/test_responder_cache_req.c -index 0ee0070d0c9fbb89020f522b2f7613f1076a8cbb..5f50b27a5ee846c9ccf71e1e661359a07c2e02e8 100644 ---- a/src/tests/cmocka/test_responder_cache_req.c -+++ b/src/tests/cmocka/test_responder_cache_req.c -@@ -59,6 +59,11 @@ struct test_group { - test_single_domain_setup, \ - test_single_domain_teardown) - -+#define new_single_domain_id_limit_test(test) \ -+ cmocka_unit_test_setup_teardown(test_ ## test, \ -+ test_single_domain_id_limits_setup, \ -+ test_single_domain_teardown) -+ - #define new_multi_domain_test(test) \ - cmocka_unit_test_setup_teardown(test_ ## test, \ - test_multi_domain_setup, \ -@@ -521,33 +526,39 @@ __wrap_sss_dp_get_account_send(TALLOC_CTX *mem_ctx, - return test_req_succeed_send(mem_ctx, rctx->ev); - } - -+static int test_single_domain_setup_common(void **state, -+ struct sss_test_conf_param *params) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ errno_t ret; -+ -+ assert_true(leak_check_setup()); -+ -+ test_dom_suite_setup(TESTS_PATH); -+ -+ test_ctx = talloc_zero(global_talloc_context, struct cache_req_test_ctx); -+ assert_non_null(test_ctx); -+ *state = test_ctx; -+ -+ test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, -+ TEST_DOM_NAME, TEST_ID_PROVIDER, params); -+ assert_non_null(test_ctx->tctx); -+ -+ test_ctx->rctx = mock_rctx(test_ctx, test_ctx->tctx->ev, -+ test_ctx->tctx->dom, NULL); -+ assert_non_null(test_ctx->rctx); -+ -+ ret = sss_ncache_init(test_ctx, 10, 0, &test_ctx->ncache); -+ assert_int_equal(ret, EOK); -+ -+ check_leaks_push(test_ctx); -+ -+ return 0; -+} -+ - static int test_single_domain_setup(void **state) - { -- struct cache_req_test_ctx *test_ctx = NULL; -- errno_t ret; -- -- assert_true(leak_check_setup()); -- -- test_dom_suite_setup(TESTS_PATH); -- -- test_ctx = talloc_zero(global_talloc_context, struct cache_req_test_ctx); -- assert_non_null(test_ctx); -- *state = test_ctx; -- -- test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, -- TEST_DOM_NAME, TEST_ID_PROVIDER, NULL); -- assert_non_null(test_ctx->tctx); -- -- test_ctx->rctx = mock_rctx(test_ctx, test_ctx->tctx->ev, -- test_ctx->tctx->dom, NULL); -- assert_non_null(test_ctx->rctx); -- -- ret = sss_ncache_init(test_ctx, 10, 0, &test_ctx->ncache); -- assert_int_equal(ret, EOK); -- -- check_leaks_push(test_ctx); -- -- return 0; -+ return test_single_domain_setup_common(state, NULL); - } - - static int test_single_domain_teardown(void **state) -@@ -565,6 +576,16 @@ static int test_single_domain_teardown(void **state) - return 0; - } - -+static int test_single_domain_id_limits_setup(void **state) -+{ -+ struct sss_test_conf_param params[] = { -+ { "min_id", "100" }, -+ { "max_id", "10000" }, -+ { NULL, NULL }, /* Sentinel */ -+ }; -+ return test_single_domain_setup_common(state, params); -+} -+ - static int test_multi_domain_setup(void **state) - { - struct cache_req_test_ctx *test_ctx = NULL; -@@ -596,6 +617,32 @@ static int test_multi_domain_setup(void **state) - return 0; - } - -+void test_user_by_id_below_id_range(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Test. */ -+ run_cache_req(test_ctx, cache_req_user_by_id_send, -+ cache_req_user_by_id_test_done, test_ctx->tctx->dom, -+ 0, 10, ENOENT); -+ assert_false(test_ctx->dp_called); -+} -+ -+void test_user_by_id_above_id_range(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Test. */ -+ run_cache_req(test_ctx, cache_req_user_by_id_send, -+ cache_req_user_by_id_test_done, test_ctx->tctx->dom, -+ 0, 100000, ENOENT); -+ assert_false(test_ctx->dp_called); -+} -+ - static int test_multi_domain_teardown(void **state) - { - struct cache_req_test_ctx *test_ctx; -@@ -1332,6 +1379,32 @@ void test_user_by_id_sub_domains_locator_missing_found(void **state) - talloc_free(tmp_ctx); - } - -+void test_group_by_id_below_id_range(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Test. */ -+ run_cache_req(test_ctx, cache_req_group_by_id_send, -+ cache_req_group_by_id_test_done, test_ctx->tctx->dom, -+ 0, 10, ENOENT); -+ assert_false(test_ctx->dp_called); -+} -+ -+void test_group_by_id_above_id_range(void **state) -+{ -+ struct cache_req_test_ctx *test_ctx = NULL; -+ -+ test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); -+ -+ /* Test. */ -+ run_cache_req(test_ctx, cache_req_group_by_id_send, -+ cache_req_group_by_id_test_done, test_ctx->tctx->dom, -+ 0, 100000, ENOENT); -+ assert_false(test_ctx->dp_called); -+} -+ - void test_user_by_id_sub_domains_locator_missing_notfound(void **state) - { - struct cache_req_test_ctx *test_ctx = NULL; -@@ -3874,6 +3947,8 @@ int main(int argc, const char *argv[]) - new_single_domain_test(user_by_id_missing_notfound), - new_multi_domain_test(user_by_id_multiple_domains_found), - new_multi_domain_test(user_by_id_multiple_domains_notfound), -+ new_single_domain_id_limit_test(user_by_id_below_id_range), -+ new_single_domain_id_limit_test(user_by_id_above_id_range), - - new_single_domain_test(group_by_name_cache_valid), - new_single_domain_test(group_by_name_cache_expired), -@@ -3884,6 +3959,8 @@ int main(int argc, const char *argv[]) - new_multi_domain_test(group_by_name_multiple_domains_found), - new_multi_domain_test(group_by_name_multiple_domains_notfound), - new_multi_domain_test(group_by_name_multiple_domains_parse), -+ new_single_domain_id_limit_test(group_by_id_below_id_range), -+ new_single_domain_id_limit_test(group_by_id_above_id_range), - - new_single_domain_test(group_by_id_cache_valid), - new_single_domain_test(group_by_id_cache_expired), -diff --git a/src/util/util_errors.c b/src/util/util_errors.c -index 06c620b40aaa00d6ce58ace3a28449ffbdf8da88..39ce3d7dcf4af4c489a0a9b7768668497cb84ba5 100644 ---- a/src/util/util_errors.c -+++ b/src/util/util_errors.c -@@ -117,6 +117,7 @@ struct err_string error_to_str[] = { - { "Unable to resolve host" }, /* ERR_UNABLE_TO_RESOLVE_HOST */ - { "GetAccountDomain() not supported" }, /* ERR_GET_ACCT_DOM_NOT_SUPPORTED */ - { "The last GetAccountDomain() result is still valid" }, /* ERR_GET_ACCT_DOM_CACHED */ -+ { "ID is outside the allowed range" }, /* ERR_ID_OUTSIDE_RANGE */ - { "ERR_LAST" } /* ERR_LAST */ - }; - -diff --git a/src/util/util_errors.h b/src/util/util_errors.h -index bebd6e198fc0077891a602f80182a993ce3f789b..621a3b116edac45960190684055bcd0692135957 100644 ---- a/src/util/util_errors.h -+++ b/src/util/util_errors.h -@@ -139,6 +139,7 @@ enum sssd_errors { - ERR_UNABLE_TO_RESOLVE_HOST, - ERR_GET_ACCT_DOM_NOT_SUPPORTED, - ERR_GET_ACCT_DOM_CACHED, -+ ERR_ID_OUTSIDE_RANGE, - ERR_LAST /* ALWAYS LAST */ - }; - --- -2.14.3 - diff --git a/SOURCES/0088-Revert-p11_child-make-sure-OCSP-checks-are-done.patch b/SOURCES/0088-Revert-p11_child-make-sure-OCSP-checks-are-done.patch deleted file mode 100644 index 18b947b..0000000 --- a/SOURCES/0088-Revert-p11_child-make-sure-OCSP-checks-are-done.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 424aa780fbb645214b92cf09f23c905b93bdf267 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 12 Dec 2017 15:28:27 +0100 -Subject: [PATCH 88/89] Revert "p11_child: make sure OCSP checks are done" -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This reverts commit 2297cc7d6cd5c38a7d64027165e4e82ca497f418. - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit c221b5fb4d3fc511cebcae2f042e43fb1c577bc7) ---- - src/p11_child/p11_child_nss.c | 17 ----------------- - 1 file changed, 17 deletions(-) - -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index bf533f3efe4d680f4c6dbd10a0d2c5a5da371c67..21c508eb1b1b68b3606d0a5eed36573b01f27a19 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -338,23 +338,6 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - PR_GetError(), PORT_ErrorToString(PR_GetError())); - continue; - } -- -- /* with 'certificateUsageCheckAllUsages' set -- * CERT_VerifyCertificateNow() does not do OCSP so it must be done -- * explicitly */ -- if (cert_verify_opts->do_ocsp) { -- rv = CERT_CheckOCSPStatus(handle, cert_list_node->cert, -- PR_Now(), NULL); -- if (rv != SECSuccess) { -- DEBUG(SSSDBG_OP_FAILURE, -- "Certificate [%s][%s] failed OCSP check [%d][%s], " -- "skipping.\n", -- cert_list_node->cert->nickname, -- cert_list_node->cert->subjectName, -- PR_GetError(), PORT_ErrorToString(PR_GetError())); -- continue; -- } -- } - } - - if (key_id_in != NULL) { --- -2.14.3 - diff --git a/SOURCES/0089-p11_child-properly-check-results-of-CERT_VerifyCerti.patch b/SOURCES/0089-p11_child-properly-check-results-of-CERT_VerifyCerti.patch deleted file mode 100644 index 85e867a..0000000 --- a/SOURCES/0089-p11_child-properly-check-results-of-CERT_VerifyCerti.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 56402a2b350ebdcfd49685a5a3c0fd42131b2196 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 12 Dec 2017 15:24:57 +0100 -Subject: [PATCH 89/89] p11_child: properly check results of - CERT_VerifyCertificateNow -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With certificateUsageCheckAllUsages not only the return code of -CERT_VerifyCertificateNow() should be checked but also the usages for -which the certificate was verified. The usages checked here will all -involve CA signature checks and OCSP checks if OCSP is enabled. - -Related to https://pagure.io/SSSD/sssd/issue/3560 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 787ba9c882f1d7ff9ea4f2745e779c5fb04dfafc) ---- - src/p11_child/p11_child_nss.c | 14 ++++++++++++-- - 1 file changed, 12 insertions(+), 2 deletions(-) - -diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c -index 21c508eb1b1b68b3606d0a5eed36573b01f27a19..cb894280c18fcbd59c5499e36d30f3ba305c0ea2 100644 ---- a/src/p11_child/p11_child_nss.c -+++ b/src/p11_child/p11_child_nss.c -@@ -45,6 +45,15 @@ - #include "util/crypto/sss_crypto.h" - #include "util/cert.h" - -+#define EXP_USAGES ( certificateUsageSSLClient \ -+ | certificateUsageSSLServer \ -+ | certificateUsageSSLServerWithStepUp \ -+ | certificateUsageEmailSigner \ -+ | certificateUsageEmailRecipient \ -+ | certificateUsageObjectSigner \ -+ | certificateUsageStatusResponder \ -+ | certificateUsageSSLCA ) -+ - enum op_mode { - OP_NONE, - OP_AUTH, -@@ -136,6 +145,7 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - char *cert_b64 = NULL; - char *multi = NULL; - PRCList *node; -+ SECCertificateUsage returned_usage = 0; - - nss_ctx = NSS_InitContext(nss_db, "", "", SECMOD_DB, ¶meters, flags); - if (nss_ctx == NULL) { -@@ -329,8 +339,8 @@ int do_work(TALLOC_CTX *mem_ctx, const char *nss_db, - rv = CERT_VerifyCertificateNow(handle, cert_list_node->cert, - PR_TRUE, - certificateUsageCheckAllUsages, -- NULL, NULL); -- if (rv != SECSuccess) { -+ NULL, &returned_usage); -+ if (rv != SECSuccess || ((returned_usage & EXP_USAGES) == 0)) { - DEBUG(SSSDBG_OP_FAILURE, - "Certificate [%s][%s] not valid [%d][%s], skipping.\n", - cert_list_node->cert->nickname, --- -2.14.3 - diff --git a/SOURCES/0090-ifp-use-realloc-in-ifp_list_ctx_remaining_capacity.patch b/SOURCES/0090-ifp-use-realloc-in-ifp_list_ctx_remaining_capacity.patch deleted file mode 100644 index c731709..0000000 --- a/SOURCES/0090-ifp-use-realloc-in-ifp_list_ctx_remaining_capacity.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 674c5c3ba930a8546371ea8e138ff20a15090431 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 15 Dec 2017 12:09:06 +0100 -Subject: [PATCH 90/90] ifp: use realloc in ifp_list_ctx_remaining_capacity() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -ifp_list_ctx_remaining_capacity() might be called multiple times if -results from multiple domains are added to the result list. - -The current use of talloc_zero_array() which was introduced with commit -b0b9222 will override results which are already in the list. This causes -a regression since it worked before. - -This patch replaces it with talloc_realloc(). - -Resolves https://pagure.io/SSSD/sssd/issue/3608 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 510ac193900a7bb9dfae10c0ca4607c224b265af) ---- - src/responder/ifp/ifp_private.h | 1 + - src/responder/ifp/ifpsrv_util.c | 16 ++++++++++++---- - 2 files changed, 13 insertions(+), 4 deletions(-) - -diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h -index 13455bbf70860fb6dbfa3bb65fe3bd565d53257d..b406e7f5bab3e0dbc9696a5ab58e46b6ee7839eb 100644 ---- a/src/responder/ifp/ifp_private.h -+++ b/src/responder/ifp/ifp_private.h -@@ -93,6 +93,7 @@ struct ifp_list_ctx { - struct ifp_ctx *ctx; - - const char **paths; -+ size_t paths_max; - size_t path_count; - }; - -diff --git a/src/responder/ifp/ifpsrv_util.c b/src/responder/ifp/ifpsrv_util.c -index 1df646339526186e862dcd09cddd971b77c20a8b..da4ab06796a99c930b7a4ad21ca408814f8b4c49 100644 ---- a/src/responder/ifp/ifpsrv_util.c -+++ b/src/responder/ifp/ifpsrv_util.c -@@ -372,7 +372,9 @@ struct ifp_list_ctx *ifp_list_ctx_new(struct sbus_request *sbus_req, - list_ctx->ctx = ctx; - list_ctx->dom = ctx->rctx->domains; - list_ctx->filter = filter; -- list_ctx->paths = talloc_zero_array(list_ctx, const char *, 1); -+ list_ctx->paths_max = 1; -+ list_ctx->paths = talloc_zero_array(list_ctx, const char *, -+ list_ctx->paths_max); - if (list_ctx->paths == NULL) { - talloc_free(list_ctx); - return NULL; -@@ -387,6 +389,7 @@ errno_t ifp_list_ctx_remaining_capacity(struct ifp_list_ctx *list_ctx, - { - size_t capacity = list_ctx->limit - list_ctx->path_count; - errno_t ret; -+ size_t c; - - if (list_ctx->limit == 0) { - capacity = entries; -@@ -396,19 +399,24 @@ errno_t ifp_list_ctx_remaining_capacity(struct ifp_list_ctx *list_ctx, - if (capacity < entries) { - DEBUG(SSSDBG_MINOR_FAILURE, - "IFP list request has limit of %"PRIu32" entries but back end " -- "returned %zu entries\n", list_ctx->limit, entries); -+ "returned %zu entries\n", list_ctx->limit, -+ list_ctx->path_count + entries); - } else { - capacity = entries; - } - - immediately: -- talloc_zfree(list_ctx->paths); -- list_ctx->paths = talloc_zero_array(list_ctx, const char *, capacity); -+ list_ctx->paths_max = list_ctx->path_count + capacity; -+ list_ctx->paths = talloc_realloc(list_ctx, list_ctx->paths, const char *, -+ list_ctx->paths_max); - if (list_ctx->paths == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero_array() failed\n"); - ret = ENOMEM; - goto done; - } -+ for (c = list_ctx->path_count; c < list_ctx->paths_max; c++) { -+ list_ctx->paths[c] = NULL; -+ } - - *_capacity = capacity; - ret = EOK; --- -2.14.3 - diff --git a/SOURCES/0091-IPA-Delay-the-first-periodic-refresh-of-trusted-doma.patch b/SOURCES/0091-IPA-Delay-the-first-periodic-refresh-of-trusted-doma.patch deleted file mode 100644 index c828f38..0000000 --- a/SOURCES/0091-IPA-Delay-the-first-periodic-refresh-of-trusted-doma.patch +++ /dev/null @@ -1,64 +0,0 @@ -From a2f7322b9d8e47c0c93463d9fe1f37dc869799df Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 8 Jan 2018 18:30:57 +0100 -Subject: [PATCH 91/96] IPA: Delay the first periodic refresh of trusted - domains -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When the IPA subdomains code is initialized, the responders send a request -to fetch subdomains. This request first stores the list of trusted domains -to the cache and then runs the ipa-getkeytab helper. - -At the same time, the periodical task to update the subdomains is also -started. The task founds out that all the trusted domains are already known -and finishes the request, which replies to the Data Provider requests as -well even while the ipa-getkeytab request is still running. - -This unblocks requests from the responders, which try to connect to the AD -DCs even before the keytab is available, which switches the SSSD status to -offline. - -This patch simply delays the first periodic task in the IPA subdomains code -by 10 minutes, thus mitigating the startup race. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3601 - -Reviewed-by: Sumit Bose -Reviewed-by: Michal Židek -Reviewed-by: Pavel Březina -(cherry picked from commit 261a84355d9d033ca03f46727dbc2cf4921f154e) ---- - src/providers/ipa/ipa_subdomains.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c -index 3d3341a3eff5e55ae0c6fa5ad40603adc609e692..7d2cf80c8137a0428880c5474d4d94ca3ad1a5d4 100644 ---- a/src/providers/ipa/ipa_subdomains.c -+++ b/src/providers/ipa/ipa_subdomains.c -@@ -2379,6 +2379,11 @@ errno_t ipa_subdomains_init(TALLOC_CTX *mem_ctx, - struct ipa_options *ipa_options; - time_t period; - errno_t ret; -+ /* Delay the first ptask that refreshes the trusted domains so that a race between -+ * the first responder-induced request and the ptask doesn't cause issues, see -+ * also upstream ticket #3601 -+ */ -+ const time_t ptask_first_delay = 600; - - ipa_options = ipa_id_ctx->ipa_options; - -@@ -2401,7 +2406,7 @@ errno_t ipa_subdomains_init(TALLOC_CTX *mem_ctx, - struct ipa_subdomains_ctx, struct dp_subdomains_data, struct dp_reply_std); - - period = be_ctx->domain->subdomain_refresh_interval; -- ret = be_ptask_create(sd_ctx, be_ctx, period, 0, 0, 0, period, -+ ret = be_ptask_create(sd_ctx, be_ctx, period, ptask_first_delay, 0, 0, period, - BE_PTASK_OFFLINE_DISABLE, 0, - ipa_subdomains_ptask_send, ipa_subdomains_ptask_recv, sd_ctx, - "Subdomains Refresh", NULL); --- -2.14.3 - diff --git a/SOURCES/0092-sysdb-add-userMappedCertificate-to-the-index.patch b/SOURCES/0092-sysdb-add-userMappedCertificate-to-the-index.patch deleted file mode 100644 index 346c8b5..0000000 --- a/SOURCES/0092-sysdb-add-userMappedCertificate-to-the-index.patch +++ /dev/null @@ -1,55 +0,0 @@ -From 57a83eb8657a125d203a335b052d965c7a3b15de Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 8 Jan 2018 18:22:17 +0100 -Subject: [PATCH 92/96] sysdb: add userMappedCertificate to the index -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Related to https://pagure.io/SSSD/sssd/issue/3503 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 5b78fff78bb44d1af5420db23b02210f755f5f17) ---- - src/db/sysdb_private.h | 1 + - src/db/sysdb_upgrade.c | 12 ++++++++++++ - 2 files changed, 13 insertions(+) - -diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h -index cac06ba46da23080d1ab661502d0792bd37b9291..c0a8e29ab9578acb27cf8d1db049c4260904fdda 100644 ---- a/src/db/sysdb_private.h -+++ b/src/db/sysdb_private.h -@@ -78,6 +78,7 @@ - "@IDXATTR: canonicalUserPrincipalName\n" \ - "@IDXATTR: uniqueID\n" \ - "@IDXATTR: mail\n" \ -+ "@IDXATTR: userMappedCertificate\n" \ - "\n" \ - "dn: @MODULES\n" \ - "@LIST: asq,memberof\n" \ -diff --git a/src/db/sysdb_upgrade.c b/src/db/sysdb_upgrade.c -index bc157a24664239bc1255e49a1825243a07acc90f..46df971e98f73dc28bc6764a478f13d871515124 100644 ---- a/src/db/sysdb_upgrade.c -+++ b/src/db/sysdb_upgrade.c -@@ -2475,6 +2475,18 @@ int sysdb_upgrade_19(struct sysdb_ctx *sysdb, const char **ver) - goto done; - } - -+ ret = ldb_msg_add_empty(msg, "@IDXATTR", LDB_FLAG_MOD_ADD, NULL); -+ if (ret != LDB_SUCCESS) { -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ ret = ldb_msg_add_string(msg, "@IDXATTR", SYSDB_USER_MAPPED_CERT); -+ if (ret != LDB_SUCCESS) { -+ ret = ENOMEM; -+ goto done; -+ } -+ - ret = ldb_modify(sysdb->ldb, msg); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); --- -2.14.3 - diff --git a/SOURCES/0093-AD-Inherit-the-MPG-setting-from-the-main-domain.patch b/SOURCES/0093-AD-Inherit-the-MPG-setting-from-the-main-domain.patch deleted file mode 100644 index 875f5fb..0000000 --- a/SOURCES/0093-AD-Inherit-the-MPG-setting-from-the-main-domain.patch +++ /dev/null @@ -1,48 +0,0 @@ -From e67f94d854ef125626294771473a1204726eeba4 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 15 Jan 2018 22:11:24 +0100 -Subject: [PATCH 93/96] AD: Inherit the MPG setting from the main domain -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If the auto_private_groups option was set in the domain section for -direct integration, it only had an effect on the joined domain, not any -of the subdomains, so requesting a user from the child domain would look -like this: - $ id childuser@child.win.trust.test - uid=30000(childuser@child.win.trust.test) gid=40000(usergroup@child.win.trust.test) groups=40000(usergroup@child.win.trust.test) -The expected result, visible after this patch is: - $ id childuser@child.win.trust.test - uid=30000(childuser@child.win.trust.test) gid=30000(childuser@child.win.trust.test) groups=30000(childuser@child.win.trust.test),40000(usergroup@child.win.trust.test) - -Resolves: -https://pagure.io/SSSD/sssd/issue/3613 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 29ebf45f96b13590ae76a19c7c16c53f172e4ae4) ---- - src/providers/ad/ad_subdomains.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c -index 3fb9b950f171d85817cce35ac92ad7c4974ccb68..1b9483a5dce937d6acdd813486a1e8c18210d35f 100644 ---- a/src/providers/ad/ad_subdomains.c -+++ b/src/providers/ad/ad_subdomains.c -@@ -391,6 +391,13 @@ ad_subdom_store(struct sdap_idmap_ctx *idmap_ctx, - } - - mpg = sdap_idmap_domain_has_algorithmic_mapping(idmap_ctx, name, sid_str); -+ if (mpg == false) { -+ /* Domains that use the POSIX attributes set by the admin must -+ * inherit the MPG setting from the parent domain so that the -+ * auto_private_groups options works for trusted domains as well -+ */ -+ mpg = domain->mpg; -+ } - - ret = sysdb_subdomain_store(domain->sysdb, name, realm, flat, sid_str, - mpg, enumerate, domain->forest, 0, NULL); --- -2.14.3 - diff --git a/SOURCES/0094-SDAP-skip-builtin-AD-groups-in-sdap_save_grpmem.patch b/SOURCES/0094-SDAP-skip-builtin-AD-groups-in-sdap_save_grpmem.patch deleted file mode 100644 index 72c1f2c..0000000 --- a/SOURCES/0094-SDAP-skip-builtin-AD-groups-in-sdap_save_grpmem.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 75da39f57ba0223be9bd9906cd3ed902623aed10 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Mon, 18 Dec 2017 20:30:04 +0100 -Subject: [PATCH 94/96] SDAP: skip builtin AD groups in sdap_save_grpmem() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -While processing group memberships SSSD might accidentally save builtin -or other well known AD groups. With this patch those groups are skipped -similar as e.g. in sdap_save_group(). - -Resolves: -https://pagure.io/SSSD/sssd/issue/3610 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit c36a66b7fb77cff29400c751b363a342923e122e) ---- - src/providers/ldap/sdap_async_groups.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c -index b1cfb7e4a4c054e5d365da5fca65da27c9ef5461..bbe6f1386eadbe4eb7b47bea9e5a6bb8ff4ee8eb 100644 ---- a/src/providers/ldap/sdap_async_groups.c -+++ b/src/providers/ldap/sdap_async_groups.c -@@ -880,6 +880,8 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx, - int ret; - const char *remove_attrs[] = {SYSDB_MEMBER, SYSDB_ORIG_MEMBER, SYSDB_GHOST, - NULL}; -+ const char *check_dom; -+ const char *check_name; - - if (dom->ignore_group_members) { - DEBUG(SSSDBG_CRIT_FAILURE, -@@ -905,6 +907,15 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx, - group_dom = sss_get_domain_by_sid_ldap_fallback(get_domains_head(dom), - group_sid); - if (group_dom == NULL) { -+ ret = well_known_sid_to_name(group_sid, &check_dom, &check_name); -+ if (ret == EOK) { -+ DEBUG(SSSDBG_TRACE_FUNC, -+ "Skipping group with SID [%s][%s\\%s] which is " -+ "currently not handled by SSSD.\n", -+ group_sid, check_dom, check_name); -+ return EOK; -+ } -+ - DEBUG(SSSDBG_TRACE_FUNC, "SID [%s] does not belong to any known " - "domain, using [%s].\n", group_sid, - dom->name); --- -2.14.3 - diff --git a/SOURCES/0095-SYSDB-Read-the-ldb_message-from-loop-s-index-counter.patch b/SOURCES/0095-SYSDB-Read-the-ldb_message-from-loop-s-index-counter.patch deleted file mode 100644 index b0469ba..0000000 --- a/SOURCES/0095-SYSDB-Read-the-ldb_message-from-loop-s-index-counter.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 80e4aa68587d5a70bfd41f78f17902bf06b447a1 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 23 Jan 2018 11:11:14 +0100 -Subject: [PATCH 95/96] SYSDB: Read the ldb_message from loop's index counter - when reading subdomain UPNs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -There was a typo in code that read the UPN suffixes from the subdomain -ldb_message. As a result, the UPN suffixes from the first domain were -always consulted for all domains. - -Related to: -https://pagure.io/SSSD/sssd/issue/3431 - -Reviewed-by: Lukáš Slebodník -Reviewed-by: Sumit Bose -(cherry picked from commit a8a3fcbf6f75a7c2665e8bf503c186e07dfab333) ---- - src/db/sysdb_subdomains.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c -index 0dd05c24c963f12a28ef6f6b64dc40faa7fcc649..b0863b7935b060cb545197005c84f51efbc2d49c 100644 ---- a/src/db/sysdb_subdomains.c -+++ b/src/db/sysdb_subdomains.c -@@ -386,7 +386,7 @@ errno_t sysdb_update_subdomains(struct sss_domain_info *domain, - SYSDB_SUBDOMAIN_FOREST, NULL); - - upn_suffixes = NULL; -- tmp_el = ldb_msg_find_element(res->msgs[0], SYSDB_UPN_SUFFIXES); -+ tmp_el = ldb_msg_find_element(res->msgs[i], SYSDB_UPN_SUFFIXES); - if (tmp_el != NULL) { - upn_suffixes = sss_ldb_el_to_string_list(tmp_ctx, tmp_el); - if (upn_suffixes == NULL) { --- -2.14.3 - diff --git a/SOURCES/0096-nss-idmap-check-timed-muted-return-code.patch b/SOURCES/0096-nss-idmap-check-timed-muted-return-code.patch deleted file mode 100644 index 974484c..0000000 --- a/SOURCES/0096-nss-idmap-check-timed-muted-return-code.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 63c09393b926f0d00317a1ca1dc6c7c992c40f4e Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 16 Jan 2018 18:09:00 +0100 -Subject: [PATCH 96/96] nss-idmap: check timed muted return code - -Check return values and make sure the mutex is released in case of -errors. - -Related to https://pagure.io/SSSD/sssd/issue/2478 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 3e32cb2ad36a9dd2654c7f63469dc595f1bb8593) ---- - src/sss_client/idmap/common_ex.c | 2 ++ - src/sss_client/idmap/sss_nss_ex.c | 5 ++++- - src/sss_client/idmap/sss_nss_idmap.c | 5 ++++- - 3 files changed, 10 insertions(+), 2 deletions(-) - -diff --git a/src/sss_client/idmap/common_ex.c b/src/sss_client/idmap/common_ex.c -index 5efe9fabed7896ce674615472dbb256c4eae2144..e655bb864e063665cb56bcd3ff419e46c766478b 100644 ---- a/src/sss_client/idmap/common_ex.c -+++ b/src/sss_client/idmap/common_ex.c -@@ -83,6 +83,7 @@ int sss_nss_timedlock(unsigned int timeout_ms, int *time_left_ms) - if (ret == 0) { - ret = clock_gettime(CLOCK_REALTIME, &endtime); - if (ret != 0) { -+ sss_nss_unlock(); - return ret; - } - -@@ -92,6 +93,7 @@ int sss_nss_timedlock(unsigned int timeout_ms, int *time_left_ms) - TIMESPECSUB(&endtime, &starttime, &diff); - left = timeout_ms - TIMESPEC_TO_MS(&diff); - if (left <= 0) { -+ sss_nss_unlock(); - return EIO; - } else if (left > SSS_CLI_SOCKET_TIMEOUT) { - *time_left_ms = SSS_CLI_SOCKET_TIMEOUT; -diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c -index 861b1e1e92db4f7e6e8d74a812dc3c9220711773..af6a95180656b598bcb94c209dfa821cb0275f02 100644 ---- a/src/sss_client/idmap/sss_nss_ex.c -+++ b/src/sss_client/idmap/sss_nss_ex.c -@@ -202,7 +202,10 @@ int sss_get_ex(struct nss_input *inp, uint32_t flags, unsigned int timeout) - } - } - -- sss_nss_timedlock(timeout, &time_left); -+ ret = sss_nss_timedlock(timeout, &time_left); -+ if (ret != 0) { -+ return ret; -+ } - - if (!skip_mc && !skip_data) { - /* previous thread might already initialize entry in mmap cache */ -diff --git a/src/sss_client/idmap/sss_nss_idmap.c b/src/sss_client/idmap/sss_nss_idmap.c -index 6e7685d2b1d80956b6a6668e9bbb146abd9e86ed..cbf8c11f2870e3574c75fe109cb19268e8a0b56d 100644 ---- a/src/sss_client/idmap/sss_nss_idmap.c -+++ b/src/sss_client/idmap/sss_nss_idmap.c -@@ -257,7 +257,10 @@ static int sss_nss_getyyybyxxx(union input inp, enum sss_cli_command cmd, - if (timeout == NO_TIMEOUT) { - sss_nss_lock(); - } else { -- sss_nss_timedlock(timeout, &time_left); -+ ret = sss_nss_timedlock(timeout, &time_left); -+ if (ret != 0) { -+ return ret; -+ } - } - - nret = sss_nss_make_request_timeout(cmd, &rd, time_left, &repbuf, &replen, --- -2.14.3 - diff --git a/SOURCES/0097-DESKPROFILE-Add-checks-for-user-and-host-category.patch b/SOURCES/0097-DESKPROFILE-Add-checks-for-user-and-host-category.patch deleted file mode 100644 index 1199481..0000000 --- a/SOURCES/0097-DESKPROFILE-Add-checks-for-user-and-host-category.patch +++ /dev/null @@ -1,155 +0,0 @@ -From 2349423ad813e8a4fe090c283603b4cf18919662 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= -Date: Mon, 22 Jan 2018 00:02:43 +0100 -Subject: [PATCH 97/97] DESKPROFILE: Add checks for user and host category -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -freeipa-deskprofile-plugin can have both user and host category set as -"all" and when it happens, no users and groups or hosts or hostgroups -are going to be set. - -Let's treat this expected (but so far missed) situation on SSSD side. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3449 - -Signed-off-by: Fabiano Fidêncio - -Reviewed-by: Jakub Hrozek -(cherry picked from commit b72e444bc1cd2fe8d9617f09b446c678d4684fff) ---- - src/providers/ipa/ipa_deskprofile_rules_util.c | 100 ++++++++++++++++++++----- - 1 file changed, 82 insertions(+), 18 deletions(-) - -diff --git a/src/providers/ipa/ipa_deskprofile_rules_util.c b/src/providers/ipa/ipa_deskprofile_rules_util.c -index 53c433145666af00a994420ccd1a926b11937fc9..01b7d0527c2a15e0f4d2bdce1867ad0482fca7b0 100644 ---- a/src/providers/ipa/ipa_deskprofile_rules_util.c -+++ b/src/providers/ipa/ipa_deskprofile_rules_util.c -@@ -684,6 +684,8 @@ ipa_deskprofile_rules_save_rule_to_disk( - TALLOC_CTX *tmp_ctx; - const char *rule_name; - const char *data; -+ const char *hostcat; -+ const char *usercat; - char *shortname; - char *domainname; - char *base_dn; -@@ -722,6 +724,28 @@ ipa_deskprofile_rules_save_rule_to_disk( - goto done; - } - -+ ret = sysdb_attrs_get_string(rule, IPA_HOST_CATEGORY, &hostcat); -+ if (ret == ENOENT) { -+ hostcat = NULL; -+ } else if (ret != EOK) { -+ DEBUG(SSSDBG_TRACE_FUNC, -+ "Failed to get the Desktop Profile Rule host category for rule " -+ "\"%s\" [%d]: %s\n", -+ rule_name, ret, sss_strerror(ret)); -+ goto done; -+ } -+ -+ ret = sysdb_attrs_get_string(rule, IPA_USER_CATEGORY, &usercat); -+ if (ret == ENOENT) { -+ usercat = NULL; -+ } else if (ret != EOK) { -+ DEBUG(SSSDBG_TRACE_FUNC, -+ "Failed to get the Desktop Profile Rule user category for rule " -+ "\"%s\" [%d]: %s\n", -+ rule_name, ret, sss_strerror(ret)); -+ goto done; -+ } -+ - rule_prio = talloc_asprintf(tmp_ctx, "%06d", prio); - if (rule_prio == NULL) { - DEBUG(SSSDBG_CRIT_FAILURE, "Failed to allocate rule priority\n"); -@@ -753,26 +777,66 @@ ipa_deskprofile_rules_save_rule_to_disk( - goto done; - } - -- ret = ipa_deskprofile_rule_check_memberuser(tmp_ctx, domain, rule, -- rule_name, rule_prio, -- base_dn, username, -- &user_prio, &group_prio); -- if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "ipa_deskprofile_rule_check_memberuser() failed [%d]: %s\n", -- ret, sss_strerror(ret)); -- goto done; -+ if (usercat != NULL && strcasecmp(usercat, "all") == 0) { -+ user_prio = talloc_strdup(tmp_ctx, rule_prio); -+ if (user_prio == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to allocate the user priority " -+ "when user category is \"all\"\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ group_prio = talloc_strdup(tmp_ctx, rule_prio); -+ if (group_prio == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to allocate the group priority " -+ "when user category is \"all\"\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ } else { -+ ret = ipa_deskprofile_rule_check_memberuser(tmp_ctx, domain, rule, -+ rule_name, rule_prio, -+ base_dn, username, -+ &user_prio, &group_prio); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "ipa_deskprofile_rule_check_memberuser() failed [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ goto done; -+ } - } - -- ret = ipa_deskprofile_rule_check_memberhost(tmp_ctx, domain, rule, -- rule_name, rule_prio, -- base_dn, hostname, -- &host_prio, &hostgroup_prio); -- if (ret != EOK) { -- DEBUG(SSSDBG_CRIT_FAILURE, -- "ipa_deskprofile_rule_check_memberhost() failed [%d]: %s\n", -- ret, sss_strerror(ret)); -- goto done; -+ if (hostcat != NULL && strcasecmp(hostcat, "all") == 0) { -+ host_prio = talloc_strdup(tmp_ctx, rule_prio); -+ if (host_prio == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to allocate the host priority " -+ "when host category is \"all\"\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ -+ hostgroup_prio = talloc_strdup(tmp_ctx, rule_prio); -+ if (hostgroup_prio == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Failed to allocate the hostgroup priority " -+ "when host category is \"all\"\n"); -+ ret = ENOMEM; -+ goto done; -+ } -+ } else { -+ ret = ipa_deskprofile_rule_check_memberhost(tmp_ctx, domain, rule, -+ rule_name, rule_prio, -+ base_dn, hostname, -+ &host_prio, &hostgroup_prio); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "ipa_deskprofile_rule_check_memberhost() failed [%d]: %s\n", -+ ret, sss_strerror(ret)); -+ goto done; -+ } - } - - ret = ipa_deskprofile_get_normalized_rule_name(mem_ctx, rule_name, --- -2.14.3 - diff --git a/SOURCES/0098-SELINUX-Check-if-SELinux-is-managed-in-selinux_child.patch b/SOURCES/0098-SELINUX-Check-if-SELinux-is-managed-in-selinux_child.patch deleted file mode 100644 index c0912b0..0000000 --- a/SOURCES/0098-SELINUX-Check-if-SELinux-is-managed-in-selinux_child.patch +++ /dev/null @@ -1,203 +0,0 @@ -From ae37ee533a791e038aab47683278fced2bc0b687 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michal=20=C5=BDidek?= -Date: Thu, 1 Feb 2018 11:34:21 +0100 -Subject: [PATCH 98/99] SELINUX: Check if SELinux is managed in selinux_child -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -If SELinux policy is not managed at all, don't call any SELinux user -handling functions and instead return that no update is needed. - -Pair-Programmed-With: Jakub Hrozek -Reviewed-by: Lukáš Slebodník -Reviewed-by: Fabiano Fidêncio - -Resolves: -https://pagure.io/SSSD/sssd/issue/3618 -(cherry picked from commit 450b472a68abf442479755c7916c757907b35ea5) ---- - src/providers/ipa/selinux_child.c | 3 +- - src/util/sss_semanage.c | 82 +++++++++++++++++++++++++++++++-------- - src/util/util.h | 3 ++ - 3 files changed, 70 insertions(+), 18 deletions(-) - -diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c -index a7e20f715626d0f3ecef7cc06f3de5d44b6a15c1..c659976e80cb7317671da52fe4777ee821589e36 100644 ---- a/src/providers/ipa/selinux_child.c -+++ b/src/providers/ipa/selinux_child.c -@@ -27,7 +27,6 @@ - #include - #include - #include --#include - - #include "util/util.h" - #include "util/child_common.h" -@@ -173,7 +172,7 @@ static bool seuser_needs_update(struct input_buffer *ibuf) - char *db_mls_range = NULL; - errno_t ret; - -- ret = getseuserbyname(ibuf->username, &db_seuser, &db_mls_range); -+ ret = sss_get_seuser(ibuf->username, &db_seuser, &db_mls_range); - DEBUG(SSSDBG_TRACE_INTERNAL, - "getseuserbyname: ret: %d seuser: %s mls: %s\n", - ret, db_seuser ? db_seuser : "unknown", -diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c -index 37278cc986a1ea49dc2218a635d52b9d54ca089d..25b6bcdad2ad7e7ac710497f13d6a6e22360b0dd 100644 ---- a/src/util/sss_semanage.c -+++ b/src/util/sss_semanage.c -@@ -22,8 +22,9 @@ - #include "config.h" - - #include --#ifdef HAVE_SEMANAGE -+#if defined(HAVE_SEMANAGE) && defined(HAVE_SELINUX) - #include -+#include - #endif - - #include "util/util.h" -@@ -32,7 +33,7 @@ - #define DEFAULT_SERANGE "s0" - #endif - --#ifdef HAVE_SEMANAGE -+#if defined(HAVE_SEMANAGE) && defined(HAVE_SELINUX) - /* turn libselinux messages into SSSD DEBUG() calls */ - static void sss_semanage_error_callback(void *varg, - semanage_handle_t *handle, -@@ -73,33 +74,47 @@ static void sss_semanage_close(semanage_handle_t *handle) - semanage_handle_destroy(handle); - } - --static int sss_semanage_init(semanage_handle_t **_handle) -+static int sss_is_selinux_managed(semanage_handle_t *handle) - { - int ret; -- semanage_handle_t *handle = NULL; - -- handle = semanage_handle_create(); -- if (!handle) { -- DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n"); -- ret = EIO; -- goto done; -+ if (handle == NULL) { -+ return EINVAL; - } - -- semanage_msg_set_callback(handle, -- sss_semanage_error_callback, -- NULL); -- - ret = semanage_is_managed(handle); - if (ret == 0) { - DEBUG(SSSDBG_TRACE_FUNC, "SELinux policy not managed via libsemanage\n"); -- ret = ERR_SELINUX_NOT_MANAGED; -- goto done; -+ return ERR_SELINUX_NOT_MANAGED; - } else if (ret == -1) { - DEBUG(SSSDBG_CRIT_FAILURE, "Call to semanage_is_managed failed\n"); -+ return EIO; -+ } -+ -+ return EOK; -+} -+ -+static int sss_semanage_init(semanage_handle_t **_handle) -+{ -+ int ret; -+ semanage_handle_t *handle = NULL; -+ -+ handle = semanage_handle_create(); -+ if (!handle) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n"); - ret = EIO; - goto done; - } - -+ semanage_msg_set_callback(handle, -+ sss_semanage_error_callback, -+ NULL); -+ -+ ret = sss_is_selinux_managed(handle); -+ if (ret != EOK) { -+ goto done; -+ } -+ - ret = semanage_access_check(handle); - if (ret < SEMANAGE_CAN_READ) { - DEBUG(SSSDBG_CRIT_FAILURE, "Cannot read SELinux policy store\n"); -@@ -229,6 +244,34 @@ done: - return ret; - } - -+int sss_get_seuser(const char *linuxuser, -+ char **selinuxuser, -+ char **level) -+{ -+ int ret; -+ semanage_handle_t *handle; -+ -+ handle = semanage_handle_create(); -+ if (handle == NULL) { -+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create SELinux management handle\n"); -+ return EIO; -+ } -+ -+ semanage_msg_set_callback(handle, -+ sss_semanage_error_callback, -+ NULL); -+ -+ /* We only needed the handle for this call. Close the handle right -+ * after it */ -+ ret = sss_is_selinux_managed(handle); -+ sss_semanage_close(handle); -+ if (ret != EOK) { -+ return ret; -+ } -+ -+ return getseuserbyname(linuxuser, selinuxuser, level); -+} -+ - int set_seuser(const char *login_name, const char *seuser_name, - const char *mls) - { -@@ -382,7 +425,7 @@ done: - sss_semanage_close(handle); - return ret; - } --#else /* HAVE_SEMANAGE */ -+#else /* HAVE_SEMANAGE && HAVE_SELINUX */ - int set_seuser(const char *login_name, const char *seuser_name, - const char *mls) - { -@@ -393,4 +436,11 @@ int del_seuser(const char *login_name) - { - return EOK; - } -+ -+int sss_get_seuser(const char *linuxuser, -+ char **selinuxuser, -+ char **level) -+{ -+ return EOK; -+} - #endif /* HAVE_SEMANAGE */ -diff --git a/src/util/util.h b/src/util/util.h -index 2521b1789b0b8701b1fbcce33890eedb7fe18d5e..be818a9531897e4f988cae48bf6ba30aea0e6d56 100644 ---- a/src/util/util.h -+++ b/src/util/util.h -@@ -654,6 +654,9 @@ errno_t restore_creds(struct sss_creds *saved_creds); - int set_seuser(const char *login_name, const char *seuser_name, - const char *mlsrange); - int del_seuser(const char *login_name); -+int sss_get_seuser(const char *linuxuser, -+ char **selinuxuser, -+ char **level); - - /* 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); --- -2.14.3 - diff --git a/SOURCES/0099-util-Add-sss_-prefix-to-some-functions.patch b/SOURCES/0099-util-Add-sss_-prefix-to-some-functions.patch deleted file mode 100644 index 829aea5..0000000 --- a/SOURCES/0099-util-Add-sss_-prefix-to-some-functions.patch +++ /dev/null @@ -1,142 +0,0 @@ -From 9e1df30e737566ca92c93cb09028717415120f47 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michal=20=C5=BDidek?= -Date: Tue, 6 Feb 2018 19:17:55 +0100 -Subject: [PATCH 99/99] util: Add sss_ prefix to some functions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Add sss_ prefix to del_seuser and set_seuser for consistency -with sss_get_seuser. Also sss_ prefix makes it clear that -these functions come from SSSD. - -Reviewed-by: Lukáš Slebodník - -Resolves: -https://pagure.io/SSSD/sssd/issue/3618 -(cherry picked from commit 6b9c38df5712b951e31800efea2df0802e333e08) ---- - src/providers/ipa/selinux_child.c | 4 ++-- - src/tools/sss_useradd.c | 2 +- - src/tools/sss_userdel.c | 2 +- - src/tools/sss_usermod.c | 2 +- - src/util/sss_semanage.c | 12 ++++++------ - src/util/util.h | 6 +++--- - 6 files changed, 14 insertions(+), 14 deletions(-) - -diff --git a/src/providers/ipa/selinux_child.c b/src/providers/ipa/selinux_child.c -index c659976e80cb7317671da52fe4777ee821589e36..a601b28c4c68afca51758b1967d1bfc1d51fb450 100644 ---- a/src/providers/ipa/selinux_child.c -+++ b/src/providers/ipa/selinux_child.c -@@ -157,9 +157,9 @@ static int sc_set_seuser(const char *login_name, const char *seuser_name, - * default. We need to remove the SELinux user from the DB - * in that case - */ -- ret = del_seuser(login_name); -+ ret = sss_del_seuser(login_name); - } else { -- ret = set_seuser(login_name, seuser_name, mls); -+ ret = sss_set_seuser(login_name, seuser_name, mls); - } - umask(old_mask); - return ret; -diff --git a/src/tools/sss_useradd.c b/src/tools/sss_useradd.c -index 8521b83011b42c9e2acca4136f154acb3919440c..ca2cbd6c119e5a1735e5b3b524cddeccb68a2578 100644 ---- a/src/tools/sss_useradd.c -+++ b/src/tools/sss_useradd.c -@@ -205,7 +205,7 @@ int main(int argc, const char **argv) - - /* Set SELinux login context - must be done after transaction is done - * b/c libselinux calls getpwnam */ -- ret = set_seuser(tctx->octx->name, pc_selinux_user, NULL); -+ ret = sss_set_seuser(tctx->octx->name, pc_selinux_user, NULL); - if (ret != EOK) { - ERROR("Cannot set SELinux login context\n"); - ret = EXIT_FAILURE; -diff --git a/src/tools/sss_userdel.c b/src/tools/sss_userdel.c -index d085dc3cabd31b2ee82b13c6cbc39c7658b071d1..fb0f2c2ab6163738da2dcf4177c06cd5dc524345 100644 ---- a/src/tools/sss_userdel.c -+++ b/src/tools/sss_userdel.c -@@ -254,7 +254,7 @@ int main(int argc, const char **argv) - - /* Set SELinux login context - must be done after transaction is done - * b/c libselinux calls getpwnam */ -- ret = del_seuser(tctx->octx->name); -+ ret = sss_del_seuser(tctx->octx->name); - if (ret != EOK) { - ERROR("Cannot reset SELinux login context\n"); - ret = EXIT_FAILURE; -diff --git a/src/tools/sss_usermod.c b/src/tools/sss_usermod.c -index 55e94394766f5f46bb3c14c231186f2d79d6b6ab..6a818f13ad2a7e087e23fa2190b83aeb1eabdbac 100644 ---- a/src/tools/sss_usermod.c -+++ b/src/tools/sss_usermod.c -@@ -300,7 +300,7 @@ int main(int argc, const char **argv) - - /* Set SELinux login context - must be done after transaction is done - * b/c libselinux calls getpwnam */ -- ret = set_seuser(tctx->octx->name, pc_selinux_user, NULL); -+ ret = sss_set_seuser(tctx->octx->name, pc_selinux_user, NULL); - if (ret != EOK) { - ERROR("Cannot set SELinux login context\n"); - ret = EXIT_FAILURE; -diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c -index 25b6bcdad2ad7e7ac710497f13d6a6e22360b0dd..1150b6236c2c227fe2fc69f2505b6e254a1e64ec 100644 ---- a/src/util/sss_semanage.c -+++ b/src/util/sss_semanage.c -@@ -272,8 +272,8 @@ int sss_get_seuser(const char *linuxuser, - return getseuserbyname(linuxuser, selinuxuser, level); - } - --int set_seuser(const char *login_name, const char *seuser_name, -- const char *mls) -+int sss_set_seuser(const char *login_name, const char *seuser_name, -+ const char *mls) - { - semanage_handle_t *handle = NULL; - semanage_seuser_key_t *key = NULL; -@@ -346,7 +346,7 @@ done: - return ret; - } - --int del_seuser(const char *login_name) -+int sss_del_seuser(const char *login_name) - { - semanage_handle_t *handle = NULL; - semanage_seuser_key_t *key = NULL; -@@ -426,13 +426,13 @@ done: - return ret; - } - #else /* HAVE_SEMANAGE && HAVE_SELINUX */ --int set_seuser(const char *login_name, const char *seuser_name, -- const char *mls) -+int sss_set_seuser(const char *login_name, const char *seuser_name, -+ const char *mls) - { - return EOK; - } - --int del_seuser(const char *login_name) -+int sss_del_seuser(const char *login_name) - { - return EOK; - } -diff --git a/src/util/util.h b/src/util/util.h -index be818a9531897e4f988cae48bf6ba30aea0e6d56..ef8ef7f57d7949aa2735171f11195dbcdc42288a 100644 ---- a/src/util/util.h -+++ b/src/util/util.h -@@ -651,9 +651,9 @@ errno_t restore_creds(struct sss_creds *saved_creds); - * certain permissions. Therefore the caller should make sure the umask is - * not too restricted (especially when called from the daemon code). - */ --int set_seuser(const char *login_name, const char *seuser_name, -- const char *mlsrange); --int del_seuser(const char *login_name); -+int sss_set_seuser(const char *login_name, const char *seuser_name, -+ const char *mlsrange); -+int sss_del_seuser(const char *login_name); - int sss_get_seuser(const char *linuxuser, - char **selinuxuser, - char **level); --- -2.14.3 - diff --git a/SOURCES/0100-MAN-Explain-how-does-auto_private_groups-affect-subd.patch b/SOURCES/0100-MAN-Explain-how-does-auto_private_groups-affect-subd.patch deleted file mode 100644 index ae772b2..0000000 --- a/SOURCES/0100-MAN-Explain-how-does-auto_private_groups-affect-subd.patch +++ /dev/null @@ -1,43 +0,0 @@ -From a09a7a03f5b330cc45a0007a56d4789116a91e46 Mon Sep 17 00:00:00 2001 -From: amitkuma -Date: Tue, 6 Feb 2018 16:27:00 +0530 -Subject: [PATCH 100/100] MAN: Explain how does auto_private_groups affect - subdomains - -Fix explains how auto_private_groups affects subdomains. -a. POSIX sudomains, gets inherited to subdomain. -b. ID-mapping subdomains, already enabled. - -Resolves: https://pagure.io/SSSD/sssd/issue/3627 - -Reviewed-by: Rob Crittenden -(cherry picked from commit 52ae76737f2df3012d67f6a0b5052c86022bffdd) ---- - src/man/sssd.conf.5.xml | 11 ++++++++++- - 1 file changed, 10 insertions(+), 1 deletion(-) - -diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml -index 47da07c33bdcfbf2fa94ff932492e9ea4bbfe846..8d06f57539e3fc55189234aab2aea950ba14713a 100644 ---- a/src/man/sssd.conf.5.xml -+++ b/src/man/sssd.conf.5.xml -@@ -2830,7 +2830,16 @@ subdomain_inherit = ldap_purge_cache_timeout - If this option is enabled, SSSD will automatically - create user private groups based on user's - UID number. The GID number is ignored in this case. -- -+ -+ -+ For POSIX subdomains, setting the option in the main -+ domain is inherited in the subdomain. -+ -+ -+ For ID-mapping subdomains, auto_private_groups is -+ already enabled for the subdomains and setting it to -+ false will not have any effect for the subdomain. -+ - - NOTE: Because the GID number and the user private group - are inferred frm the UID number, it is not supported --- -2.14.3 - diff --git a/SOURCES/0101-AD-Use-the-right-sdap_domain-for-the-forest-root.patch b/SOURCES/0101-AD-Use-the-right-sdap_domain-for-the-forest-root.patch deleted file mode 100644 index 128a9ea..0000000 --- a/SOURCES/0101-AD-Use-the-right-sdap_domain-for-the-forest-root.patch +++ /dev/null @@ -1,201 +0,0 @@ -From d56d41e76741f418e88e479b91193db3ee3f1688 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Wed, 17 Jan 2018 21:59:24 +0100 -Subject: [PATCH 101/101] AD: Use the right sdap_domain for the forest root -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Each ad_id_ctx structure which represents a trusted AD domain contains a -list of sdap_domain structures representing all the other domains. This -is used to e.g. be able to reach another domain's ad_id_ctx and use its -LDAP connection. - -However, the sdap search call that was searching for trusted domains in -the forest that the root domain knows about, was unconditionally using -the first sdap_domain structure in the list linked from the root_domain's -ad_id_ctx structure. - -It should be noted that this search only happens in case the machine is -joined to one of the non-root domains in the forest and searches the root -domain explicitly. - -In case sdap_domain structures linked from the ad_id_ctx representing -the root domain were ordered so that the first sdap_domain in the list -was representing a different domain than the one linked from the -ad_id_ctx, the sdap search would have used a wrong search base derived -from the unexpected sdap_domain which would result in a referral being -returned. - -This patch explicitly looks up the sdap_domain structure that -corresponds to the root domain. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3594 - -Reviewed-by: Sumit Bose -Reviewed-by: Lukáš Slebodník -(cherry picked from commit 9ac071272ce0152eb293d3181a5c12b395655521) ---- - src/providers/ad/ad_subdomains.c | 110 +++++++++++++++++++++++++++------------ - 1 file changed, 77 insertions(+), 33 deletions(-) - -diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c -index 1b9483a5dce937d6acdd813486a1e8c18210d35f..bd94ba8ea93679df8d01508b3d4d85217d9c1c87 100644 ---- a/src/providers/ad/ad_subdomains.c -+++ b/src/providers/ad/ad_subdomains.c -@@ -57,6 +57,71 @@ - /* do not refresh more often than every 5 seconds for now */ - #define AD_SUBDOMAIN_REFRESH_LIMIT 5 - -+static struct sss_domain_info * -+ads_get_root_domain(struct be_ctx *be_ctx, struct sysdb_attrs *attrs) -+{ -+ struct sss_domain_info *dom; -+ const char *name; -+ errno_t ret; -+ -+ if (attrs == NULL) { -+ /* Clients joined to the forest root directly don't even discover -+ * the root domain, so the attrs are expected to be NULL in this -+ * case -+ */ -+ return be_ctx->domain; -+ } -+ -+ ret = sysdb_attrs_get_string(attrs, AD_AT_TRUST_PARTNER, &name); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); -+ return NULL; -+ } -+ -+ /* With a subsequent run, the root should already be known */ -+ for (dom = be_ctx->domain; dom != NULL; -+ dom = get_next_domain(dom, SSS_GND_ALL_DOMAINS)) { -+ -+ if (strcasecmp(dom->name, name) == 0) { -+ /* The forest root is special, although it might be disabled for -+ * general lookups we still want to try to get the domains in the -+ * forest from a DC of the forest root */ -+ if (sss_domain_get_state(dom) == DOM_DISABLED -+ && !sss_domain_is_forest_root(dom)) { -+ return NULL; -+ } -+ return dom; -+ } -+ } -+ -+ return NULL; -+} -+ -+static struct sdap_domain * -+ads_get_root_sdap_domain(struct be_ctx *be_ctx, -+ struct sdap_options *opts, -+ struct sysdb_attrs *attrs) -+{ -+ struct sdap_domain *root_sdom; -+ struct sss_domain_info *root_dom; -+ -+ root_dom = ads_get_root_domain(be_ctx, attrs); -+ if (root_dom == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "ads_get_root_domain did not find the domain\n"); -+ return NULL; -+ } -+ -+ root_sdom = sdap_domain_get(opts, root_dom); -+ if (root_sdom == NULL) { -+ DEBUG(SSSDBG_OP_FAILURE, -+ "Failed to find sdap_domain for the root domain\n"); -+ return NULL; -+ } -+ -+ return root_sdom; -+} -+ - static errno_t ad_get_enabled_domains(TALLOC_CTX *mem_ctx, - struct ad_id_ctx *ad_id_ctx, - const char *ad_domain, -@@ -755,6 +820,7 @@ struct ad_get_slave_domain_state { - struct sdap_options *opts; - struct sdap_idmap_ctx *idmap_ctx; - struct sysdb_attrs *root_attrs; -+ struct sdap_domain *root_sdom; - struct sdap_id_op *sdap_op; - }; - -@@ -786,6 +852,13 @@ ad_get_slave_domain_send(TALLOC_CTX *mem_ctx, - state->opts = root_id_ctx->sdap_id_ctx->opts; - state->idmap_ctx = root_id_ctx->sdap_id_ctx->opts->idmap_ctx; - state->root_attrs = root_attrs; -+ state->root_sdom = ads_get_root_sdap_domain(state->be_ctx, -+ state->opts, -+ state->root_attrs); -+ if (state->root_sdom == NULL) { -+ ret = ERR_DOMAIN_NOT_FOUND; -+ goto immediately; -+ } - - state->sdap_op = sdap_id_op_create(state, root_id_ctx->ldap_ctx->conn_cache); - if (state->sdap_op == NULL) { -@@ -861,7 +934,7 @@ static void ad_get_slave_domain_connect_done(struct tevent_req *subreq) - - subreq = sdap_search_bases_send(state, state->ev, state->opts, - sdap_id_op_handle(state->sdap_op), -- state->opts->sdom->search_bases, -+ state->root_sdom->search_bases, - NULL, false, 0, - SLAVE_DOMAIN_FILTER, attrs); - if (subreq == NULL) { -@@ -965,38 +1038,6 @@ static errno_t ad_get_slave_domain_recv(struct tevent_req *req) - return EOK; - } - --static struct sss_domain_info * --ads_get_root_domain(struct be_ctx *be_ctx, struct sysdb_attrs *attrs) --{ -- struct sss_domain_info *dom; -- const char *name; -- errno_t ret; -- -- ret = sysdb_attrs_get_string(attrs, AD_AT_TRUST_PARTNER, &name); -- if (ret != EOK) { -- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); -- return NULL; -- } -- -- /* With a subsequent run, the root should already be known */ -- for (dom = be_ctx->domain; dom != NULL; -- dom = get_next_domain(dom, SSS_GND_ALL_DOMAINS)) { -- -- if (strcasecmp(dom->name, name) == 0) { -- /* The forest root is special, although it might be disabled for -- * general lookups we still want to try to get the domains in the -- * forest from a DC of the forest root */ -- if (sss_domain_get_state(dom) == DOM_DISABLED -- && !sss_domain_is_forest_root(dom)) { -- return NULL; -- } -- return dom; -- } -- } -- -- return NULL; --} -- - static struct ad_id_ctx * - ads_get_root_id_ctx(struct be_ctx *be_ctx, - struct ad_id_ctx *ad_id_ctx, -@@ -1416,6 +1457,9 @@ static void ad_subdomains_refresh_root_done(struct tevent_req *subreq) - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct ad_subdomains_refresh_state); - -+ /* Note: For clients joined to the root domain, root_attrs is NULL, -+ * see ad_get_root_domain_send() -+ */ - ret = ad_get_root_domain_recv(state, subreq, &root_attrs, &root_id_ctx); - talloc_zfree(subreq); - if (ret != EOK) { --- -2.14.3 - diff --git a/SOURCES/0102-AD-sdap_get_ad_tokengroups_done-allocate-temporary-d.patch b/SOURCES/0102-AD-sdap_get_ad_tokengroups_done-allocate-temporary-d.patch deleted file mode 100644 index 5f9991f..0000000 --- a/SOURCES/0102-AD-sdap_get_ad_tokengroups_done-allocate-temporary-d.patch +++ /dev/null @@ -1,47 +0,0 @@ -From f6f8fca59937b746b3c47cf0aeb23ea554a43fab Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 16 Feb 2018 12:07:28 +0100 -Subject: [PATCH] AD: sdap_get_ad_tokengroups_done() allocate temporary data on - state - -Related to https://pagure.io/SSSD/sssd/issue/3639 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit db52090e33b8f1747b7d77bab64ab8c9f9f5ecc2) ---- - src/providers/ldap/sdap_async_initgroups_ad.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c -index 61aa69a2dfbe22cac37a5b7fddc07473527e5de5..ee0cd6707924b02d239ce4c329d9853268d49a80 100644 ---- a/src/providers/ldap/sdap_async_initgroups_ad.c -+++ b/src/providers/ldap/sdap_async_initgroups_ad.c -@@ -372,7 +372,6 @@ immediately: - - static void sdap_get_ad_tokengroups_done(struct tevent_req *subreq) - { -- TALLOC_CTX *tmp_ctx = NULL; - struct sdap_get_ad_tokengroups_state *state = NULL; - struct tevent_req *req = NULL; - struct sysdb_attrs **users = NULL; -@@ -386,7 +385,7 @@ static void sdap_get_ad_tokengroups_done(struct tevent_req *subreq) - req = tevent_req_callback_data(subreq, struct tevent_req); - state = tevent_req_data(req, struct sdap_get_ad_tokengroups_state); - -- ret = sdap_get_generic_recv(subreq, tmp_ctx, &num_users, &users); -+ ret = sdap_get_generic_recv(subreq, state, &num_users, &users); - talloc_zfree(subreq); - if (ret != EOK) { - DEBUG(SSSDBG_MINOR_FAILURE, -@@ -449,8 +448,6 @@ static void sdap_get_ad_tokengroups_done(struct tevent_req *subreq) - ret = EOK; - - done: -- talloc_free(tmp_ctx); -- - if (ret != EOK) { - tevent_req_error(req, ret); - return; --- -2.14.3 - diff --git a/SOURCES/0103-AD-do-not-allocate-temporary-data-on-long-living-con.patch b/SOURCES/0103-AD-do-not-allocate-temporary-data-on-long-living-con.patch deleted file mode 100644 index 7140380..0000000 --- a/SOURCES/0103-AD-do-not-allocate-temporary-data-on-long-living-con.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 3dae415229a7a2526a886ea55a12377fdc62361e Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 16 Feb 2018 12:09:01 +0100 -Subject: [PATCH] AD: do not allocate temporary data on long living context - -Related to https://pagure.io/SSSD/sssd/issue/3639 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit e6ad16e05f42a1678a8c6cd14eb54ca75b8d775e) ---- - src/providers/ad/ad_common.c | 5 +++-- - src/providers/ad/ad_common.h | 3 ++- - src/providers/ad/ad_id.c | 2 +- - src/tests/cmocka/test_ad_common.c | 4 ++-- - 4 files changed, 8 insertions(+), 6 deletions(-) - -diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c -index 84845e285bef336b503b9d27bfc6eb99d6ee43ff..2a1647173b76b410371315eb364e9a3785714a93 100644 ---- a/src/providers/ad/ad_common.c -+++ b/src/providers/ad/ad_common.c -@@ -1402,13 +1402,14 @@ ad_ldap_conn_list(TALLOC_CTX *mem_ctx, - } - - struct sdap_id_conn_ctx ** --ad_user_conn_list(struct ad_id_ctx *ad_ctx, -+ad_user_conn_list(TALLOC_CTX *mem_ctx, -+ struct ad_id_ctx *ad_ctx, - struct sss_domain_info *dom) - { - struct sdap_id_conn_ctx **clist; - int cindex = 0; - -- clist = talloc_zero_array(ad_ctx, struct sdap_id_conn_ctx *, 3); -+ clist = talloc_zero_array(mem_ctx, struct sdap_id_conn_ctx *, 3); - if (clist == NULL) { - return NULL; - } -diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h -index ce33b37c75f45ae72adb268858cce34759b8b02f..931aafc6c031e0979460925a1402517b054b202c 100644 ---- a/src/providers/ad/ad_common.h -+++ b/src/providers/ad/ad_common.h -@@ -175,7 +175,8 @@ ad_ldap_conn_list(TALLOC_CTX *mem_ctx, - struct sss_domain_info *dom); - - struct sdap_id_conn_ctx ** --ad_user_conn_list(struct ad_id_ctx *ad_ctx, -+ad_user_conn_list(TALLOC_CTX *mem_ctx, -+ struct ad_id_ctx *ad_ctx, - struct sss_domain_info *dom); - - struct sdap_id_conn_ctx * -diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c -index 0b8f49819405c7dbbfa18b5359f7743441dc65e5..782d9bc402e71d6b20976367f6afbae82bd25750 100644 ---- a/src/providers/ad/ad_id.c -+++ b/src/providers/ad/ad_id.c -@@ -367,7 +367,7 @@ get_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx, - - switch (ar->entry_type & BE_REQ_TYPE_MASK) { - case BE_REQ_USER: /* user */ -- clist = ad_user_conn_list(ad_ctx, dom); -+ clist = ad_user_conn_list(mem_ctx, ad_ctx, dom); - break; - case BE_REQ_BY_SECID: /* by SID */ - case BE_REQ_USER_AND_GROUP: /* get SID */ -diff --git a/src/tests/cmocka/test_ad_common.c b/src/tests/cmocka/test_ad_common.c -index 80b3bb5599a95578b7734d5dfcd20a2a7428a084..a8a447e91bd5107bbfc9d8445d0508778a5012f8 100644 ---- a/src/tests/cmocka/test_ad_common.c -+++ b/src/tests/cmocka/test_ad_common.c -@@ -771,7 +771,7 @@ void test_user_conn_list(void **state) - struct ad_common_test_ctx); - assert_non_null(test_ctx); - -- conn_list = ad_user_conn_list(test_ctx->ad_ctx, -+ conn_list = ad_user_conn_list(test_ctx, test_ctx->ad_ctx, - test_ctx->dom); - assert_non_null(conn_list); - -@@ -780,7 +780,7 @@ void test_user_conn_list(void **state) - assert_null(conn_list[1]); - talloc_free(conn_list); - -- conn_list = ad_user_conn_list(test_ctx->ad_ctx, -+ conn_list = ad_user_conn_list(test_ctx, test_ctx->ad_ctx, - test_ctx->subdom); - assert_non_null(conn_list); - --- -2.14.3 - diff --git a/SOURCES/0104-nss-idmap-do-not-set-a-limit.patch b/SOURCES/0104-nss-idmap-do-not-set-a-limit.patch deleted file mode 100644 index 894d05e..0000000 --- a/SOURCES/0104-nss-idmap-do-not-set-a-limit.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 814108dc02a4de5d0333e9c2713f809fc3d2da47 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 18 Apr 2018 10:20:06 +0200 -Subject: [PATCH] nss-idmap: do not set a limit - -If the limit is set the needed size to return all groups cannot be -returned. - -Related to https://pagure.io/SSSD/sssd/issue/3715 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 46a4c265629d9b725c41f22849741ce7342bdd85) - -DOWNSTREAM: -Resolves: rhbz#1570527 - memory management issue in the sssd_nss_ex interface can cause the ns-slapd process on IPA server to crash [rhel-7.5.z] ---- - src/sss_client/idmap/sss_nss_ex.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c -index af6a95180656b598bcb94c209dfa821cb0275f02..f56bffcc24a7e2503e23a892541a9242ed4b5069 100644 ---- a/src/sss_client/idmap/sss_nss_ex.c -+++ b/src/sss_client/idmap/sss_nss_ex.c -@@ -96,7 +96,9 @@ errno_t sss_nss_mc_get(struct nss_input *inp) - inp->result.initgrrep.start, - inp->result.initgrrep.ngroups, - &(inp->result.initgrrep.groups), -- *(inp->result.initgrrep.ngroups)); -+ /* no limit so that needed size can -+ * be returned properly */ -+ -1); - break; - default: - return EINVAL; --- -2.14.3 - diff --git a/SOURCES/0105-nss-idmap-use-right-group-list-pointer-after-sss_get.patch b/SOURCES/0105-nss-idmap-use-right-group-list-pointer-after-sss_get.patch deleted file mode 100644 index 5e524cd..0000000 --- a/SOURCES/0105-nss-idmap-use-right-group-list-pointer-after-sss_get.patch +++ /dev/null @@ -1,69 +0,0 @@ -From c3e0098383fb199d678df54bfd129123a8184e70 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Wed, 18 Apr 2018 10:23:22 +0200 -Subject: [PATCH] nss-idmap: use right group list pointer after sss_get_ex() - -If the initial array is too small it will be reallocated during -sss_get_ex() and the pointer might change and the initial memory area -should not be used anymore. - -Related to https://pagure.io/SSSD/sssd/issue/3715 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 2c4dc7a4d98c439c69625f12ba4c3c8253f4cc5b) ---- - src/sss_client/idmap/sss_nss_ex.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - -diff --git a/src/sss_client/idmap/sss_nss_ex.c b/src/sss_client/idmap/sss_nss_ex.c -index f56bffcc24a7e2503e23a892541a9242ed4b5069..5bcfe8850b5355d6cbe0efc5e52fe076737f2a08 100644 ---- a/src/sss_client/idmap/sss_nss_ex.c -+++ b/src/sss_client/idmap/sss_nss_ex.c -@@ -485,7 +485,6 @@ int sss_nss_getgrouplist_timeout(const char *name, gid_t group, - uint32_t flags, unsigned int timeout) - { - int ret; -- gid_t *new_groups; - long int new_ngroups; - long int start = 1; - struct nss_input inp = { -@@ -498,27 +497,28 @@ int sss_nss_getgrouplist_timeout(const char *name, gid_t group, - } - - new_ngroups = MAX(1, *ngroups); -- new_groups = malloc(new_ngroups * sizeof(gid_t)); -- if (new_groups == NULL) { -+ inp.result.initgrrep.groups = malloc(new_ngroups * sizeof(gid_t)); -+ if (inp.result.initgrrep.groups == NULL) { - free(discard_const(inp.rd.data)); - return ENOMEM; - } -- new_groups[0] = group; -+ inp.result.initgrrep.groups[0] = group; - -- inp.result.initgrrep.groups = new_groups, - inp.result.initgrrep.ngroups = &new_ngroups; - inp.result.initgrrep.start = &start; - -- -+ /* inp.result.initgrrep.groups, inp.result.initgrrep.ngroups and -+ * inp.result.initgrrep.start might be modified by sss_get_ex() */ - ret = sss_get_ex(&inp, flags, timeout); - free(discard_const(inp.rd.data)); - if (ret != 0) { -- free(new_groups); -+ free(inp.result.initgrrep.groups); - return ret; - } - -- memcpy(groups, new_groups, MIN(*ngroups, start) * sizeof(gid_t)); -- free(new_groups); -+ memcpy(groups, inp.result.initgrrep.groups, -+ MIN(*ngroups, start) * sizeof(gid_t)); -+ free(inp.result.initgrrep.groups); - - if (start > *ngroups) { - ret = ERANGE; --- -2.14.3 - diff --git a/SOURCES/0106-nss-add-a-netgroup-counter-to-struct-nss_enum_index.patch b/SOURCES/0106-nss-add-a-netgroup-counter-to-struct-nss_enum_index.patch deleted file mode 100644 index 2611011..0000000 --- a/SOURCES/0106-nss-add-a-netgroup-counter-to-struct-nss_enum_index.patch +++ /dev/null @@ -1,119 +0,0 @@ -From f9859498b52d89bf60dbddd898752f859f4952d3 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 15 Mar 2018 12:50:20 +0100 -Subject: [PATCH] nss: add a netgroup counter to struct nss_enum_index - -Netgroups are not looked up with the help of a single request but by -calling setnetgrent(), getnetgrent() and endnetgrent() where -getnetgrent() might be called multiple times depending on the number of -netgroup elements. Since the caller does not provide a state the state -has to be maintained by the SSSD nss responder. Besides the netgroup -name this is mainly the number of elements already returned. - -This number is used to select the next element to return and currently -it is assumed that there are not changes to the netgroup while the -client is requesting the individual elements. But if e.g. the 3 nss -calls are not used correctly or the netgroup is modified while the -client is sending getnetgrent() calls the stored number might be out of -range. To be on the safe side the stored number should be always -compared with the current number of netgroup elements. - -Related to https://pagure.io/SSSD/sssd/issue/3679 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 08db22b1b1a2e742edbca92e35087294d963adda) - -DOWNSTREAM: -Resolves: rhbz#1579703 - crash in nss_protocol_fill_netgrent. sssd_nss[19234]: segfault at 80 ip 000055612688c2a0 sp 00007ffddf9b9cd0 error 4 in sssd_nss[55612687e000+39000] [rhel-7.5.z] ---- - src/db/sysdb.h | 3 ++- - src/db/sysdb_search.c | 5 ++++- - src/responder/nss/nss_enum.c | 3 ++- - src/responder/nss/nss_private.h | 1 + - src/responder/nss/nss_protocol_netgr.c | 7 +++++++ - 5 files changed, 16 insertions(+), 3 deletions(-) - -diff --git a/src/db/sysdb.h b/src/db/sysdb.h -index fd18ecefed2b2c5f35060fa47fd160a8968e073b..2660314a75a574d7f5625c8672e5261587056d1a 100644 ---- a/src/db/sysdb.h -+++ b/src/db/sysdb.h -@@ -1219,7 +1219,8 @@ errno_t sysdb_attrs_to_list(TALLOC_CTX *mem_ctx, - - errno_t sysdb_netgr_to_entries(TALLOC_CTX *mem_ctx, - struct ldb_result *res, -- struct sysdb_netgroup_ctx ***entries); -+ struct sysdb_netgroup_ctx ***entries, -+ size_t *netgroup_count); - - errno_t sysdb_dn_sanitize(TALLOC_CTX *mem_ctx, const char *input, - char **sanitized); -diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c -index a6a81e23d257331614085403b4dca8ded860600b..9f37cbcd50a778145518c15b6146ad812a5b4fa3 100644 ---- a/src/db/sysdb_search.c -+++ b/src/db/sysdb_search.c -@@ -1829,7 +1829,8 @@ done: - - errno_t sysdb_netgr_to_entries(TALLOC_CTX *mem_ctx, - struct ldb_result *res, -- struct sysdb_netgroup_ctx ***entries) -+ struct sysdb_netgroup_ctx ***entries, -+ size_t *netgroup_count) - { - errno_t ret; - size_t size = 0; -@@ -1933,6 +1934,8 @@ errno_t sysdb_netgr_to_entries(TALLOC_CTX *mem_ctx, - tmp_entry[c] = NULL; - - *entries = talloc_steal(mem_ctx, tmp_entry); -+ *netgroup_count = c; -+ - ret = EOK; - - done: -diff --git a/src/responder/nss/nss_enum.c b/src/responder/nss/nss_enum.c -index da844fbced529f606a3e98669fb7b95e0696ce00..b2b22bbae8a373ed3abb47381fabd989d4931690 100644 ---- a/src/responder/nss/nss_enum.c -+++ b/src/responder/nss/nss_enum.c -@@ -144,7 +144,8 @@ static void nss_setent_internal_done(struct tevent_req *subreq) - /* We need to expand the netgroup into triples and members. */ - ret = sysdb_netgr_to_entries(state->enum_ctx, - result[0]->ldb_result, -- &state->enum_ctx->netgroup); -+ &state->enum_ctx->netgroup, -+ &state->enum_ctx->netgroup_count); - if (ret != EOK) { - goto done; - } -diff --git a/src/responder/nss/nss_private.h b/src/responder/nss/nss_private.h -index 5fc19d26be9adda4d967086e7b239e49a78866ee..aa8d8e9cde0d73e72d3aa4c186f104d6baae411f 100644 ---- a/src/responder/nss/nss_private.h -+++ b/src/responder/nss/nss_private.h -@@ -41,6 +41,7 @@ struct nss_enum_index { - struct nss_enum_ctx { - struct cache_req_result **result; - struct sysdb_netgroup_ctx **netgroup; -+ size_t netgroup_count; - - /* Ongoing cache request that is constructing enumeration result. */ - struct tevent_req *ongoing; -diff --git a/src/responder/nss/nss_protocol_netgr.c b/src/responder/nss/nss_protocol_netgr.c -index ed04fd25821031554e20e14afebaca9b828a748b..9f27c6b78d47f188dea99600a634a18be2512bfb 100644 ---- a/src/responder/nss/nss_protocol_netgr.c -+++ b/src/responder/nss/nss_protocol_netgr.c -@@ -126,6 +126,13 @@ nss_protocol_fill_netgrent(struct nss_ctx *nss_ctx, - idx = cmd_ctx->enum_index; - entries = cmd_ctx->enum_ctx->netgroup; - -+ if (idx->result > cmd_ctx->enum_ctx->netgroup_count) { -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Unconsistent state while processing netgroups.\n"); -+ ret = EINVAL; -+ goto done; -+ } -+ - /* First two fields (length and reserved), filled up later. */ - ret = sss_packet_grow(packet, 2 * sizeof(uint32_t)); - if (ret != EOK) { --- -2.17.0 - diff --git a/SOURCES/0107-nss-initialize-nss_enum_index-in-nss_setnetgrent.patch b/SOURCES/0107-nss-initialize-nss_enum_index-in-nss_setnetgrent.patch deleted file mode 100644 index 3ae5b68..0000000 --- a/SOURCES/0107-nss-initialize-nss_enum_index-in-nss_setnetgrent.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 1e2f20f89b1b699e569dfecb7cba98ec8f6fc936 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Thu, 15 Mar 2018 12:43:34 +0100 -Subject: [PATCH] nss: initialize nss_enum_index in nss_setnetgrent() - -setnetgrent() is the first call when looking up a netgroup and sets the -netgroup name for upcoming getnetgrent() and endnetgrent() calls. -Currently the state is reset by calling endnetgrent() but it would be -more robust to unconditionally reset the state in setnetgrent() as well -in case calling endnetgrent() was forgotten. - -Related to https://pagure.io/SSSD/sssd/issue/3679 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 37a84285aeb497ed4909d16916bbf934af3f68b3) ---- - src/responder/nss/nss_cmd.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/responder/nss/nss_cmd.c b/src/responder/nss/nss_cmd.c -index 956ee53cb88dd24faaa95ac39c8d9540af66cfb2..9f8479b7b350823ee81b5af15199e0dda9acda8b 100644 ---- a/src/responder/nss/nss_cmd.c -+++ b/src/responder/nss/nss_cmd.c -@@ -756,6 +756,9 @@ static errno_t nss_setnetgrent(struct cli_ctx *cli_ctx, - goto done; - } - -+ state_ctx->netgrent.domain = 0; -+ state_ctx->netgrent.result = 0; -+ - talloc_zfree(state_ctx->netgroup); - state_ctx->netgroup = talloc_strdup(state_ctx, netgroup); - if (state_ctx->netgroup == NULL) { --- -2.17.0 - diff --git a/SOURCES/0108-NSS-nss_clear_netgroup_hash_table-do-not-free-data.patch b/SOURCES/0108-NSS-nss_clear_netgroup_hash_table-do-not-free-data.patch deleted file mode 100644 index 89c55c3..0000000 --- a/SOURCES/0108-NSS-nss_clear_netgroup_hash_table-do-not-free-data.patch +++ /dev/null @@ -1,52 +0,0 @@ -From d92cb9cb3860d7ff1b3ab64b459edf6051f69291 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 4 May 2018 17:00:55 +0200 -Subject: [PATCH] NSS: nss_clear_netgroup_hash_table() do not free data -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -nss_clear_netgroup_hash_table() is called during the clearEnumCache SBUS -request, which is e.g. used during 'sss_cache -E', to remove netgroup -data cached in the memory of the NSS responder. - -Currently nss_clear_netgroup_hash_table() calls -'sss_ptr_hash_delete_all(nss_ctx->netgrent, true);' which not only -removes all entries in the 'netgerent' hash table but frees them as -well. - -The second step is not needed because nss_setnetgrent_set_timeout() -takes care that the data is freed after a timeout. Additionally freeing -the data in nss_clear_netgroup_hash_table() can even do harm when the -request is received by the NSS responder while waiting for the backend -to acquire the netgroup data. Because if the backend is done the NSS -responder tries do use enum_ctx which might have been freed in the -meantime. - -Because of this nss_clear_netgroup_hash_table() should only remove the -data from the hash table but not free it. - -Related to https://pagure.io/SSSD/sssd/issue/3731 - -Reviewed-by: Pavel Březina -(cherry picked from commit b13cc2d1413a0d5bbe36e06e5ffd87dbf5c0cb9f) ---- - src/responder/nss/nsssrv.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c -index 11d19fd30c86283d537623db12e52caa6cc4dcd3..123a2d73ce93a025c789524fa90b41d9a0afb58b 100644 ---- a/src/responder/nss/nsssrv.c -+++ b/src/responder/nss/nsssrv.c -@@ -142,7 +142,7 @@ static int nss_clear_netgroup_hash_table(struct sbus_request *dbus_req, void *da - - DEBUG(SSSDBG_TRACE_FUNC, "Invalidating netgroup hash table\n"); - -- sss_ptr_hash_delete_all(nss_ctx->netgrent, true); -+ sss_ptr_hash_delete_all(nss_ctx->netgrent, false); - - return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID); - } --- -2.17.0 - diff --git a/SOURCES/0109-winbind-idmap-plugin-support-inferface-version-6.patch b/SOURCES/0109-winbind-idmap-plugin-support-inferface-version-6.patch deleted file mode 100644 index a2b93a0..0000000 --- a/SOURCES/0109-winbind-idmap-plugin-support-inferface-version-6.patch +++ /dev/null @@ -1,236 +0,0 @@ -From 9ae62c07c579fa9b3f0804c12cc0715f5f2524d4 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 15 May 2018 11:55:35 +0200 -Subject: [PATCH] winbind idmap plugin: support inferface version 6 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -With Samba 4.7 the interface version of the idmap plugin was updated to -6. The patch adds support for this new version but can be complied with -the older version as well. - -A configure option is added to select the version, if no version is -given configure tries to detect the version with the help of an internal -Samba library libidmap-samba4.so. - -To make sure that always the right version is used configure will fail -if Samba is used (--with-samba, default) and no version can be -determined. - -Resolves https://pagure.io/SSSD/sssd/issue/3741 - -Reviewed-by: Alexander Bokovoy -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit c6b99b070268c3807833e9f894d9a36304014417) - -DOWNSTREAM: -Resolves: rhbz#1580281 - Samba can not register sss idmap module because it's using an outdated SMB_IDMAP_INTERFACE_VERSION [rhel-7.5.z] ---- - contrib/ci/configure.sh | 9 ++ - contrib/sssd.spec.in | 12 +++ - src/external/samba.m4 | 82 +++++++++++++++++++ - src/lib/winbind_idmap_sss/winbind_idmap_sss.c | 6 ++ - src/lib/winbind_idmap_sss/winbind_idmap_sss.h | 6 +- - 5 files changed, 114 insertions(+), 1 deletion(-) - -diff --git a/contrib/ci/configure.sh b/contrib/ci/configure.sh -index 9d18d0c187561a2dc3bc47d3e8913626e7ff3046..09da5b4e7b0b4a7859bcf81db987394ac91f4fa2 100644 ---- a/contrib/ci/configure.sh -+++ b/contrib/ci/configure.sh -@@ -35,6 +35,7 @@ declare -a CONFIGURE_ARG_LIST=( - if [[ "$DISTRO_BRANCH" == -redhat-redhatenterprise*-6.*- || - "$DISTRO_BRANCH" == -redhat-centos-6.*- ]]; then - CONFIGURE_ARG_LIST+=( -+ "--with-smb-idmap-interface-version=5" - "--disable-cifs-idmap-plugin" - "--with-syslog=syslog" - "--without-python3-bindings" -@@ -56,6 +57,14 @@ if [[ "$DISTRO_BRANCH" == -redhat-redhatenterprise*-7.*- || - ) - fi - -+# Different versions of Debian might need different versions here but this is -+# sufficient to make the CI work -+if [[ "$DISTRO_BRANCH" == -debian-* ]]; then -+ CONFIGURE_ARG_LIST+=( -+ "--with-smb-idmap-interface-version=5" -+ ) -+fi -+ - declare -r -a CONFIGURE_ARG_LIST - - fi # _CONFIGURE_SH -diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in -index d9323bf1a2d84f4219f8ab11886e5ce87b401c15..3ddd054dea8a4b5dd46457acf9aaabed29ab754e 100644 ---- a/contrib/sssd.spec.in -+++ b/contrib/sssd.spec.in -@@ -127,6 +127,14 @@ - %global with_gdm_pam_extensions 0 - %endif - -+# Do not try to detect the idmap version on RHEL6 to avoid conflicts between -+# samba and samba4 package -+%if (0%{?fedora} || 0%{?rhel} >= 7) -+ %global detect_idmap_version 1 -+%else -+ %global with_idmap_version --with-smb-idmap-interface-version=5 -+%endif -+ - Name: @PACKAGE_NAME@ - Version: @PACKAGE_VERSION@ - Release: 0@PRERELEASE_VERSION@%{?dist} -@@ -225,6 +233,9 @@ BuildRequires: nfs-utils-lib-devel - - BuildRequires: samba4-devel - BuildRequires: libsmbclient-devel -+%if (0%{?detect_idmap_version} == 1) -+BuildRequires: samba-winbind -+%endif - - %if (0%{?enable_systemtap} == 1) - BuildRequires: systemtap-sdt-devel -@@ -747,6 +758,7 @@ autoreconf -ivf - %{?enable_systemtap_opt} \ - %{?with_secret_responder} \ - %{?with_kcm_option} \ -+ %{?with_idmap_version} \ - %{?experimental} - - make %{?_smp_mflags} all -diff --git a/src/external/samba.m4 b/src/external/samba.m4 -index 91a583a0d0f514dab40d4f65cc32b17d0368f540..610831bf054e3687eb13025e954acf345fca1a00 100644 ---- a/src/external/samba.m4 -+++ b/src/external/samba.m4 -@@ -39,4 +39,86 @@ them. In this case, you will need to execute configure script with argument - --without-samba - ]]) - fi -+ -+ AC_ARG_WITH([smb-idmap-interface-version], -+ [AC_HELP_STRING([--with-smb-idmap-interface-version=[5|6]], -+ [Idmap interface version of installed Samba] -+ ) -+ ] -+ ) -+ -+ if test x"$with_smb_idmap_interface_version" != x; then -+ if test x"$with_smb_idmap_interface_version" = x5 -o x"$with_smb_idmap_interface_version" = x6; then -+ idmap_test_result=$with_smb_idmap_interface_version -+ else -+ AC_MSG_ERROR([Illegal value -$with_smb_idmap_interface_version- for option --with-smb-idmap-interface-version]) -+ fi -+ else -+ -+ AC_MSG_CHECKING([Samba's idmap plugin interface version]) -+ sambalibdir="`$PKG_CONFIG --variable=libdir smbclient`"/samba -+ SAVE_CFLAGS=$CFLAGS -+ SAVE_LIBS=$LIBS -+ CFLAGS="$CFLAGS $SMBCLIENT_CFLAGS -I/usr/include/samba-4.0" -+ LIBS="$LIBS -L${sambalibdir} -lidmap-samba4 -Wl,-rpath ${sambalibdir}" -+ AC_RUN_IFELSE( -+ [AC_LANG_SOURCE([ -+#include -+#include -+#include -+#include -+#include -+ -+struct winbindd_domain; -+ -+/* overwrite some winbind internal functions */ -+struct winbindd_domain *find_domain_from_name(const char *domain_name) -+{ -+ return NULL; -+} -+ -+bool get_global_winbindd_state_offline(void) { -+ return false; -+} -+ -+struct tevent_context *winbind_event_context(void) -+{ -+ return NULL; -+} -+ -+struct idmap_methods; -+ -+NTSTATUS smb_register_idmap(int version, const char *name, struct idmap_methods *methods); -+ -+int main(void) -+{ -+ int v; -+ NTSTATUS ret; -+ -+ /* Check the versions we know about */ -+ for (v = 5; v <= 6; v++) { -+ ret = smb_register_idmap(v, NULL, NULL); -+ if (ret != NT_STATUS_OBJECT_TYPE_MISMATCH) { -+ return v; -+ } -+ } -+ -+ return -1; -+}])], -+ [AC_MSG_ERROR([idmap version test program is not expected to return 0])], -+ [idmap_test_result=$?; AC_MSG_RESULT([idmap test result is: $idmap_test_result])] -+ ) -+ fi -+ -+ CFLAGS=$SAVE_CFLAGS -+ LIBS=$SAVE_LIBS -+ -+ if test $idmap_test_result -eq 5 -o $idmap_test_result -eq 6 ; then -+ idmap_version=$idmap_test_result -+ else -+ AC_MSG_ERROR([Cannot determine Samba's idmap interface version, please use --with-smb-idmap-interface-version]) -+ fi -+ AC_MSG_NOTICE([Samba's idmap interface version: $idmap_version]) -+ AC_DEFINE_UNQUOTED(SMB_IDMAP_INTERFACE_VERSION, $idmap_version, -+ [Detected version of Samba's idmap plugin interface]) - fi -diff --git a/src/lib/winbind_idmap_sss/winbind_idmap_sss.c b/src/lib/winbind_idmap_sss/winbind_idmap_sss.c -index 26f753708303f513e265de465e4d888f84e22b6a..ea5e727c3461524c3af84ea35c6ee032a5948ddf 100644 ---- a/src/lib/winbind_idmap_sss/winbind_idmap_sss.c -+++ b/src/lib/winbind_idmap_sss/winbind_idmap_sss.c -@@ -190,7 +190,13 @@ static struct idmap_methods sss_methods = { - .sids_to_unixids = idmap_sss_sids_to_unixids, - }; - -+#if SMB_IDMAP_INTERFACE_VERSION == 5 - NTSTATUS idmap_sss_init(void) -+#elif SMB_IDMAP_INTERFACE_VERSION == 6 -+NTSTATUS idmap_sss_init(TALLOC_CTX *ctx) -+#else -+#error Unexpected Samba idmpa inferface version -+#endif - { - return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "sss", &sss_methods); - } -diff --git a/src/lib/winbind_idmap_sss/winbind_idmap_sss.h b/src/lib/winbind_idmap_sss/winbind_idmap_sss.h -index 0f27c8561a540b63fb365edb79867eb4eb8d6e21..868049ffff7bd788507bf02d61245ff254aca465 100644 ---- a/src/lib/winbind_idmap_sss/winbind_idmap_sss.h -+++ b/src/lib/winbind_idmap_sss/winbind_idmap_sss.h -@@ -32,6 +32,8 @@ - #include - #include - -+#include "config.h" -+ - /* The following definitions are taken from the Samba header files - * - winbindd/idmap_proto.h - * - idmap.d -@@ -64,7 +66,9 @@ struct id_map { - enum id_mapping status; - }; - --#define SMB_IDMAP_INTERFACE_VERSION 5 -+#ifndef SMB_IDMAP_INTERFACE_VERSION -+#error Missing Samba idmap interface version -+#endif - - struct idmap_domain { - const char *name; --- -2.17.0 - diff --git a/SOURCES/0110-winbind-idmap-plugin-fix-detection.patch b/SOURCES/0110-winbind-idmap-plugin-fix-detection.patch deleted file mode 100644 index ad6b2e6..0000000 --- a/SOURCES/0110-winbind-idmap-plugin-fix-detection.patch +++ /dev/null @@ -1,49 +0,0 @@ -From f2a1f317dfa76ec7b5ff7a218b82f92e2de5f30d Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Fri, 18 May 2018 21:34:44 +0200 -Subject: [PATCH] winbind idmap plugin: fix detection -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Currently when compiling the detection code for the idmap interface -version only SMBCLIENT_CFLAGS are used. Since libsmbclient does not use -NTSTATUS the cflags do not contain '-DHAVE_IMMEDIATE_STRUCTURES=1' which -make NTSTATUS to a struct instead of an integer. Since Samba itself -might be complied with this define (it typically is) we have to make -sure we use it as well. Otherwise the test program might crash on -platforms where this change changes the calling convention as well. - -Related to https://pagure.io/SSSD/sssd/issue/3741 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 095bbe17b25369b967e97162d945cb001a13029e) ---- - src/external/samba.m4 | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/external/samba.m4 b/src/external/samba.m4 -index 610831bf054e3687eb13025e954acf345fca1a00..794cac2461d7fbd5e690ea105cd346cbe6fcce9a 100644 ---- a/src/external/samba.m4 -+++ b/src/external/samba.m4 -@@ -59,7 +59,7 @@ them. In this case, you will need to execute configure script with argument - sambalibdir="`$PKG_CONFIG --variable=libdir smbclient`"/samba - SAVE_CFLAGS=$CFLAGS - SAVE_LIBS=$LIBS -- CFLAGS="$CFLAGS $SMBCLIENT_CFLAGS -I/usr/include/samba-4.0" -+ CFLAGS="$CFLAGS $SMBCLIENT_CFLAGS $NDR_NBT_CFLAGS $NDR_KRB5PAC_CFLAGS -I/usr/include/samba-4.0" - LIBS="$LIBS -L${sambalibdir} -lidmap-samba4 -Wl,-rpath ${sambalibdir}" - AC_RUN_IFELSE( - [AC_LANG_SOURCE([ -@@ -98,7 +98,7 @@ int main(void) - /* Check the versions we know about */ - for (v = 5; v <= 6; v++) { - ret = smb_register_idmap(v, NULL, NULL); -- if (ret != NT_STATUS_OBJECT_TYPE_MISMATCH) { -+ if (!NT_STATUS_EQUAL(ret, NT_STATUS_OBJECT_TYPE_MISMATCH)) { - return v; - } - } --- -2.17.0 - diff --git a/SOURCES/0111-Do-not-keep-allocating-external-groups-on-a-long-liv.patch b/SOURCES/0111-Do-not-keep-allocating-external-groups-on-a-long-liv.patch deleted file mode 100644 index 825aa79..0000000 --- a/SOURCES/0111-Do-not-keep-allocating-external-groups-on-a-long-liv.patch +++ /dev/null @@ -1,59 +0,0 @@ -From d2e17974c6bcb3ae2fc8a2cde696d387385c7d61 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 3 Apr 2018 21:48:37 +0200 -Subject: [PATCH] Do not keep allocating external groups on a long-lived - context -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The hash table with the external groups was never freed, so the -server_mode->ext_groups context was growing over time. - -This patch keeps the new hash on the state if something failed, then -frees the previous hash and finally steals the new hash onto the server -mode. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3719 - -Signed-off-by: Sumit Bose -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 10213efaf1f9f587b47a82778a252d79863f665e) - -DOWNSTREAM: -Resolves: rhbz#1583746 - The SSSD IPA provider allocates information about external groups on a long lived memory context, causing memory growth of the sssd_be process [rhel-7.5.z] ---- - src/providers/ipa/ipa_subdomains_ext_groups.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/src/providers/ipa/ipa_subdomains_ext_groups.c b/src/providers/ipa/ipa_subdomains_ext_groups.c -index 9e1d6c3a9bdeda56b421a2dc9198dff0b84c54ce..63ff7c7d7373a4e6a18fc914eff7ca00d477bca6 100644 ---- a/src/providers/ipa/ipa_subdomains_ext_groups.c -+++ b/src/providers/ipa/ipa_subdomains_ext_groups.c -@@ -583,14 +583,19 @@ static void ipa_get_ext_groups_done(struct tevent_req *subreq) - DEBUG(SSSDBG_TRACE_FUNC, "[%zu] external groups found.\n", - state->reply_count); - -- ret = process_ext_groups(state->server_mode->ext_groups, -- state->reply_count, state->reply, &ext_group_hash); -+ ret = process_ext_groups(state, -+ state->reply_count, -+ state->reply, -+ &ext_group_hash); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "process_ext_groups failed.\n"); - goto fail; - } - -- state->server_mode->ext_groups->ext_groups = ext_group_hash; -+ talloc_free(state->server_mode->ext_groups->ext_groups); -+ state->server_mode->ext_groups->ext_groups = talloc_steal( -+ state->server_mode->ext_groups, -+ ext_group_hash); - /* Do we have to make the update timeout configurable? */ - state->server_mode->ext_groups->next_update = time(NULL) + 10; - --- -2.17.0 - diff --git a/SOURCES/0112-TESTS-Extend-the-schema-with-sshPublicKey-attribute.patch b/SOURCES/0112-TESTS-Extend-the-schema-with-sshPublicKey-attribute.patch deleted file mode 100644 index 5d2d383..0000000 --- a/SOURCES/0112-TESTS-Extend-the-schema-with-sshPublicKey-attribute.patch +++ /dev/null @@ -1,62 +0,0 @@ -From c981d4f4a40ac6cb3650ae1934b0931b0ea5b6f6 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Sun, 17 Jun 2018 21:48:36 +0200 -Subject: [PATCH] TESTS: Extend the schema with sshPublicKey attribute -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This will allow to store the users with a sshPublicKey attribute -provided that they have the right objectclass as well. - -Related to: -https://pagure.io/SSSD/sssd/issue/3747 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 1575ec97e080656f69b3f93e641c76e74ffb8182) - -DOWNSTREAM: -Resolves: rhbz#1594178 - Login with sshkeys stored in ipa not working after update to RHEL-7.5 [rhel-7.5.z] ---- - src/tests/intg/data/ssh_schema.ldif | 11 +++++++++++ - src/tests/intg/ds_openldap.py | 6 ++++++ - 2 files changed, 17 insertions(+) - create mode 100644 src/tests/intg/data/ssh_schema.ldif - -diff --git a/src/tests/intg/data/ssh_schema.ldif b/src/tests/intg/data/ssh_schema.ldif -new file mode 100644 -index 0000000000000000000000000000000000000000..efe05706b9ded5614a7f3f5e0bab28a7eb869daa ---- /dev/null -+++ b/src/tests/intg/data/ssh_schema.ldif -@@ -0,0 +1,11 @@ -+dn: cn=openssh-lpk,cn=schema,cn=config -+objectClass: olcSchemaConfig -+cn: openssh-lpk -+olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' -+ DESC 'MANDATORY: OpenSSH Public key' -+ EQUALITY octetStringMatch -+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 ) -+olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY -+ DESC 'MANDATORY: OpenSSH LPK objectclass' -+ MAY ( sshPublicKey $ uid ) -+ ) -diff --git a/src/tests/intg/ds_openldap.py b/src/tests/intg/ds_openldap.py -index 842ff910803658834841c8f9181f3c4af29b955a..c9a4b6de8c53c6644b3de9047d657ee35ce06512 100644 ---- a/src/tests/intg/ds_openldap.py -+++ b/src/tests/intg/ds_openldap.py -@@ -186,6 +186,12 @@ class DSOpenLDAP(DS): - db_config_file.write(db_config) - db_config_file.close() - -+ # Import ad schema -+ subprocess.check_call( -+ ["slapadd", "-F", self.conf_slapd_d_dir, "-b", "cn=config", -+ "-l", "data/ssh_schema.ldif"], -+ ) -+ - def _start_daemon(self): - """Start the instance.""" - if subprocess.call(["slapd", "-F", self.conf_slapd_d_dir, --- -2.14.4 - diff --git a/SOURCES/0113-TESTS-Allow-adding-sshPublicKey-for-users.patch b/SOURCES/0113-TESTS-Allow-adding-sshPublicKey-for-users.patch deleted file mode 100644 index 630e1b0..0000000 --- a/SOURCES/0113-TESTS-Allow-adding-sshPublicKey-for-users.patch +++ /dev/null @@ -1,78 +0,0 @@ -From db4a80c1e798872d4b1196ef9a768b35e7962d28 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Sun, 17 Jun 2018 22:06:22 +0200 -Subject: [PATCH] TESTS: Allow adding sshPublicKey for users -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adds the objectclass and allows storing a list of sshPublicKey -attributes for users. Since there is no harm in adding the extra -objectclass, we can do it unconditionally. - -Related to: -https://pagure.io/SSSD/sssd/issue/3747 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 56cda832e9f61c52e9cfde1f0864507de718ffbb) ---- - src/tests/intg/ldap_ent.py | 15 +++++++++++---- - 1 file changed, 11 insertions(+), 4 deletions(-) - -diff --git a/src/tests/intg/ldap_ent.py b/src/tests/intg/ldap_ent.py -index 6b6d8f903cbcc277d892c3212ca382f4aaadc671..a4c987969d3dcefba2af69e095b220180e0fa54c 100644 ---- a/src/tests/intg/ldap_ent.py -+++ b/src/tests/intg/ldap_ent.py -@@ -24,7 +24,8 @@ def user(base_dn, uid, uidNumber, gidNumber, - homeDirectory=None, - loginShell=None, - cn=None, -- sn=None): -+ sn=None, -+ sshPubKey=()): - """ - Generate an RFC2307(bis) user add-modlist for passing to ldap.add* - """ -@@ -33,7 +34,8 @@ def user(base_dn, uid, uidNumber, gidNumber, - user = ( - "uid=" + uid + ",ou=Users," + base_dn, - [ -- ('objectClass', [b'top', b'inetOrgPerson', b'posixAccount']), -+ ('objectClass', [b'top', b'inetOrgPerson', -+ b'posixAccount', b'ldapPublicKey']), - ('cn', [uidNumber if cn is None else cn.encode('utf-8')]), - ('sn', [b'User' if sn is None else sn.encode('utf-8')]), - ('uidNumber', [uidNumber]), -@@ -51,6 +53,9 @@ def user(base_dn, uid, uidNumber, gidNumber, - ) - if gecos is not None: - user[1].append(('gecos', [gecos.encode('utf-8')])) -+ if len(sshPubKey) > 0: -+ pubkeys = [key.encode('utf-8') for key in sshPubKey] -+ user[1].append(('sshPublicKey', pubkeys)) - return user - - -@@ -118,7 +123,8 @@ class List(list): - homeDirectory=None, - loginShell=None, - cn=None, -- sn=None): -+ sn=None, -+ sshPubKey=()): - """Add an RFC2307(bis) user add-modlist.""" - self.append(user(base_dn or self.base_dn, - uid, uidNumber, gidNumber, -@@ -127,7 +133,8 @@ class List(list): - homeDirectory=homeDirectory, - loginShell=loginShell, - cn=cn, -- sn=sn)) -+ sn=sn, -+ sshPubKey=sshPubKey)) - - def add_group(self, cn, gidNumber, member_uids=[], - base_dn=None): --- -2.14.4 - diff --git a/SOURCES/0114-TESTS-Add-a-basic-SSH-responder-test.patch b/SOURCES/0114-TESTS-Add-a-basic-SSH-responder-test.patch deleted file mode 100644 index 8dbcf01..0000000 --- a/SOURCES/0114-TESTS-Add-a-basic-SSH-responder-test.patch +++ /dev/null @@ -1,276 +0,0 @@ -From 612dda4bbd706be9e7c3674e4d0420f9ebd1ea83 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 18 Jun 2018 09:12:13 +0200 -Subject: [PATCH] TESTS: Add a basic SSH responder test -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adds a basic test that makes sure that a list of SSH public keys can be -retrieved. This is to make sure we don't break the SSH integration later -on. - -Related: -https://pagure.io/SSSD/sssd/issue/3747 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 804c5b538ad89a1a3897b93f39d716fa50530842) ---- - src/tests/intg/Makefile.am | 1 + - src/tests/intg/test_ssh_pubkey.py | 232 ++++++++++++++++++++++++++++++++++++++ - 2 files changed, 233 insertions(+) - create mode 100644 src/tests/intg/test_ssh_pubkey.py - -diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am -index 209e5a0c73db99b11aa6967f30db23933d21acb0..285ce21f04dddb6388c595470eac8f31bc224a60 100644 ---- a/src/tests/intg/Makefile.am -+++ b/src/tests/intg/Makefile.am -@@ -35,6 +35,7 @@ dist_noinst_DATA = \ - data/ad_data.ldif \ - data/ad_schema.ldif \ - test_pysss_nss_idmap.py \ -+ test_ssh_pubkey.py \ - $(NULL) - - config.py: config.py.m4 -diff --git a/src/tests/intg/test_ssh_pubkey.py b/src/tests/intg/test_ssh_pubkey.py -new file mode 100644 -index 0000000000000000000000000000000000000000..fbf55566e341373873057ec4e3af1d7f83202aa7 ---- /dev/null -+++ b/src/tests/intg/test_ssh_pubkey.py -@@ -0,0 +1,232 @@ -+# -+# ssh public key integration test -+# -+# Copyright (c) 2018 Red Hat, Inc. -+# -+# This 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; version 2 only -+# -+# 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 . -+# -+ -+import os -+import stat -+import signal -+import subprocess -+import time -+import ldap -+import ldap.modlist -+import pytest -+ -+import config -+import ds_openldap -+import ent -+import ldap_ent -+from util import unindent, get_call_output -+ -+LDAP_BASE_DN = "dc=example,dc=com" -+ -+USER1_PUBKEY1 = "ssh-dss AAAAB3NzaC1kc3MAAACBAPMkvcU53RVhBtjwiC3IqeRIWR9Qwdv8\ -+DmZzEsDD3Csd6jYxMsPZoXcPrHqwYcEj1s5MVqhdSFS0Cjz13e7gO6OMLInO3xMBSSFHjfp9RE1H\ -+pgc4WisazzyJaW9EMkQo/DqvkFkKh31oqAmxcSbLAFJRg4TTIqm18qu8IRKS6m/RAAAAFQC97TA5\ -+JSsMsaX1bRszC7y4PhMBvQAAAIEAt9Yo9v/h9W4nDbzUdkGwNRszlPEK+T12bJv0O9Fk6subD3Do\ -+6A4Qru/Nr6voXoq8b018Wb7iFWvKOoz5uT/plWBKLXL2NN7ovTR+dUJIzvwurQZroukmU1EghNey\ -+lkSHmDlxSoMK6Nh21uGu6l+b6x5pXNaZHMpsywG4kY8SoC0AAACAAWLHneEGvqkYA8La4Eob+Hjj\ -+mAKilx8byxm3Kfb1XO+ZrR6XxadofZOaUYRMpPKgFjKAKPxJftPLiDjWM7lSe6h8df0dUMLVXt6m\ -+eA83kE0uK5JOOGJfJDqmRed2YnfxUDNNFQGT4xFWGrNtYNbGyw9BWKbkooAsLqaO04zP3Rs= \ -+user1@LDAP" -+ -+USER1_PUBKEY2 = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAwHUUF3HPH+DkU6j8k7Q1wHG\ -+RJY9NeLqSav3h95mTSCQYPSC7I9RTJ4OORgqCbEzrP/DYrrn4TtQ9dhRJar3ZY+F36SH5yFIXORb\ -+lAIbFU+/anahBuFS9vHi1MqFPckGmwJ4QCpjQhdYxo1ro0e1RuGSaQNp/w9N6S/fDz4Cj4I99xDz\ -+SeQeGHxYv0e60plQ8dUajmnaGmYRJHF9a6Ban7IWySActCja7eQP2zIRXEZMpuhl1E0U4y+gHTFI\ -+gD3zQai3QrXm8RUrQURIJ0u6BlGS910OPbHqLpLTFWG08L8sNUcYzC+DY6yoCSO0n/Df3pVRS4C9\ -+5Krf3FqppMTjdfQ== user1@LDAP" -+ -+ -+@pytest.fixture(scope="module") -+def ds_inst(request): -+ """LDAP server instance fixture""" -+ ds_inst = ds_openldap.DSOpenLDAP( -+ config.PREFIX, 10389, LDAP_BASE_DN, -+ "cn=admin", "Secret123" -+ ) -+ -+ try: -+ ds_inst.setup() -+ except: -+ ds_inst.teardown() -+ raise -+ request.addfinalizer(ds_inst.teardown) -+ return ds_inst -+ -+ -+@pytest.fixture(scope="module") -+def ldap_conn(request, ds_inst): -+ """LDAP server connection fixture""" -+ ldap_conn = ds_inst.bind() -+ ldap_conn.ds_inst = ds_inst -+ request.addfinalizer(ldap_conn.unbind_s) -+ return ldap_conn -+ -+ -+def create_ldap_entries(ldap_conn, ent_list=None): -+ """Add LDAP entries from ent_list""" -+ if ent_list is not None: -+ for entry in ent_list: -+ ldap_conn.add_s(entry[0], entry[1]) -+ -+ -+def cleanup_ldap_entries(ldap_conn, ent_list=None): -+ """Remove LDAP entries added by create_ldap_entries""" -+ if ent_list is None: -+ for ou in ("Users", "Groups", "Netgroups", "Services", "Policies"): -+ for entry in ldap_conn.search_s("ou=" + ou + "," + -+ ldap_conn.ds_inst.base_dn, -+ ldap.SCOPE_ONELEVEL, -+ attrlist=[]): -+ ldap_conn.delete_s(entry[0]) -+ else: -+ for entry in ent_list: -+ ldap_conn.delete_s(entry[0]) -+ -+ -+def create_ldap_cleanup(request, ldap_conn, ent_list=None): -+ """Add teardown for removing all user/group LDAP entries""" -+ request.addfinalizer(lambda: cleanup_ldap_entries(ldap_conn, ent_list)) -+ -+ -+def create_ldap_fixture(request, ldap_conn, ent_list=None): -+ """Add LDAP entries and add teardown for removing them""" -+ create_ldap_entries(ldap_conn, ent_list) -+ create_ldap_cleanup(request, ldap_conn, ent_list) -+ -+ -+SCHEMA_RFC2307_BIS = "rfc2307bis" -+ -+ -+def format_basic_conf(ldap_conn, schema): -+ """Format a basic SSSD configuration""" -+ schema_conf = "ldap_schema = " + schema + "\n" -+ schema_conf += "ldap_group_object_class = groupOfNames\n" -+ return unindent("""\ -+ [sssd] -+ domains = LDAP -+ services = nss, ssh -+ -+ [nss] -+ -+ [ssh] -+ debug_level=10 -+ -+ [domain/LDAP] -+ {schema_conf} -+ id_provider = ldap -+ auth_provider = ldap -+ ldap_uri = {ldap_conn.ds_inst.ldap_url} -+ ldap_search_base = {ldap_conn.ds_inst.base_dn} -+ ldap_sudo_use_host_filter = false -+ debug_level=10 -+ """).format(**locals()) -+ -+ -+def create_conf_file(contents): -+ """Create sssd.conf with specified contents""" -+ conf = open(config.CONF_PATH, "w") -+ conf.write(contents) -+ conf.close() -+ os.chmod(config.CONF_PATH, stat.S_IRUSR | stat.S_IWUSR) -+ -+ -+def cleanup_conf_file(): -+ """Remove sssd.conf, if it exists""" -+ if os.path.lexists(config.CONF_PATH): -+ os.unlink(config.CONF_PATH) -+ -+ -+def create_conf_cleanup(request): -+ """Add teardown for removing sssd.conf""" -+ request.addfinalizer(cleanup_conf_file) -+ -+ -+def create_conf_fixture(request, contents): -+ """ -+ Create sssd.conf with specified contents and add teardown for removing it -+ """ -+ create_conf_file(contents) -+ create_conf_cleanup(request) -+ -+ -+def create_sssd_process(): -+ """Start the SSSD process""" -+ if subprocess.call(["sssd", "-D", "-f"]) != 0: -+ raise Exception("sssd start failed") -+ -+ -+def get_sssd_pid(): -+ pid_file = open(config.PIDFILE_PATH, "r") -+ pid = int(pid_file.read()) -+ return pid -+ -+ -+def cleanup_sssd_process(): -+ """Stop the SSSD process and remove its state""" -+ try: -+ pid = get_sssd_pid() -+ os.kill(pid, signal.SIGTERM) -+ while True: -+ try: -+ os.kill(pid, signal.SIGCONT) -+ except: -+ break -+ time.sleep(1) -+ except: -+ pass -+ for path in os.listdir(config.DB_PATH): -+ os.unlink(config.DB_PATH + "/" + path) -+ for path in os.listdir(config.MCACHE_PATH): -+ os.unlink(config.MCACHE_PATH + "/" + path) -+ -+ -+def create_sssd_fixture(request): -+ """Start SSSD and add teardown for stopping it and removing its state""" -+ create_sssd_process() -+ create_sssd_cleanup(request) -+ -+ -+def create_sssd_cleanup(request): -+ """Add teardown for stopping SSSD and removing its state""" -+ request.addfinalizer(cleanup_sssd_process) -+ -+ -+@pytest.fixture -+def add_user_with_ssh_key(request, ldap_conn): -+ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) -+ ent_list.add_user("user1", 1001, 2001, -+ sshPubKey=(USER1_PUBKEY1, USER1_PUBKEY2)) -+ ent_list.add_user("user2", 1002, 2001) -+ create_ldap_fixture(request, ldap_conn, ent_list) -+ -+ conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) -+ create_conf_fixture(request, conf) -+ create_sssd_fixture(request) -+ return None -+ -+ -+def test_ssh_pubkey_retrieve(add_user_with_ssh_key): -+ """ -+ Test that we can retrieve an SSH public key for a user who has one -+ and can't retrieve a key for a user who does not have one. -+ """ -+ sshpubkey = get_call_output(["sss_ssh_authorizedkeys", "user1"]) -+ assert sshpubkey == USER1_PUBKEY1 + '\n' + USER1_PUBKEY2 + '\n' -+ -+ sshpubkey = get_call_output(["sss_ssh_authorizedkeys", "user2"]) -+ assert len(sshpubkey) == 0 --- -2.14.4 - diff --git a/SOURCES/0115-SSH-Do-not-exit-abruptly-if-SSHD-closes-its-end-of-t.patch b/SOURCES/0115-SSH-Do-not-exit-abruptly-if-SSHD-closes-its-end-of-t.patch deleted file mode 100644 index 711e447..0000000 --- a/SOURCES/0115-SSH-Do-not-exit-abruptly-if-SSHD-closes-its-end-of-t.patch +++ /dev/null @@ -1,88 +0,0 @@ -From d1b01f0a04e54c55183fd5cee4b713e28e4e2cd7 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 28 May 2018 21:41:49 +0200 -Subject: [PATCH] SSH: Do not exit abruptly if SSHD closes its end of the pipe - before reading all the SSH keys -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Resolves: -https://pagure.io/SSSD/sssd/issue/3747 - -Before writing the keys to sshd, ignore SIGPIPE so that if the pipe -towards the authorizedkeys helper is closed, the sss_ssh_authorizedkeys -helper is not terminated with SIGPIPE, but instead proceeds and then the -write(2) calls would non-terminally fail with EPIPE. - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit cb138d7d060611e891d341db08477e41f9a3d17d) ---- - src/sss_client/ssh/sss_ssh_authorizedkeys.c | 35 ++++++++++++++++++++++++++++- - 1 file changed, 34 insertions(+), 1 deletion(-) - -diff --git a/src/sss_client/ssh/sss_ssh_authorizedkeys.c b/src/sss_client/ssh/sss_ssh_authorizedkeys.c -index 782a9f44379bff5346c896b3e03570720632c0be..b0280fbf8b0ed0501d792973241b826fc4a7a04d 100644 ---- a/src/sss_client/ssh/sss_ssh_authorizedkeys.c -+++ b/src/sss_client/ssh/sss_ssh_authorizedkeys.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - - #include "util/util.h" - #include "util/crypto/sss_crypto.h" -@@ -99,8 +100,16 @@ int main(int argc, const char **argv) - goto fini; - } - -+ /* if sshd closes its end of the pipe, we don't want sss_ssh_authorizedkeys -+ * to exit abruptly, but to finish gracefully instead because the valid -+ * key can be present in the data already written -+ */ -+ signal(SIGPIPE, SIG_IGN); -+ - /* print results */ - for (i = 0; i < ent->num_pubkeys; i++) { -+ char *repr_break = NULL; -+ - ret = sss_ssh_format_pubkey(mem_ctx, &ent->pubkeys[i], &repr); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, -@@ -109,7 +118,31 @@ int main(int argc, const char **argv) - continue; - } - -- printf("%s\n", repr); -+ /* OpenSSH expects a linebreak after each key */ -+ repr_break = talloc_asprintf(mem_ctx, "%s\n", repr); -+ talloc_zfree(repr); -+ if (repr_break == NULL) { -+ ret = ENOMEM; -+ goto fini; -+ } -+ -+ ret = sss_atomic_write_s(STDOUT_FILENO, repr_break, strlen(repr_break)); -+ /* Avoid spiking memory with too many large keys */ -+ talloc_zfree(repr_break); -+ if (ret < 0) { -+ ret = errno; -+ if (ret == EPIPE) { -+ DEBUG(SSSDBG_MINOR_FAILURE, -+ "SSHD closed the pipe before all keys could be written\n"); -+ /* Return 0 so that openssh doesn't abort pubkey auth */ -+ ret = 0; -+ goto fini; -+ } -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "sss_atomic_write_s() failed (%d): %s\n", -+ ret, strerror(ret)); -+ goto fini; -+ } - } - - ret = EXIT_SUCCESS; --- -2.14.4 - diff --git a/SOURCES/0116-TESTS-Add-a-helper-binary-that-can-trigger-the-SIGPI.patch b/SOURCES/0116-TESTS-Add-a-helper-binary-that-can-trigger-the-SIGPI.patch deleted file mode 100644 index 494b327..0000000 --- a/SOURCES/0116-TESTS-Add-a-helper-binary-that-can-trigger-the-SIGPI.patch +++ /dev/null @@ -1,213 +0,0 @@ -From 187b9f28f1ea2e3fa4b5e3385050701fdc1d0f69 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Mon, 28 May 2018 21:49:41 +0200 -Subject: [PATCH] TESTS: Add a helper binary that can trigger the SIGPIPE to - authorizedkeys -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Adds a test tool that simulates the behaviour of OpenSSH in the sense -that it starts to read the output from the sss_ssh_authorizedkeys tool, -but then closes the pipe before reading the whole output. - -Related: -https://pagure.io/SSSD/sssd/issue/3747 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 909c16edb26a3c48b10a49e7919a35d13d31c52e) ---- - Makefile.am | 15 ++++- - src/tests/test_ssh_client.c | 133 ++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 147 insertions(+), 1 deletion(-) - create mode 100644 src/tests/test_ssh_client.c - -diff --git a/Makefile.am b/Makefile.am -index 5917bd904054055a259eb69217282e4fb914c700..01fa4e43e48dcb722056d614e19f02687d32014b 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -331,6 +331,7 @@ endif # HAVE_CMOCKA - check_PROGRAMS = \ - stress-tests \ - krb5-child-test \ -+ test_ssh_client \ - $(non_interactive_cmocka_based_tests) \ - $(non_interactive_check_based_tests) - -@@ -2294,6 +2295,18 @@ krb5_child_test_LDADD = \ - $(SSSD_INTERNAL_LTLIBS) \ - libsss_test_common.la - -+test_ssh_client_SOURCES = \ -+ src/tests/test_ssh_client.c \ -+ $(NULL) -+test_ssh_client_CFLAGS = \ -+ $(AM_CFLAGS) \ -+ -DSSH_CLIENT_DIR=\"$(abs_top_builddir)\" \ -+ $(NULL) -+test_ssh_client_LDADD = \ -+ $(SSSD_INTERNAL_LTLIBS) \ -+ $(SSSD_LIBS) \ -+ $(NULL) -+ - if BUILD_DBUS_TESTS - - sbus_tests_SOURCES = \ -@@ -3418,7 +3431,6 @@ test_iobuf_LDADD = \ - $(SSSD_LIBS) \ - $(NULL) - -- - EXTRA_simple_access_tests_DEPENDENCIES = \ - $(ldblib_LTLIBRARIES) - simple_access_tests_SOURCES = \ -@@ -3607,6 +3619,7 @@ intgcheck-prepare: - $(INTGCHECK_CONFIGURE_FLAGS) \ - CFLAGS="$$CFLAGS -DKCM_PEER_UID=$$(id -u)"; \ - $(MAKE) $(AM_MAKEFLAGS) ; \ -+ $(MAKE) $(AM_MAKEFLAGS) test_ssh_client; \ - : Force single-thread install to workaround concurrency issues; \ - $(MAKE) $(AM_MAKEFLAGS) -j1 install; \ - : Remove .la files from LDB module directory to avoid loader warnings; \ -diff --git a/src/tests/test_ssh_client.c b/src/tests/test_ssh_client.c -new file mode 100644 -index 0000000000000000000000000000000000000000..8f963941f3249561178436d6f6dfc376780a4cda ---- /dev/null -+++ b/src/tests/test_ssh_client.c -@@ -0,0 +1,133 @@ -+/* -+ 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 -+#include "util/util.h" -+ -+#ifdef SSH_CLIENT_DIR -+#define SSH_AK_CLIENT_PATH SSH_CLIENT_DIR"/sss_ssh_authorizedkeys" -+#else -+#error "The path to the ssh authorizedkeys helper is not defined" -+#endif /* SSH_CLIENT_DIR */ -+ -+int main(int argc, const char *argv[]) -+{ -+ poptContext pc; -+ int opt; -+ struct poptOption long_options[] = { -+ POPT_AUTOHELP -+ SSSD_DEBUG_OPTS -+ POPT_TABLEEND -+ }; -+ struct stat sb; -+ int ret; -+ int status; -+ int p[2]; -+ pid_t pid; -+ const char *pc_user = NULL; -+ char *av[3]; -+ char buf[5]; /* Ridiculously small buffer by design */ -+ -+ /* 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); -+ poptSetOtherOptionHelp(pc, "USER"); -+ 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 3; -+ } -+ } -+ -+ pc_user = poptGetArg(pc); -+ if (pc_user == NULL) { -+ fprintf(stderr, "No user specified\n"); -+ return 3; -+ } -+ -+ poptFreeContext(pc); -+ -+ DEBUG_CLI_INIT(debug_level); -+ -+ ret = stat(SSH_AK_CLIENT_PATH, &sb); -+ if (ret != 0) { -+ ret = errno; -+ DEBUG(SSSDBG_CRIT_FAILURE, -+ "Could not stat %s [%d]: %s\n", -+ SSH_AK_CLIENT_PATH, ret, strerror(ret)); -+ return 3; -+ } -+ -+ ret = pipe(p); -+ if (ret != 0) { -+ perror("pipe"); -+ return 3; -+ } -+ -+ switch (pid = fork()) { -+ case -1: -+ ret = errno; -+ close(p[0]); -+ close(p[1]); -+ DEBUG(SSSDBG_CRIT_FAILURE, "fork failed: %d\n", ret); -+ return 3; -+ case 0: -+ /* child */ -+ av[0] = discard_const(SSH_AK_CLIENT_PATH); -+ av[1] = discard_const(pc_user); -+ av[2] = NULL; -+ -+ close(p[0]); -+ ret = dup2(p[1], STDOUT_FILENO); -+ if (ret == -1) { -+ perror("dup2"); -+ return 3; -+ } -+ -+ execv(av[0], av); -+ return 3; -+ default: -+ /* parent */ -+ break; -+ } -+ -+ close(p[1]); -+ read(p[0], buf, sizeof(buf)); -+ close(p[0]); -+ -+ pid = waitpid(pid, &status, 0); -+ if (pid == -1) { -+ perror("waitpid"); -+ return 3; -+ } -+ -+ if (WIFEXITED(status)) { -+ printf("sss_ssh_authorizedkeys exited with return code %d\n", WEXITSTATUS(status)); -+ return 0; -+ } else if (WIFSIGNALED(status)) { -+ printf("sss_ssh_authorizedkeys exited with signal %d\n", WTERMSIG(status)); -+ return 1; -+ } -+ -+ printf("sss_ssh_authorizedkeys exited for another reason\n"); -+ return 2; -+} --- -2.14.4 - diff --git a/SOURCES/0117-TESTS-Add-a-regression-test-for-SIGHUP-handling-in-s.patch b/SOURCES/0117-TESTS-Add-a-regression-test-for-SIGHUP-handling-in-s.patch deleted file mode 100644 index c791974..0000000 --- a/SOURCES/0117-TESTS-Add-a-regression-test-for-SIGHUP-handling-in-s.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 103a22b85df5c371aefb08e476a3ab950e6882a3 Mon Sep 17 00:00:00 2001 -From: Jakub Hrozek -Date: Tue, 19 Jun 2018 11:39:02 +0200 -Subject: [PATCH] TESTS: Add a regression test for SIGHUP handling in - sss_ssh_authorizedkeys -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -A regression test for: -https://pagure.io/SSSD/sssd/issue/3747 - -Reviewed-by: Fabiano Fidêncio -(cherry picked from commit 4cc3c1a1b1070c12bcc4351880d8207e47b37496) ---- - src/tests/intg/test_ssh_pubkey.py | 58 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 58 insertions(+) - -diff --git a/src/tests/intg/test_ssh_pubkey.py b/src/tests/intg/test_ssh_pubkey.py -index fbf55566e341373873057ec4e3af1d7f83202aa7..8fb41c62d87ec210c9aad8582023fe1cb00f2b4e 100644 ---- a/src/tests/intg/test_ssh_pubkey.py -+++ b/src/tests/intg/test_ssh_pubkey.py -@@ -24,6 +24,8 @@ import time - import ldap - import ldap.modlist - import pytest -+import string -+import random - - import config - import ds_openldap -@@ -230,3 +232,59 @@ def test_ssh_pubkey_retrieve(add_user_with_ssh_key): - - sshpubkey = get_call_output(["sss_ssh_authorizedkeys", "user2"]) - assert len(sshpubkey) == 0 -+ -+ -+@pytest.fixture() -+def sighup_client(request): -+ test_ssh_cli_path = os.path.join(config.ABS_BUILDDIR, -+ "..", "..", "..", "test_ssh_client") -+ assert os.access(test_ssh_cli_path, os.X_OK) -+ return test_ssh_cli_path -+ -+ -+@pytest.fixture -+def add_user_with_many_keys(request, ldap_conn): -+ # Generate a large list of unique ssh pubkeys -+ pubkey_list = [] -+ while len(pubkey_list) < 50: -+ new_pubkey = list(USER1_PUBKEY1) -+ new_pubkey[10] = random.choice(string.ascii_uppercase) -+ new_pubkey[11] = random.choice(string.ascii_uppercase) -+ new_pubkey[12] = random.choice(string.ascii_uppercase) -+ str_new_pubkey = ''.join(c for c in new_pubkey) -+ if str_new_pubkey in pubkey_list: -+ continue -+ pubkey_list.append(str_new_pubkey) -+ -+ ent_list = ldap_ent.List(ldap_conn.ds_inst.base_dn) -+ ent_list.add_user("user1", 1001, 2001, sshPubKey=pubkey_list) -+ create_ldap_fixture(request, ldap_conn, ent_list) -+ -+ conf = format_basic_conf(ldap_conn, SCHEMA_RFC2307_BIS) -+ create_conf_fixture(request, conf) -+ create_sssd_fixture(request) -+ return None -+ -+ -+def test_ssh_sighup(add_user_with_many_keys, sighup_client): -+ """ -+ A regression test for https://pagure.io/SSSD/sssd/issue/3747 -+ -+ OpenSSH can close its end of the pipe towards sss_ssh_authorizedkeys -+ before all of the output is read. In that case, older versions -+ of sss_ssh_authorizedkeys were receiving a SIGPIPE -+ """ -+ cli_path = sighup_client -+ -+ # python actually does the sensible, but unexpected (for a C programmer) -+ # thing and handles SIGPIPE. In order to reproduce the bug, we need -+ # to unset the SIGPIPE handler -+ signal.signal(signal.SIGPIPE, signal.SIG_DFL) -+ -+ process = subprocess.Popen([cli_path, "user1"], -+ stdout=subprocess.PIPE, -+ stderr=subprocess.PIPE) -+ _, _ = process.communicate() -+ # If the test tool detects that sss_ssh_authorizedkeys was killed with a -+ # signal, it would have returned 1 -+ assert process.returncode == 0 --- -2.14.4 - diff --git a/SOURCES/0118-TESTS-Order-list-of-entries-in-some-lists.patch b/SOURCES/0118-TESTS-Order-list-of-entries-in-some-lists.patch deleted file mode 100644 index 8e7ca54..0000000 --- a/SOURCES/0118-TESTS-Order-list-of-entries-in-some-lists.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 1a73dbe9747aec2818fabd179e0fb46695d66433 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Michal=20=C5=BDidek?= -Date: Mon, 13 Nov 2017 16:15:21 +0100 -Subject: [PATCH] TESTS: Order list of entries in some lists -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Some tests started to fail because we depended on specific -order of users in groups or messages in ldb results to be -returned and that order changed. - -This patch adds a simple helper functions into these tests -that order the entries before comparison with expected results. -more deterministic. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3563 - -Reviewed-by: Lukáš Slebodník -(cherry picked from commit caae0e53e6091806634943699f4398b6a20273b4) - -DOWNSTREAM: -Resolves: rhbz#1596292 - home dir disappear in sssd cache on the IPA master for AD users [rhel-7.5.z] ---- - src/tests/cmocka/test_nss_srv.c | 22 +++++++++++++++++++ - src/tests/cmocka/test_sysdb_views.c | 42 ++++++++++++++++++++++++++++++++----- - 2 files changed, 59 insertions(+), 5 deletions(-) - -diff --git a/src/tests/cmocka/test_nss_srv.c b/src/tests/cmocka/test_nss_srv.c -index 6aa726153183b5a871a75d398727ea7132358ca6..21bd80fb7f6562f6a31452bac6a26c109fef4cb1 100644 ---- a/src/tests/cmocka/test_nss_srv.c -+++ b/src/tests/cmocka/test_nss_srv.c -@@ -585,6 +585,25 @@ static errno_t delete_group(struct nss_test_ctx *ctx, - return ret; - } - -+static int cmp_func(const void *a, const void *b) -+{ -+ char *str1 = *(char **)discard_const(a); -+ char *str2 = *(char **)discard_const(b); -+ -+ return strcmp(str1, str2); -+} -+ -+static void order_string_array(char **_list, int size) -+{ -+ if (size < 2 || _list == NULL || *_list == NULL) { -+ /* Nothing to do */ -+ return; -+ } -+ -+ qsort(_list, size, sizeof(char *), cmp_func); -+ return; -+} -+ - static void assert_groups_equal(struct group *expected, - struct group *gr, const int nmem) - { -@@ -594,6 +613,9 @@ static void assert_groups_equal(struct group *expected, - assert_string_equal(gr->gr_name, expected->gr_name); - assert_string_equal(gr->gr_passwd, expected->gr_passwd); - -+ order_string_array(gr->gr_mem, nmem); -+ order_string_array(expected->gr_mem, nmem); -+ - for (i = 0; i < nmem; i++) { - assert_string_equal(gr->gr_mem[i], expected->gr_mem[i]); - } -diff --git a/src/tests/cmocka/test_sysdb_views.c b/src/tests/cmocka/test_sysdb_views.c -index 0378254b4440b29c3182faf2adde8c3db8a4ce97..dd3eb50f9310ff925734dcf51a669d08a638aefd 100644 ---- a/src/tests/cmocka/test_sysdb_views.c -+++ b/src/tests/cmocka/test_sysdb_views.c -@@ -22,6 +22,7 @@ - along with this program. If not, see . - */ - -+#include - #include - #include - #include -@@ -612,6 +613,31 @@ static int test_enum_users_setup(void **state) - return 0; - } - -+static int cmp_func(const void *a, const void *b) -+{ -+ const char *str1; -+ const char *str2; -+ struct ldb_message *msg1 = *(struct ldb_message **)discard_const(a); -+ struct ldb_message *msg2 = *(struct ldb_message **)discard_const(b); -+ -+ str1 = ldb_msg_find_attr_as_string(msg1, SYSDB_NAME, NULL); -+ str2 = ldb_msg_find_attr_as_string(msg2, SYSDB_NAME, NULL); -+ -+ return strcmp(str1, str2); -+} -+ -+/* Make the order of ldb results deterministic */ -+static void order_ldb_res_msgs(struct ldb_result *res) -+{ -+ if (res == NULL || res->count < 2) { -+ /* Nothing to do */ -+ return; -+ } -+ -+ qsort(res->msgs, res->count, sizeof(struct ldb_message *), cmp_func); -+ return; -+} -+ - static void assert_user_attrs(struct ldb_message *msg, - struct sss_domain_info *dom, - const char *shortname, -@@ -660,8 +686,9 @@ static void check_enumpwent(int ret, struct sss_domain_info *dom, - assert_int_equal(ret, EOK); - assert_int_equal(res->count, N_ELEMENTS(users)-1); - -- assert_user_attrs(res->msgs[0], dom, "barney", views); -- assert_user_attrs(res->msgs[1], dom, "alice", views); -+ order_ldb_res_msgs(res); -+ assert_user_attrs(res->msgs[0], dom, "alice", views); -+ assert_user_attrs(res->msgs[1], dom, "barney", views); - assert_user_attrs(res->msgs[2], dom, "bob", views); - } - -@@ -703,6 +730,7 @@ static void test_sysdb_enumpwent_filter(void **state) - ret = sysdb_enumpwent_filter(test_ctx, test_ctx->domain, "b*", 0, &res); - assert_int_equal(ret, EOK); - assert_int_equal(res->count, 2); -+ order_ldb_res_msgs(res); - assert_user_attrs(res->msgs[0], test_ctx->domain, "barney", false); - assert_user_attrs(res->msgs[1], test_ctx->domain, "bob", false); - -@@ -749,6 +777,7 @@ static void test_sysdb_enumpwent_filter_views(void **state) - "b*", NULL, &res); - assert_int_equal(ret, EOK); - assert_int_equal(res->count, 2); -+ order_ldb_res_msgs(res); - assert_user_attrs(res->msgs[0], test_ctx->domain, "barney", true); - assert_user_attrs(res->msgs[1], test_ctx->domain, "bob", true); - -@@ -896,10 +925,11 @@ static void check_enumgrent(int ret, struct sss_domain_info *dom, - { - assert_int_equal(ret, EOK); - assert_int_equal(res->count, N_ELEMENTS(groups)-1); -- assert_group_attrs(res->msgs[0], dom, "three", -- views ? TEST_GID_OVERRIDE_BASE + 2 : 0); -- assert_group_attrs(res->msgs[1], dom, "one", -+ order_ldb_res_msgs(res); -+ assert_group_attrs(res->msgs[0], dom, "one", - views ? TEST_GID_OVERRIDE_BASE : 0); -+ assert_group_attrs(res->msgs[1], dom, "three", -+ views ? TEST_GID_OVERRIDE_BASE + 2 : 0); - assert_group_attrs(res->msgs[2], dom, "two", - views ? TEST_GID_OVERRIDE_BASE + 1 : 0); - } -@@ -942,6 +972,7 @@ static void test_sysdb_enumgrent_filter(void **state) - ret = sysdb_enumgrent_filter(test_ctx, test_ctx->domain, "t*", 0, &res); - assert_int_equal(ret, EOK); - assert_int_equal(res->count, 2); -+ order_ldb_res_msgs(res); - assert_group_attrs(res->msgs[0], test_ctx->domain, "three", 0); - assert_group_attrs(res->msgs[1], test_ctx->domain, "two", 0); - -@@ -988,6 +1019,7 @@ static void test_sysdb_enumgrent_filter_views(void **state) - "t*", NULL, &res); - assert_int_equal(ret, EOK); - assert_int_equal(res->count, 2); -+ order_ldb_res_msgs(res); - assert_group_attrs(res->msgs[0], test_ctx->domain, - "three", TEST_GID_OVERRIDE_BASE + 2); - assert_group_attrs(res->msgs[1], test_ctx->domain, "two", --- -2.14.4 - diff --git a/SOURCES/0119-sysdb-add-sysdb_getgrgid_attrs.patch b/SOURCES/0119-sysdb-add-sysdb_getgrgid_attrs.patch deleted file mode 100644 index 747a123..0000000 --- a/SOURCES/0119-sysdb-add-sysdb_getgrgid_attrs.patch +++ /dev/null @@ -1,171 +0,0 @@ -From f46dc8010a7d5fbb398e282d680703e1bd5963f4 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 29 May 2018 15:33:34 +0200 -Subject: [PATCH] sysdb: add sysdb_getgrgid_attrs() - -sysdb_getgrgid() is the only MPG aware by GID request but only supports -a fixes set of attributes. The new call allows to add additional -arguments. - -Related to https://pagure.io/SSSD/sssd/issue/3748 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 8aa56a9e8744a7611fa26a254c4f9228e919c8ed) ---- - src/db/sysdb.h | 6 ++++++ - src/db/sysdb_ops.c | 3 +++ - src/db/sysdb_search.c | 31 ++++++++++++++++++++++++++----- - src/tests/sysdb-tests.c | 37 +++++++++++++++++++++++++++++++++++++ - 4 files changed, 72 insertions(+), 5 deletions(-) - -diff --git a/src/db/sysdb.h b/src/db/sysdb.h -index 2660314a75a574d7f5625c8672e5261587056d1a..affd1c9053e43ff24c98cc8fb23eec2c4b69f955 100644 ---- a/src/db/sysdb.h -+++ b/src/db/sysdb.h -@@ -779,6 +779,12 @@ int sysdb_getgrgid(TALLOC_CTX *mem_ctx, - gid_t gid, - struct ldb_result **res); - -+int sysdb_getgrgid_attrs(TALLOC_CTX *mem_ctx, -+ struct sss_domain_info *domain, -+ gid_t gid, -+ const char **attrs, -+ struct ldb_result **res); -+ - int sysdb_enumgrent(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - struct ldb_result **res); -diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c -index 024683317cab99743681db804f7026c8dbb33a38..c0d343bdabd324cbe8b9745c65c2a6e5a56321e1 100644 ---- a/src/db/sysdb_ops.c -+++ b/src/db/sysdb_ops.c -@@ -709,6 +709,9 @@ int sysdb_search_group_by_name(TALLOC_CTX *mem_ctx, - return sysdb_search_by_name(mem_ctx, domain, name, SYSDB_GROUP, attrs, msg); - } - -+/* Please note that sysdb_search_group_by_gid() is not aware of MPGs. If MPG -+ * support is needed either the caller must handle it or sysdb_getgrgid() or -+ * sysdb_getgrgid_attrs() should be used. */ - int sysdb_search_group_by_gid(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - gid_t gid, -diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c -index 9f37cbcd50a778145518c15b6146ad812a5b4fa3..3d78a38b36e65febd50e41fc1d1be29eceeb7649 100644 ---- a/src/db/sysdb_search.c -+++ b/src/db/sysdb_search.c -@@ -1036,24 +1036,37 @@ done: - return ret; - } - --int sysdb_getgrgid(TALLOC_CTX *mem_ctx, -- struct sss_domain_info *domain, -- gid_t gid, -- struct ldb_result **_res) -+int sysdb_getgrgid_attrs(TALLOC_CTX *mem_ctx, -+ struct sss_domain_info *domain, -+ gid_t gid, -+ const char **additional_attrs, -+ struct ldb_result **_res) - { - TALLOC_CTX *tmp_ctx; - unsigned long int ul_gid = gid; -- static const char *attrs[] = SYSDB_GRSRC_ATTRS; - const char *fmt_filter; - struct ldb_dn *base_dn; - struct ldb_result *res; - int ret; -+ static const char *default_attrs[] = SYSDB_GRSRC_ATTRS; -+ const char **attrs = NULL; - - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - return ENOMEM; - } - -+ if (additional_attrs == NULL) { -+ attrs = default_attrs; -+ } else { -+ ret = add_strings_lists(tmp_ctx, additional_attrs, default_attrs, -+ false, discard_const(&attrs)); -+ if (ret != EOK) { -+ DEBUG(SSSDBG_OP_FAILURE, "add_strings_lists failed.\n"); -+ goto done; -+ } -+ } -+ - if (domain->mpg) { - fmt_filter = SYSDB_GRGID_MPG_FILTER; - base_dn = ldb_dn_new_fmt(tmp_ctx, domain->sysdb->ldb, -@@ -1092,6 +1105,14 @@ done: - return ret; - } - -+int sysdb_getgrgid(TALLOC_CTX *mem_ctx, -+ struct sss_domain_info *domain, -+ gid_t gid, -+ struct ldb_result **_res) -+{ -+ return sysdb_getgrgid_attrs(mem_ctx, domain, gid, NULL, _res); -+} -+ - int sysdb_enumgrent_filter(TALLOC_CTX *mem_ctx, - struct sss_domain_info *domain, - const char *name_filter, -diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c -index fc9936968bcde8370c7054ba303de4463b35e15a..30574679f51362d03d7b9e3f8a1d55889817e4c1 100644 ---- a/src/tests/sysdb-tests.c -+++ b/src/tests/sysdb-tests.c -@@ -1114,6 +1114,42 @@ done: - } - END_TEST - -+START_TEST (test_sysdb_getgrgid_attrs) -+{ -+ struct sysdb_test_ctx *test_ctx; -+ struct test_data *data; -+ struct ldb_result *res; -+ int ret; -+ const char *attrs[] = { SYSDB_CREATE_TIME, NULL }; -+ uint64_t ctime; -+ -+ /* Setup */ -+ ret = setup_sysdb_tests(&test_ctx); -+ if (ret != EOK) { -+ fail("Could not set up the test"); -+ return; -+ } -+ -+ data = test_data_new_group(test_ctx, _i); -+ fail_if(data == NULL, "OOM"); -+ -+ ret = sysdb_getgrgid_attrs(test_ctx, -+ test_ctx->domain, -+ data->gid, attrs, &res); -+ if (ret) { -+ fail("sysdb_getgrgid_attrs failed for gid %d (%d: %s)", -+ data->gid, ret, strerror(ret)); -+ goto done; -+ } -+ -+ ctime = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_CREATE_TIME, 0); -+ fail_unless(ctime != 0, "Missing create time"); -+ -+done: -+ talloc_free(test_ctx); -+} -+END_TEST -+ - START_TEST (test_sysdb_search_groups) - { - struct sysdb_test_ctx *test_ctx; -@@ -7072,6 +7108,7 @@ Suite *create_sysdb_suite(void) - - /* Verify the groups can be queried by GID */ - tcase_add_loop_test(tc_sysdb, test_sysdb_getgrgid, 28010, 28020); -+ tcase_add_loop_test(tc_sysdb, test_sysdb_getgrgid_attrs, 28010, 28020); - - /* Find the users by GID using a filter */ - tcase_add_loop_test(tc_sysdb, test_sysdb_search_groups, 28010, 28020); --- -2.14.4 - diff --git a/SOURCES/0120-ipa-use-mpg-aware-group-lookup-in-get_object_from_ca.patch b/SOURCES/0120-ipa-use-mpg-aware-group-lookup-in-get_object_from_ca.patch deleted file mode 100644 index b5ea5f9..0000000 --- a/SOURCES/0120-ipa-use-mpg-aware-group-lookup-in-get_object_from_ca.patch +++ /dev/null @@ -1,61 +0,0 @@ -From a6de362d3cfe16550eb16d01900f44c9aeb8cc50 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 29 May 2018 15:42:55 +0200 -Subject: [PATCH] ipa: use mpg aware group lookup in get_object_from_cache() - -Since with algorithmic id-mapping SSSD automatically creates user -private groups for AD user with the help of magic private groups (mpg) -get_object_from_cache() should use mpg aware calls to make sure the -right user object is found when handling a request to look up a user -private group. - -Only the lookup by gid had to be modified because -sysdb_search_group_by_name() used for lookups by name is aware of MPGs. - -Related to https://pagure.io/SSSD/sssd/issue/3748 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit 032221568fe4287686d0ebb11b5c1fe51cc4735f) ---- - src/providers/ipa/ipa_subdomains_id.c | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - -diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c -index d40671086854f9c1a3f8bc7fc711009298dc31c8..3943579b07c7b2d32dde192b97b86eb036b91885 100644 ---- a/src/providers/ipa/ipa_subdomains_id.c -+++ b/src/providers/ipa/ipa_subdomains_id.c -@@ -1030,7 +1030,14 @@ errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, - - switch (ar->entry_type & BE_REQ_TYPE_MASK) { - case BE_REQ_GROUP: -- ret = sysdb_search_group_by_gid(mem_ctx, dom, id, attrs, &msg); -+ ret = sysdb_getgrgid_attrs(mem_ctx, dom, id, attrs, &res); -+ if (ret == EOK) { -+ if (res->count == 0) { -+ ret = ENOENT; -+ } else { -+ msg = res->msgs[0]; -+ } -+ } - break; - case BE_REQ_INITGROUPS: - case BE_REQ_USER: -@@ -1038,7 +1045,14 @@ errno_t get_object_from_cache(TALLOC_CTX *mem_ctx, - ret = sysdb_search_user_by_uid(mem_ctx, dom, id, attrs, &msg); - if (ret == ENOENT && (ar->entry_type & BE_REQ_TYPE_MASK) - == BE_REQ_USER_AND_GROUP) { -- ret = sysdb_search_group_by_gid(mem_ctx, dom, id, attrs, &msg); -+ ret = sysdb_getgrgid_attrs(mem_ctx, dom, id, attrs, &res); -+ if (ret == EOK) { -+ if (res->count == 0) { -+ ret = ENOENT; -+ } else { -+ msg = res->msgs[0]; -+ } -+ } - } - break; - default: --- -2.14.4 - diff --git a/SOURCES/0121-ipa-allow-mpg-group-objects-in-apply_subdomain_homed.patch b/SOURCES/0121-ipa-allow-mpg-group-objects-in-apply_subdomain_homed.patch deleted file mode 100644 index b785997..0000000 --- a/SOURCES/0121-ipa-allow-mpg-group-objects-in-apply_subdomain_homed.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 8bbee851484f7fa51af542ed2757e2eea36bf535 Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 29 May 2018 15:44:28 +0200 -Subject: [PATCH] ipa: allow mpg group objects in apply_subdomain_homedir() - -Since with algorithmic id-mapping SSSD automatically creates user -private groups for AD user with the help of magic private groups (mpg) -apply_subdomain_homedir() should be aware the in mpg domains a group -lookup might actually return a user object. Since the related sysdb -calls are clever and replace the objectcategory so that it matches the -original request type we have to check for the group category in the mpg -case as well. apply_subdomain_homedir() checks the uidNumber later as -well to make sure the object has the needed attributes for a user. - -Related to https://pagure.io/SSSD/sssd/issue/3748 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit e66517dcf63f1d4aaf866c22371dac7740ce0a48) ---- - src/providers/ipa/ipa_subdomains_id.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c -index 3943579b07c7b2d32dde192b97b86eb036b91885..c2064d33029a27a2c5d4b5344034ce90f8e746b8 100644 ---- a/src/providers/ipa/ipa_subdomains_id.c -+++ b/src/providers/ipa/ipa_subdomains_id.c -@@ -895,9 +895,16 @@ apply_subdomain_homedir(TALLOC_CTX *mem_ctx, struct sss_domain_info *dom, - goto done; - } - -+ /* The object is a user if SYSDB_OBJECTCATEGORY is SYSDB_USER_CLASS or in -+ * case of a MPG group lookup if SYSDB_OBJECTCATEGORY is SYSDB_GROUP_CLASS. -+ */ - for (c = 0; c < msg_el->num_values; c++) { - if (strncmp(SYSDB_USER_CLASS, (const char *)msg_el->values[c].data, -- msg_el->values[c].length) == 0) { -+ msg_el->values[c].length) == 0 -+ || (dom->mpg -+ && strncmp(SYSDB_GROUP_CLASS, -+ (const char *)msg_el->values[c].data, -+ msg_el->values[c].length) == 0)) { - break; - } - } --- -2.14.4 - diff --git a/SOURCES/0122-AD-LDAP-do-not-fall-back-to-mpg-user-lookup-on-GC-co.patch b/SOURCES/0122-AD-LDAP-do-not-fall-back-to-mpg-user-lookup-on-GC-co.patch deleted file mode 100644 index 68dba38..0000000 --- a/SOURCES/0122-AD-LDAP-do-not-fall-back-to-mpg-user-lookup-on-GC-co.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 4dbfa49f50fd785f374209c2e59205e79533788e Mon Sep 17 00:00:00 2001 -From: Sumit Bose -Date: Tue, 29 May 2018 15:46:33 +0200 -Subject: [PATCH] AD/LDAP: do not fall back to mpg user lookup on GC connection - -For MPG domains a group lookup might fall back to a user lookup to check -if the request is for a user private group. Since we cannot be sure that -all needed attributes for a user are replicated to the Global Catalog we -do not want to lookup the user during the fall back from the Global -Catalog. - -Since we cannot skip Global Catalog lookups for groups completely due to -membership to groups with universal scope this patch adds a flag to tell -the lower level lookup calls to not fall back on connections to a Global -Catalog. - -Related to https://pagure.io/SSSD/sssd/issue/3748 - -Reviewed-by: Jakub Hrozek -(cherry picked from commit ad6ab352879264fdade8861aff53aa035a2e2240) ---- - src/providers/ad/ad_common.c | 1 + - src/providers/ldap/ldap_common.h | 2 ++ - src/providers/ldap/ldap_id.c | 3 ++- - 3 files changed, 5 insertions(+), 1 deletion(-) - -diff --git a/src/providers/ad/ad_common.c b/src/providers/ad/ad_common.c -index 2a1647173b76b410371315eb364e9a3785714a93..1dca2fe279cb7d6d647aed42e3b3fabfb34b7dac 100644 ---- a/src/providers/ad/ad_common.c -+++ b/src/providers/ad/ad_common.c -@@ -1375,6 +1375,7 @@ ad_gc_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx, - if (dp_opt_get_bool(ad_ctx->ad_options->basic, AD_ENABLE_GC)) { - clist[cindex] = ad_ctx->gc_ctx; - clist[cindex]->ignore_mark_offline = true; -+ clist[cindex]->no_mpg_user_fallback = true; - cindex++; - } - -diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h -index 44dbc3fb0678412f46366321e0be836313380949..21cb57b0e7b265972db74ac78a3c1fb4ba2a9529 100644 ---- a/src/providers/ldap/ldap_common.h -+++ b/src/providers/ldap/ldap_common.h -@@ -57,6 +57,8 @@ struct sdap_id_conn_ctx { - struct sdap_id_conn_ctx *prev, *next; - /* do not go offline, try another connection */ - bool ignore_mark_offline; -+ /* do not fall back to user lookups for mpg domains on this connection */ -+ bool no_mpg_user_fallback; - }; - - struct sdap_id_ctx { -diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c -index 3824f8f9aa8d2892664f1182376bedf6fb8627f6..365d90fd1cdfba86c719b3669d057444a7449d66 100644 ---- a/src/providers/ldap/ldap_id.c -+++ b/src/providers/ldap/ldap_id.c -@@ -1076,7 +1076,8 @@ static void groups_get_done(struct tevent_req *subreq) - } - - if (ret == ENOENT -- && state->domain->mpg == true) { -+ && state->domain->mpg == true -+ && !state->conn->no_mpg_user_fallback) { - /* The requested filter did not find a group. Before giving up, we must - * also check if the GID can be resolved through a primary group of a - * user --- -2.14.4 - diff --git a/SOURCES/0123-deskprofile-don-t-bail-if-we-fail-to-save-one-profil.patch b/SOURCES/0123-deskprofile-don-t-bail-if-we-fail-to-save-one-profil.patch deleted file mode 100644 index 85fe196..0000000 --- a/SOURCES/0123-deskprofile-don-t-bail-if-we-fail-to-save-one-profil.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 7f698a050cea2baad34c84f8ae9e611dbf03ac7f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= -Date: Thu, 12 Jul 2018 23:55:03 +0200 -Subject: [PATCH] deskprofile: don't bail if we fail to save one profile -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Due to different reasons (a bug on fleet-commander, for instance?) we -may face the situation where one profile ends up stored in freeipa on a -half-broken state (with no data, for instance). - -In case it happens, we should try our best to save the not broken -profiles and just skip the broken ones instead of bailing the whole -operation. - -Resolves: -https://pagure.io/SSSD/sssd/issue/3773 - -Signed-off-by: Fabiano Fidêncio -Reviewed-by: Jakub Hrozek -(cherry picked from commit efd6702e5f70bb3df0f840dd3ce9f8f9264661ba) - -DOWNSTREAM: -Resolves: rhbz#1601360 - SSSD bails out saving desktop profiles in case an invalid profile is found [rhel-7.5.z] ---- - src/providers/ipa/ipa_session.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/providers/ipa/ipa_session.c b/src/providers/ipa/ipa_session.c -index 3c7dd33c30ac6331319fc62cac466c4fbf04c0a5..a93c21224ee4d539d412e61ea06cbde3b928416a 100644 ---- a/src/providers/ipa/ipa_session.c -+++ b/src/providers/ipa/ipa_session.c -@@ -766,7 +766,7 @@ ipa_pam_session_handler_save_deskprofile_rules( - DEBUG(SSSDBG_OP_FAILURE, - "Failed to save a Desktop Profile Rule to disk [%d]: %s\n", - ret, sss_strerror(ret)); -- goto done; -+ continue; - } - } - --- -2.14.4 - diff --git a/SPECS/sssd.spec b/SPECS/sssd.spec index 475c27c..2b87898 100644 --- a/SPECS/sssd.spec +++ b/SPECS/sssd.spec @@ -47,141 +47,62 @@ %endif Name: sssd -Version: 1.16.0 -Release: 19%{?dist}.8 +Version: 1.16.2 +Release: 13%{?dist} Group: Applications/System Summary: System Security Services Daemon License: GPLv3+ URL: https://pagure.io/SSSD/sssd/ Source0: https://releases.pagure.org/SSSD/sssd/sssd-%{version}.tar.gz -Source1: cert9.db -Source2: key4.db BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) ### Patches ### -Patch0001: 0001-NSS-Move-memcache-setup-to-separate-function.patch -Patch0002: 0002-NSS-Specify-memcache_timeout-0-semantics.patch -Patch0003: 0003-MAN-Document-memcache_timeout-0-meaning.patch -Patch0004: 0004-CONFIG-Add-a-new-option-auto_private_groups.patch -Patch0005: 0005-CONFDB-Remove-the-obsolete-option-magic_private_grou.patch -Patch0006: 0006-SDAP-Allow-the-mpg-flag-for-the-main-domain.patch -Patch0007: 0007-LDAP-Turn-group-request-into-user-request-for-MPG-do.patch -Patch0008: 0008-SYSDB-Prevent-users-and-groups-ID-collision-in-MPG-d.patch -Patch0009: 0009-TESTS-Add-integration-tests-for-the-auto_private_gro.patch -Patch0010: 0010-CACHE_REQ-Copy-the-cr_domain-list-for-each-request.patch -Patch0011: 0011-MAN-GPO-Security-Filtering-limitation.patch -Patch0012: 0012-sudo-always-use-srv_opts-from-id-context.patch -Patch0013: 0013-AD-Remember-last-site-discovered.patch -Patch0014: 0014-sysdb-add-functions-to-get-set-client-site.patch -Patch0015: 0015-AD-Remember-last-site-discovered-in-sysdb.patch -Patch0016: 0016-UTIL-Add-wrapper-function-to-configure-logger.patch -Patch0017: 0017-Add-parameter-logger-to-daemons.patch -Patch0018: 0018-SYSTEMD-Replace-parameter-debug-to-files-with-DEBUG_.patch -Patch0019: 0019-SYSTEMD-Add-environment-file-to-responder-service-fi.patch -Patch0020: 0020-UTIL-Hide-and-deprecate-parameter-debug-to-files.patch -Patch0021: 0021-LDAP-Bind-to-the-LDAP-server-also-in-the-auth.patch -Patch0022: 0022-sss_client-create-nss_common.h.patch -Patch0023: 0023-nss-idmap-add-nss-like-calls-with-timeout-and-flags.patch -Patch0024: 0024-NSS-add-_EX-version-of-some-requests.patch -Patch0025: 0025-NSS-add-support-for-SSS_NSS_EX_FLAG_NO_CACHE.patch -Patch0026: 0026-CACHE_REQ-Add-cache_req_data_set_bypass_dp.patch -Patch0027: 0027-nss-make-memcache_delete_entry-public.patch -Patch0028: 0028-NSS-add-support-for-SSS_NSS_EX_FLAG_INVALIDATE_CACHE.patch -Patch0029: 0029-NSS-TESTS-add-unit-tests-for-_EX-requests.patch -Patch0030: 0030-nss-idmap-add-timeout-version-of-old-sss_nss_-calls.patch -Patch0031: 0031-nss-idmap-allow-empty-buffer-with-SSS_NSS_EX_FLAG_IN.patch -Patch0032: 0032-BUILD-Properly-expand-variables-in-sssd-ifp.service.patch -Patch0033: 0033-SYSTEMD-Clean-pid-file-in-corner-cases.patch -Patch0034: 0034-CHILD-Pass-information-about-logger-to-children.patch -Patch0035: 0035-LDAP-Improve-error-treatment-from-sdap_cli_connect-i.patch -Patch0036: 0036-p11_child-return-multiple-certs.patch -Patch0037: 0037-PAM-handled-multiple-certs-in-the-responder.patch -Patch0038: 0038-pam_sss-refactoring-use-struct-cert_auth_info.patch -Patch0039: 0039-p11_child-use-options-to-select-certificate-for-auth.patch -Patch0040: 0040-pam-add-prompt-string-for-certificate-authentication.patch -Patch0041: 0041-PAM-allow-missing-logon_name-during-certificate-auth.patch -Patch0042: 0042-p11_child-add-descriptions-for-error-codes-to-debug-.patch -Patch0043: 0043-pam-filter-certificates-in-the-responder-not-in-the-.patch -Patch0044: 0044-PAM-add-certificate-s-label-to-the-selection-prompt.patch -Patch0045: 0045-SYSDB-Remove-code-causing-a-covscan-warning.patch -Patch0046: 0046-SYSDB-Better-debugging-for-email-conflicts.patch -Patch0047: 0047-NSS-Use-enum_ctx-as-memory_context-in-_setnetgrent_s.patch -Patch0048: 0048-TOOLS-Add-a-new-sssctl-command-access-report.patch -Patch0049: 0049-dp-use-void-to-express-empty-output-argument-list.patch -Patch0050: 0050-dp-add-method-to-refresh-access-control-rules.patch -Patch0051: 0051-ipa-implement-method-to-refresh-HBAC-rules.patch -Patch0052: 0052-ifp-add-method-to-refresh-access-control-rules-in-do.patch -Patch0053: 0053-sssctl-call-dbus-instead-of-pam-to-refresh-HBAC-rule.patch -Patch0054: 0054-sysdb-be_refresh_get_values_ex-remove-unused-option.patch -Patch0055: 0055-sysdb-do-not-use-objectClass-for-users-and-groups.patch -Patch0056: 0056-sysdb-do-not-use-LDB_SCOPE_ONELEVEL.patch -Patch0057: 0057-sysdb-remove-IDXONE-and-objectClass-from-users-and-g.patch -Patch0058: 0058-mmap_cache-make-checks-independent-of-input-size.patch -Patch0059: 0059-NSS-Fix-covscan-warning.patch -Patch0060: 0060-responder-Fix-talloc-hierarchy-in-sized_output_name.patch -Patch0061: 0061-test_responder-Check-memory-leak-in-sized_output_nam.patch -Patch0062: 0062-UTIL-add-find_domain_by_object_name_ex.patch -Patch0063: 0063-ipa-handle-users-from-different-domains-in-ipa_resol.patch -Patch0064: 0064-overrides-fixes-for-sysdb_invalidate_overrides.patch -Patch0065: 0065-ipa-check-for-SYSDB_OVERRIDE_DN-in-process_members-a.patch -Patch0066: 0066-IPA-use-cache-searches-in-get_groups_dns.patch -Patch0067: 0067-ipa-compare-DNs-instead-of-group-names-in-ipa_s2n_sa.patch -Patch0068: 0068-SDAP-Split-out-utility-function-sdap_get_object_doma.patch -Patch0069: 0069-LDAP-Extract-the-check-whether-to-run-a-POSIX-check-.patch -Patch0070: 0070-LDAP-Only-run-the-POSIX-check-with-a-GC-connection.patch -Patch0071: 0071-SDAP-Search-with-a-NULL-search-base-when-looking-up-.patch -Patch0072: 0072-SDAP-Rename-sdap_posix_check-to-sdap_gc_posix_check.patch -Patch0073: 0073-DP-Create-a-new-handler-function-getAccountDomain.patch -Patch0074: 0074-AD-Implement-a-real-getAccountDomain-handler-for-the.patch -Patch0075: 0075-RESP-Expose-DP-method-getAccountDomain-to-responders.patch -Patch0076: 0076-NEGCACHE-Add-API-for-setting-and-checking-locate-acc.patch -Patch0077: 0077-TESTS-Add-tests-for-the-object-by-id-cache_req-inter.patch -Patch0078: 0078-CACHE_REQ-Export-cache_req_search_ncache_add-as-cach.patch -Patch0079: 0079-CACHE_REQ-Add-plugin-methods-required-for-the-domain.patch -Patch0080: 0080-CACHE_REQ-Add-a-private-request-cache_req_locate_dom.patch -Patch0081: 0081-CACHE_REQ-Implement-the-plugin-methods-that-utilize-.patch -Patch0082: 0082-CACHE_REQ-Use-the-domain-locator-request-to-only-sea.patch -Patch0083: 0083-MAN-Document-how-the-Global-Catalog-is-used-currentl.patch -Patch0084: 0084-p11_child-make-sure-OCSP-checks-are-done.patch -Patch0085: 0085-IPA-Include-SYSDB_OBJECTCATEGORY-not-OBJECTCLASS-in-.patch -Patch0086: 0086-nss-idmap-allow-NULL-result-in-_timeout-calls.patch -Patch0087: 0087-cache-Check-for-max_id-min_id-in-cache_req.patch -Patch0088: 0088-Revert-p11_child-make-sure-OCSP-checks-are-done.patch -Patch0089: 0089-p11_child-properly-check-results-of-CERT_VerifyCerti.patch -Patch0090: 0090-ifp-use-realloc-in-ifp_list_ctx_remaining_capacity.patch -Patch0091: 0091-IPA-Delay-the-first-periodic-refresh-of-trusted-doma.patch -Patch0092: 0092-sysdb-add-userMappedCertificate-to-the-index.patch -Patch0093: 0093-AD-Inherit-the-MPG-setting-from-the-main-domain.patch -Patch0094: 0094-SDAP-skip-builtin-AD-groups-in-sdap_save_grpmem.patch -Patch0095: 0095-SYSDB-Read-the-ldb_message-from-loop-s-index-counter.patch -Patch0096: 0096-nss-idmap-check-timed-muted-return-code.patch -Patch0097: 0097-DESKPROFILE-Add-checks-for-user-and-host-category.patch -Patch0098: 0098-SELINUX-Check-if-SELinux-is-managed-in-selinux_child.patch -Patch0099: 0099-util-Add-sss_-prefix-to-some-functions.patch -Patch0100: 0100-MAN-Explain-how-does-auto_private_groups-affect-subd.patch -Patch0101: 0101-AD-Use-the-right-sdap_domain-for-the-forest-root.patch -Patch0102: 0102-AD-sdap_get_ad_tokengroups_done-allocate-temporary-d.patch -Patch0103: 0103-AD-do-not-allocate-temporary-data-on-long-living-con.patch -Patch0104: 0104-nss-idmap-do-not-set-a-limit.patch -Patch0105: 0105-nss-idmap-use-right-group-list-pointer-after-sss_get.patch -Patch0106: 0106-nss-add-a-netgroup-counter-to-struct-nss_enum_index.patch -Patch0107: 0107-nss-initialize-nss_enum_index-in-nss_setnetgrent.patch -Patch0108: 0108-NSS-nss_clear_netgroup_hash_table-do-not-free-data.patch -Patch0109: 0109-winbind-idmap-plugin-support-inferface-version-6.patch -Patch0110: 0110-winbind-idmap-plugin-fix-detection.patch -Patch0111: 0111-Do-not-keep-allocating-external-groups-on-a-long-liv.patch -Patch0112: 0112-TESTS-Extend-the-schema-with-sshPublicKey-attribute.patch -Patch0113: 0113-TESTS-Allow-adding-sshPublicKey-for-users.patch -Patch0114: 0114-TESTS-Add-a-basic-SSH-responder-test.patch -Patch0115: 0115-SSH-Do-not-exit-abruptly-if-SSHD-closes-its-end-of-t.patch -Patch0116: 0116-TESTS-Add-a-helper-binary-that-can-trigger-the-SIGPI.patch -Patch0117: 0117-TESTS-Add-a-regression-test-for-SIGHUP-handling-in-s.patch -Patch0118: 0118-TESTS-Order-list-of-entries-in-some-lists.patch -Patch0119: 0119-sysdb-add-sysdb_getgrgid_attrs.patch -Patch0120: 0120-ipa-use-mpg-aware-group-lookup-in-get_object_from_ca.patch -Patch0121: 0121-ipa-allow-mpg-group-objects-in-apply_subdomain_homed.patch -Patch0122: 0122-AD-LDAP-do-not-fall-back-to-mpg-user-lookup-on-GC-co.patch -Patch0123: 0123-deskprofile-don-t-bail-if-we-fail-to-save-one-profil.patch +Patch0001: 0001-krb5-locator-add-support-for-multiple-addresses.patch +Patch0002: 0002-krb5-locator-fix-IPv6-support.patch +Patch0003: 0003-krb5-locator-make-plugin-more-robust.patch +Patch0004: 0004-krb5-locator-add-unit-tests.patch +Patch0005: 0005-AD-IPA-Create-kdcinfo-file-for-sub-domains.patch +Patch0006: 0006-krb5-refactor-removal-of-krb5info-files.patch +Patch0007: 0007-krb5_common-add-callback-only-once.patch +Patch0008: 0008-data-provider-run-offline-callbacks-only-once.patch +Patch0009: 0009-TESTS-Extend-the-schema-with-sshPublicKey-attribute.patch +Patch0010: 0010-TESTS-Allow-adding-sshPublicKey-for-users.patch +Patch0011: 0011-TESTS-Add-a-basic-SSH-responder-test.patch +Patch0012: 0012-SSH-Do-not-exit-abruptly-if-SSHD-closes-its-end-of-t.patch +Patch0013: 0013-TESTS-Add-a-helper-binary-that-can-trigger-the-SIGPI.patch +Patch0014: 0014-TESTS-Add-a-regression-test-for-SIGHUP-handling-in-s.patch +Patch0015: 0015-Revert-LDAP-IPA-add-local-email-address-to-aliases.patch +Patch0016: 0016-util-Remove-the-unused-function-is_email_from_domain.patch +Patch0017: 0017-TESTS-Allow-storing-e-mail-address-for-users.patch +Patch0018: 0018-TESTS-Add-regression-test-for-looking-up-users-with-.patch +Patch0019: 0019-MAN-Remove-outdated-notes-from-the-re_expression-des.patch +Patch0020: 0020-SUDO-Create-the-socket-with-stricter-permissions.patch +Patch0021: 0021-MAN-Give-information-regarding-priority-of-ldap-look.patch +Patch0022: 0022-AD-LDAP-Do-not-misuse-the-ignore_mark_offline-to-che.patch +Patch0023: 0023-AD-expose-the-helper-function-to-format-the-site-DNS.patch +Patch0024: 0024-RESOLV-Add-a-resolv_hostport_list-request.patch +Patch0025: 0025-KRB5-IPA-AD-Add-a-utility-function-to-create-a-krb5_.patch +Patch0026: 0026-KRB5-Allow-writing-multiple-addresses-to-the-kdcinfo.patch +Patch0027: 0027-IPA-Add-the-options-that-the-IPA-subdomains-code-wil.patch +Patch0028: 0028-IPA-Populate-kdcinfo-files-on-trust-clients-with-con.patch +Patch0029: 0029-MAN-Document-the-options-available-for-AD-trusted-do.patch +Patch0030: 0030-AD-consider-resource_groups-in-PAC-as-well.patch +Patch0031: 0031-LDAP-Remove-the-legacy-POSIX-check-itself.patch +Patch0032: 0032-LDAP-AD-Remove-the-legacy-POSIX-check-from-user-grou.patch +Patch0033: 0033-AD-Remove-the-legacy-check-from-ad_get_account_domai.patch +Patch0034: 0034-AD-Add-Global-Catalog-usability-check-in-subdomain-c.patch +Patch0035: 0035-SDAP-Detect-schemaNamingContext-from-the-rootDSE.patch +Patch0036: 0036-deskprofile-don-t-bail-if-we-fail-to-save-one-profil.patch +Patch0037: 0037-SUDO-Fix-running-in-unprivileged-responder.patch +Patch0038: 0038-SUDO-Root-should-be-able-to-read-write-sssd-sudo-soc.patch +Patch0039: 0039-sdap-respect-passwordGracelimit.patch +Patch0040: 0040-MC-Remove-check-if-record-is-in-the-mapped-address-s.patch +Patch0041: 0041-Revert-CRYPTO-Suppress-warning-Wstringop-truncation.patch +Patch0042: 0042-Revert-Revert-CRYPTO-Suppress-warning-Wstringop-trun.patch +Patch0043: 0043-CRYPTO-Save-prefix-in-s3crypt_sha512.patch +Patch0044: 0044-crypto-tests-Add-unit-test-for-s3crypt_sha512.patch +Patch0045: 0045-SSS_CERT-Close-file-descriptors-after-executing-p11_.patch +Patch0046: 0046-SELINUX-Also-call-is_selinux_enabled-as-a-check-for-.patch #This patch should not be removed in RHEL-7 Patch999: 0999-NOUPSTREAM-Default-to-root-if-sssd-user-is-not-spec @@ -213,6 +134,7 @@ BuildRequires: autoconf BuildRequires: automake BuildRequires: libtool BuildRequires: m4 +BuildRequires: gcc BuildRequires: popt-devel BuildRequires: libtalloc-devel BuildRequires: libtevent-devel @@ -296,6 +218,13 @@ Requires(postun): systemd-units chkconfig # gpo_child -> libsmbclient -> samba-client-libs -> libwbclient OrderWithRequires: libwbclient OrderWithRequires: sssd-libwbclient +# Explicitly require RHEL-7.6 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.13-1 +Requires: libtevent >= 0.9.36-1 +Requires: libldb >= 1.3.4-1 +Requires: libtdb >= 1.3.15-1 ### Provides ### Provides: libsss_sudo-devel = %{version}-%{release} @@ -679,9 +608,6 @@ for p in %patches ; do UpdateTimestamps -p1 $p done -cp %{SOURCE1} src/tests/cmocka/p11_nssdb_2certs/ -cp %{SOURCE2} src/tests/cmocka/p11_nssdb_2certs/ - %build autoreconf -ivf @@ -1329,29 +1255,91 @@ systemctl try-restart sssd >/dev/null 2>&1 || : } %changelog -* Thu Jul 26 2018 Jakub Hrozek - 1.16.0-19.8 -- Resolves: rhbz#1601360 - SSSD bails out saving desktop profiles in case an invalid profile is found [rhel-7.5.z] - -* Tue Jul 24 2018 Jakub Hrozek - 1.16.0-19.7 -- Resolves: rhbz#1596292 - home dir disappear in sssd cache on the IPA master for AD users [rhel-7.5.z] - -* Fri Jul 20 2018 Jakub Hrozek - 1.16.0-19.6 -- Resolves: rhbz#1594178 - Login with sshkeys stored in ipa not working after update to RHEL-7.5 [rhel-7.5.z] - -* Thu May 31 2018 Fabiano Fidêncio - 1.16.0-19.5 -- Resolves: rhbz#1583746 - The SSSD IPA provider allocates information about external groups on a long lived memory context, causing memory growth of the sssd_be process [rhel-7.5.z] - -* Mon May 21 2018 Fabiano Fidêncio - 1.16.0-19.4 -- Resolves: rhbz#1580281 - Samba can not register sss idmap module because it's using an outdated SMB_IDMAP_INTERFACE_VERSION [rhel-7.5.z] - -* Fri May 18 2018 Fabiano Fidêncio - 1.16.0-19.3 -- Resolves: rhbz#1579780 - After updating to RHEL 7.5 failing to clear the sssd cache [rhel-7.5.z] - -* Fri May 18 2018 Fabiano Fidêncio - 1.16.0-19.2 -- Resolves: rhbz#1579703 - crash in nss_protocol_fill_netgrent. sssd_nss[19234]: segfault at 80 ip 000055612688c2a0 sp 00007ffddf9b9cd0 error 4 in sssd_nss[55612687e000+39000] [rhel-7.5.z] - -* Mon Apr 23 2018 Fabiano Fidêncio - 1.16.0-19.1 -- Resolves: rhbz#1570527 - memory management issue in the sssd_nss_ex interface can cause the ns-slapd process on IPA server to crash [rhel-7.5.z] +* Wed Sep 5 2018 Jakub Hrozek - 1.16.2-13 +- Resolves: rhbz#1593756 - sssd needs to require a newer version of + libtalloc and libtevent to avoid an issue + in GPO processing + +* Thu Aug 9 2018 Fabiano Fidêncio - 1.16.2-12 +- Resolves: rhbz#1610667 - sssd_ssh leaks file descriptors when more than one certificate is converted into an SSH key +- Resolves: rhbz#1583360 - The IPA selinux provider can return an error if SELinux is completely disabled + +* Thu Aug 2 2018 Jakub Hrozek - 1.16.2-11 +- Resolves: rhbz#1602781 - Local users failed to login with same password + +* Wed Aug 1 2018 Jakub Hrozek - 1.16.2-10 +- Resolves: rhbz#1586127 - Spurious check in the sssd nss memcache can cause the memory cache to be skipped + +* Thu Jul 26 2018 Jakub Hrozek - 1.16.2-9 +- Resolves: rhbz#1522928 - sssd doesn't allow user with expired password + +* Thu Jul 26 2018 Jakub Hrozek - 1.16.2-8 +- Resolves: rhbz#1607313 - When sssd is running as non-root user, the sudo pipe is created as sssd:sssd but then the private pipe ownership fails + +* Fri Jul 13 2018 Fabiano Fidêncio - 1.16.2-7 +- Resolves: rhbz#1600822 - SSSD bails out saving desktop profiles in case an invalid profile is found + +* Wed Jul 11 2018 Fabiano Fidêncio - 1.16.2-6 +- Resolves: rhbz#1582975 - The search filter for detecting POSIX attributes in global catalog is too broad and can cause a high load on the servers + +* Fri Jun 29 2018 Fabiano Fidêncio - 1.16.2-5 +- Resolves: rhbz#1583725 - SSSD AD uses LDAP filter to detect POSIX attributes stored in AD GC also for regular AD DC queries +- Resolves: rhbz#1416528 - sssd in cross realm trust configuration should be able to use AD KDCs from a client site defined in sssd.conf or a snippet +- Resolves: rhbz#1592964 - Groups go missing with PAC enabled in sssd + +* Mon Jun 25 2018 Fabiano Fidêncio - 1.16.2-4 +- Resolves: rhbz#1590603 - EMBARGOED CVE-2018-10852 sssd: information leak from the sssd-sudo responder [rhel-7] +- Resolves: rhbz#1450778 - Full information regarding priority of lookup of principal in keytab not in man page + +* Fri Jun 22 2018 Fabiano Fidêncio - 1.16.2-3 +- Resolves: rhbz#1494690 - kdcinfo files are not created for subdomains of a directly joined AD client +- Resolves: rhbz#1583343 - Login with sshkeys stored in ipa not working after update to RHEL-7.5 +- Resolves: rhbz#1527662 - Handle conflicting e-mail addresses more gracefully +- Resolves: rhbz#1509691 - Document how to change the regular expression for SSSD so that group names with an @-sign can be parsed + +* Fri Jun 22 2018 Fabiano Fidêncio - 1.16.2-2 +- Related: rhbz#1558498 - Rebase sssd to the latests upstream release of the 1.16 branch + +* Mon Jun 11 2018 Fabiano Fidêncio - 1.16.2-1 +- Resolves: rhbz#1558498 - Rebase sssd to the latests upstream release of the 1.16 branch +- Resolves: rhbz#1523019 - Reset password with two factor authentication fails +- Resolves: rhbz#1534749 - Requesting an AD user's private group and then the user itself returns an emty homedir +- Resolves: rhbz#1537272 - SSH public key authentication keeps working after keys are removed from ID view +- Resolves: rhbz#1537279 - Certificate is not removed from cache when it's removed from the override +- Resolves: rhbz#1562025 - externalUser sudo attribute must be fully-qualified +- Resolves: rhbz#1577335 - /usr/libexec/sssd/sssd_autofs SIGABRT crash daily +- Resolves: rhbz#1508530 - How should sudo behave without sudoHost attribute? +- Resolves: rhbz#1546754 - The man page of sss_ssh_authorizedkeys can be enhanced to better explain how the keys are retrieved and how X.509 certificates can be used +- Resolves: rhbz#1572790 - getgrgid/getpwuid fails in setups with multiple domains if the first domain uses mid_id/max_id +- Resolves: rhbz#1561562 - sssd not honoring dyndns_server if the DNS update process is terminated with a signal +- Resolves: rhbz#1583251 - home dir disappear in sssd cache on the IPA master for AD users +- Resolves: rhbz#1514061 - ID override GID from Default Trust View is not properly resolved in case domain resolution order is set +- Resolves: rhbz#1571466 - Utilizing domain_resolution_order in sssd.conf breaks SELinux user map +- Resolves: rhbz#1571526 - SSSD with ID provider 'ad' should give a warning in case the ldap schema is manually changed to something different than 'ad'. + +* Thu May 31 2018 Fabiano Fidêncio - 1.16.0-25 +- Resolves: rhbz#1547782 - The SSSD IPA provider allocates information about external groups on a long lived memory context, causing memory growth of the sssd_be process + +* Sat May 19 2018 Fabiano Fidêncio - 1.16.0-24 +- Related: rhbz#1578291 - Samba can not register sss idmap module because it's using an outdated SMB_IDMAP_INTERFACE_VERSION + +* Fri May 18 2018 Fabiano Fidêncio - 1.16.0-23 +- Resolves: rhbz#1578291 - Samba can not register sss idmap module because it's using an outdated SMB_IDMAP_INTERFACE_VERSION + +* Fri May 18 2018 Fabiano Fidêncio - 1.16.0-22 +- Resolves: rhbz#1516266 - Give a more detailed debug and system-log message if krb5_init_context() failed +- Resolves: rhbz#1503802 - Smartcard authentication fails if SSSD is offline and 'krb5_store_password_if_offline = True' +- Resolves: rhbz#1385665 - Incorrect error code returned from krb5_child (updated) +- Resolves: rhbz#1547234 - SSSD's GPO code ignores ad_site option +- Resolves: rhbz#1459348 - extend sss-certmap man page regarding priority processing +- Resolves: rhbz#1220767 - Group renaming issue when "id_provider = ldap" is set +- Resolves: rhbz#1538555 - crash in nss_protocol_fill_netgrent. sssd_nss[19234]: segfault at 80 ip 000055612688c2a0 sp 00007ffddf9b9cd0 error 4 in sssd_nss[55612687e000+39000] + +* Wed Apr 25 2018 Jakub Hrozek - 1.16.0-21 +- Resolves: rhbz#1565774 - After updating to RHEL 7.5 failing to clear the sssd cache + +* Fri Apr 20 2018 Fabiano Fidêncio - 1.16.0-20 +- Resolves: rhbz#1566782 - memory management issue in the sssd_nss_ex interface can cause the ns-slapd process on IPA server to crash * Wed Feb 21 2018 Fabiano Fidêncio - 1.16.0-19 - Related: rhbzrhbz#1544943 - sssd goes offline when renewing expired ticket