Resolves: upstream#3766 - CVE-2018-10852: information leak from the sssd-sudo responder
And also ... - Related: upstream#941 - return multiple server addresses to the Kerberos locator plugin - Related: upstream#3652 - kdcinfo doesn't get populated for other domains - Resolves: upstream#3747 - sss_ssh_authorizedkeys exits abruptly if SSHD closes its end of the pipe before reading all the SSH keys - Resolves: upstream#3607 - Handle conflicting e-mail addresses more gracefully - Resolves: upstream#3754 - SSSD AD uses LDAP filter to detect POSIX attributes stored in AD GC also for regular AD DC queries - Related: upstream#3219 - [RFE] Regular expression used in sssd.conf not being able to consume an @-sign in the user/group name. Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com> (cherry picked from commit68ef824a5f
) (cherry picked from commitf311832a06
)
This commit is contained in:
parent
efa0c9fd07
commit
b1aca931e9
468
0001-krb5-locator-add-support-for-multiple-addresses.patch
Normal file
468
0001-krb5-locator-add-support-for-multiple-addresses.patch
Normal file
@ -0,0 +1,468 @@
|
||||
From 4b1137562c3446e85a6383010702850f9532a4f2 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
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 <jhrozek@redhat.com>
|
||||
|
||||
(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
|
||||
|
65
0002-krb5-locator-fix-IPv6-support.patch
Normal file
65
0002-krb5-locator-fix-IPv6-support.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From 45a48b9a73f39e9ef9e622dbcf87cc05a2a54e40 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
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 <jhrozek@redhat.com>
|
||||
|
||||
(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
|
||||
|
35
0003-krb5-locator-make-plugin-more-robust.patch
Normal file
35
0003-krb5-locator-make-plugin-more-robust.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 4e851d1391f56c632c271fd21dd96f29565cadfe Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
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 <jhrozek@redhat.com>
|
||||
|
||||
(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
|
||||
|
724
0004-krb5-locator-add-unit-tests.patch
Normal file
724
0004-krb5-locator-add-unit-tests.patch
Normal file
@ -0,0 +1,724 @@
|
||||
From 3d6b8b306cdbd4ec15b36a1e7936d219204e08dc Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
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 <jhrozek@redhat.com>
|
||||
|
||||
(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 <sbose@redhat.com>
|
||||
+
|
||||
+ 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 <http://www.gnu.org/licenses/>.
|
||||
+*/
|
||||
+#include "config.h"
|
||||
+
|
||||
+#include <popt.h>
|
||||
+#include <sys/types.h>
|
||||
+#include <sys/socket.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <string.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <netdb.h>
|
||||
+#include <krb5/krb5.h>
|
||||
+#include <krb5/locate_plugin.h>
|
||||
+
|
||||
+#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
|
||||
|
148
0005-AD-IPA-Create-kdcinfo-file-for-sub-domains.patch
Normal file
148
0005-AD-IPA-Create-kdcinfo-file-for-sub-domains.patch
Normal file
@ -0,0 +1,148 @@
|
||||
From 660ef95e36ad73b4715656a4207aeb499ac96d16 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
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 <jhrozek@redhat.com>
|
||||
|
||||
(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
|
||||
|
493
0006-krb5-refactor-removal-of-krb5info-files.patch
Normal file
493
0006-krb5-refactor-removal-of-krb5info-files.patch
Normal file
@ -0,0 +1,493 @@
|
||||
From 713bc782502163251ef22eb81b09eed61a8407f7 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
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 <jhrozek@redhat.com>
|
||||
|
||||
(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
|
||||
|
86
0007-krb5_common-add-callback-only-once.patch
Normal file
86
0007-krb5_common-add-callback-only-once.patch
Normal file
@ -0,0 +1,86 @@
|
||||
From 54ea4576ba8cb8dfbefdd3ced29fc35f836afc61 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Fri, 8 Jun 2018 08:29:04 +0200
|
||||
Subject: [PATCH] krb5_common: add callback only once
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
(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
|
||||
|
95
0008-data-provider-run-offline-callbacks-only-once.patch
Normal file
95
0008-data-provider-run-offline-callbacks-only-once.patch
Normal file
@ -0,0 +1,95 @@
|
||||
From 2d350235bc960a91233d29b97c3a205bd2e04c08 Mon Sep 17 00:00:00 2001
|
||||
From: Sumit Bose <sbose@redhat.com>
|
||||
Date: Fri, 8 Jun 2018 18:42:28 +0200
|
||||
Subject: [PATCH] data provider: run offline callbacks only once
|
||||
|
||||
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
||||
(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
|
||||
|
@ -0,0 +1,62 @@
|
||||
From 2b210b10ce54f6f2595f6ab181a51bce367d43a9 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <fidencio@redhat.com>
|
||||
(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
|
||||
|
78
0010-TESTS-Allow-adding-sshPublicKey-for-users.patch
Normal file
78
0010-TESTS-Allow-adding-sshPublicKey-for-users.patch
Normal file
@ -0,0 +1,78 @@
|
||||
From 4bff9d92a51bff2fabb6168f8ae69c8a8d17ba2a Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <fidencio@redhat.com>
|
||||
(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
|
||||
|
276
0011-TESTS-Add-a-basic-SSH-responder-test.patch
Normal file
276
0011-TESTS-Add-a-basic-SSH-responder-test.patch
Normal file
@ -0,0 +1,276 @@
|
||||
From 079464a0fd417f09cfafa2bda9ff1a4e1afdbe8a Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <fidencio@redhat.com>
|
||||
(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 <http://www.gnu.org/licenses/>.
|
||||
+#
|
||||
+
|
||||
+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
|
||||
|
@ -0,0 +1,88 @@
|
||||
From 60f868ac16c4678d60f17d62fa3b47534d4d07cb Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <fidencio@redhat.com>
|
||||
(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 <stdio.h>
|
||||
#include <talloc.h>
|
||||
#include <popt.h>
|
||||
+#include <signal.h>
|
||||
|
||||
#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
|
||||
|
213
0013-TESTS-Add-a-helper-binary-that-can-trigger-the-SIGPI.patch
Normal file
213
0013-TESTS-Add-a-helper-binary-that-can-trigger-the-SIGPI.patch
Normal file
@ -0,0 +1,213 @@
|
||||
From ef28a3bdc50d0da6fab86b0d27e4c548ac61a749 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <fidencio@redhat.com>
|
||||
(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 <http://www.gnu.org/licenses/>.
|
||||
+*/
|
||||
+
|
||||
+#include <popt.h>
|
||||
+#include <sys/wait.h>
|
||||
+#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
|
||||
|
@ -0,0 +1,94 @@
|
||||
From 0adf4f50e9773afda2dc422b04163f19d946c150 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <fidencio@redhat.com>
|
||||
(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
|
||||
|
141
0015-Revert-LDAP-IPA-add-local-email-address-to-aliases.patch
Normal file
141
0015-Revert-LDAP-IPA-add-local-email-address-to-aliases.patch
Normal file
@ -0,0 +1,141 @@
|
||||
From 9efaade255e59b4a2f5cff2ab78c1db61132a40a Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <fidencio@redhat.com>
|
||||
(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
|
||||
|
117
0016-util-Remove-the-unused-function-is_email_from_domain.patch
Normal file
117
0016-util-Remove-the-unused-function-is_email_from_domain.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From 5651a893f7dddb13fa9edc94e96d7bc95ec13f8b Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <fidencio@redhat.com>
|
||||
(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
|
||||
|
65
0017-TESTS-Allow-storing-e-mail-address-for-users.patch
Normal file
65
0017-TESTS-Allow-storing-e-mail-address-for-users.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From 75710952e74ea6070a53baaf5ea4e80507cdc26c Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <fidencio@redhat.com>
|
||||
(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
|
||||
|
@ -0,0 +1,93 @@
|
||||
From 0cbf6070bccb6c1f904cea596f00af0cc6328bae Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <fidencio@redhat.com>
|
||||
(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
|
||||
|
@ -0,0 +1,47 @@
|
||||
From 8d5241404e8eb2388a9fc45115f5210e3ada1f1b Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <fidencio@redhat.com>
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
(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 <quote>@</quote> sign, the domain everything
|
||||
after that"
|
||||
</para>
|
||||
- <para>
|
||||
- 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.
|
||||
- </para>
|
||||
- <para>
|
||||
- PLEASE NOTE ALSO: older version of libpcre only
|
||||
- support the Python syntax (?P<name>) to label
|
||||
- subpatterns.
|
||||
- </para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
--
|
||||
2.17.1
|
||||
|
55
0020-SUDO-Create-the-socket-with-stricter-permissions.patch
Normal file
55
0020-SUDO-Create-the-socket-with-stricter-permissions.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From 69eedc59283888a1d7d5f59284e032f9cad89b73 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
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 <sbose@redhat.com>
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
(cherry picked from commit ed90a20a0f0e936eb00d268080716c0384ffb01d)
|
||||
---
|
||||
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
|
||||
|
39
sssd.spec
39
sssd.spec
@ -38,7 +38,7 @@
|
||||
|
||||
Name: sssd
|
||||
Version: 1.16.2
|
||||
Release: 3%{?dist}
|
||||
Release: 4%{?dist}
|
||||
Group: Applications/System
|
||||
Summary: System Security Services Daemon
|
||||
License: GPLv3+
|
||||
@ -47,6 +47,26 @@ Source0: https://releases.pagure.org/SSSD/sssd/%{name}-%{version}.tar.gz
|
||||
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
||||
|
||||
### Patches ###
|
||||
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
|
||||
|
||||
Patch0502: 0502-SYSTEMD-Use-capabilities.patch
|
||||
Patch0503: 0503-Disable-stopping-idle-socket-activated-responders.patch
|
||||
@ -1261,7 +1281,22 @@ fi
|
||||
%{_libdir}/%{name}/modules/libwbclient.so
|
||||
|
||||
%changelog
|
||||
* Thu Jun 21 2018 Fabiano fidêncio <fidencio@fedoraproject.org> - 1.16.2-3
|
||||
* Mon Jun 25 2018 Fabiano Fidêncio <fidencio@fedoraproject.org> - 1.16.2-4
|
||||
- Related: upstream#941 - return multiple server addresses to the Kerberos
|
||||
locator plugin
|
||||
- Related: upstream#3652 - kdcinfo doesn't get populated for other domains
|
||||
- Resolves: upstream#3747 - sss_ssh_authorizedkeys exits abruptly if SSHD
|
||||
closes its end of the pipe before reading all the
|
||||
SSH keys
|
||||
- Resolves: upstream#3607 - Handle conflicting e-mail addresses more gracefully
|
||||
- Resolves: upstream#3754 - SSSD AD uses LDAP filter to detect POSIX attributes
|
||||
stored in AD GC also for regular AD DC queries
|
||||
- Related: upstream#3219 - [RFE] Regular expression used in sssd.conf not being
|
||||
able to consume an @-sign in the user/group name.
|
||||
- Resolves: upstream#3766 - CVE-2018-10852: information leak from the sssd-sudo
|
||||
responder
|
||||
|
||||
* Thu Jun 21 2018 Fabiano Fidêncio <fidencio@fedoraproject.org> - 1.16.2-3
|
||||
- Resolves: rhbz#1591804 - something keeps /lib/libnss_systemd.so.2 open on
|
||||
minimal appliance image, breaking composes
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user