Backport upstream patches required by FreeIPA 4.2.1
This commit is contained in:
parent
cc1ba0d674
commit
cc6c9ff159
98
0003-DYNDNS-sss_iface_addr_list_get-return-ENOENT.patch
Normal file
98
0003-DYNDNS-sss_iface_addr_list_get-return-ENOENT.patch
Normal file
@ -0,0 +1,98 @@
|
||||
From a74f42e33fd62be175c30574242a214cdce14b06 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Reichl <preichl@redhat.com>
|
||||
Date: Wed, 8 Jul 2015 09:01:24 -0400
|
||||
Subject: [PATCH 03/14] DYNDNS: sss_iface_addr_list_get return ENOENT
|
||||
|
||||
If none of eligible interfaces matches ifname then ENOENT is returned.
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2549
|
||||
---
|
||||
src/providers/dp_dyndns.c | 13 +++++++++++--
|
||||
src/providers/ldap/sdap_dyndns.c | 6 +++++-
|
||||
src/tests/cmocka/test_dyndns.c | 20 ++++++++++++++++++++
|
||||
3 files changed, 36 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/providers/dp_dyndns.c b/src/providers/dp_dyndns.c
|
||||
index 1cac3d0fae2454cea823ed640a4325f27580353f..2ac43a108ff6197d9e2662198a6da976ca348e76 100644
|
||||
--- a/src/providers/dp_dyndns.c
|
||||
+++ b/src/providers/dp_dyndns.c
|
||||
@@ -222,8 +222,17 @@ sss_iface_addr_list_get(TALLOC_CTX *mem_ctx, const char *ifname,
|
||||
}
|
||||
}
|
||||
|
||||
- ret = EOK;
|
||||
- *_addrlist = addrlist;
|
||||
+ if (addrlist != NULL) {
|
||||
+ /* OK, some result was found */
|
||||
+ ret = EOK;
|
||||
+ *_addrlist = addrlist;
|
||||
+ } else {
|
||||
+ /* No result was found */
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "No IPs usable for DNS was found for interface: %s.\n", ifname);
|
||||
+ ret = ENOENT;
|
||||
+ }
|
||||
+
|
||||
done:
|
||||
freeifaddrs(ifaces);
|
||||
return ret;
|
||||
diff --git a/src/providers/ldap/sdap_dyndns.c b/src/providers/ldap/sdap_dyndns.c
|
||||
index 0d9c9205792062378aa25aad6ac706058001433a..e99a4f6687035928f6775c38b9df6b2a06d38f38 100644
|
||||
--- a/src/providers/ldap/sdap_dyndns.c
|
||||
+++ b/src/providers/ldap/sdap_dyndns.c
|
||||
@@ -502,8 +502,12 @@ sdap_dyndns_get_addrs_send(TALLOC_CTX *mem_ctx,
|
||||
if (iface) {
|
||||
ret = sss_iface_addr_list_get(state, iface, &state->addresses);
|
||||
if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ DEBUG(ret == ENOENT ? SSSDBG_MINOR_FAILURE : SSSDBG_OP_FAILURE,
|
||||
"Cannot get list of addresses from interface %s\n", iface);
|
||||
+ /* non critical failure */
|
||||
+ if (ret == ENOENT) {
|
||||
+ ret = EOK;
|
||||
+ }
|
||||
}
|
||||
/* We're done. Just fake an async request completion */
|
||||
goto done;
|
||||
diff --git a/src/tests/cmocka/test_dyndns.c b/src/tests/cmocka/test_dyndns.c
|
||||
index 689e333d4e68c4a2582894d06b8b7b20c76b9be8..3214e90c063ea9a4cf6f6bc6507bf4e37b7d23a4 100644
|
||||
--- a/src/tests/cmocka/test_dyndns.c
|
||||
+++ b/src/tests/cmocka/test_dyndns.c
|
||||
@@ -247,6 +247,23 @@ void dyndns_test_get_multi_ifaddr(void **state)
|
||||
assert_true(check_leaks_pop(dyndns_test_ctx) == true);
|
||||
}
|
||||
|
||||
+void dyndns_test_get_ifaddr_enoent(void **state)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+ struct sss_iface_addr *addrlist = NULL;
|
||||
+
|
||||
+ check_leaks_push(dyndns_test_ctx);
|
||||
+ will_return_getifaddrs("eth0", "192.168.0.1");
|
||||
+ will_return_getifaddrs("eth1", "192.168.0.2");
|
||||
+ will_return_getifaddrs(NULL, NULL); /* sentinel */
|
||||
+ ret = sss_iface_addr_list_get(dyndns_test_ctx, "non_existing_interface",
|
||||
+ &addrlist);
|
||||
+ assert_int_equal(ret, ENOENT);
|
||||
+ talloc_free(addrlist);
|
||||
+
|
||||
+ assert_true(check_leaks_pop(dyndns_test_ctx) == true);
|
||||
+}
|
||||
+
|
||||
void dyndns_test_ok(void **state)
|
||||
{
|
||||
struct tevent_req *req;
|
||||
@@ -460,6 +477,9 @@ int main(int argc, const char *argv[])
|
||||
cmocka_unit_test_setup_teardown(dyndns_test_get_multi_ifaddr,
|
||||
dyndns_test_simple_setup,
|
||||
dyndns_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(dyndns_test_get_ifaddr_enoent,
|
||||
+ dyndns_test_simple_setup,
|
||||
+ dyndns_test_teardown),
|
||||
|
||||
/* Dynamic DNS update unit tests*/
|
||||
cmocka_unit_test_setup_teardown(dyndns_test_ok,
|
||||
--
|
||||
2.5.0
|
||||
|
194
0004-DYNDNS-support-mult.-interfaces-for-dyndns_iface-opt.patch
Normal file
194
0004-DYNDNS-support-mult.-interfaces-for-dyndns_iface-opt.patch
Normal file
@ -0,0 +1,194 @@
|
||||
From 7a7696e489087f3e02f7d484766dc55112fe7803 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Reichl <preichl@redhat.com>
|
||||
Date: Wed, 8 Jul 2015 09:08:03 -0400
|
||||
Subject: [PATCH 04/14] DYNDNS: support mult. interfaces for dyndns_iface opt
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2549
|
||||
---
|
||||
src/man/sssd-ad.5.xml | 11 +++---
|
||||
src/man/sssd-ipa.5.xml | 10 ++++--
|
||||
src/providers/dp_dyndns.c | 6 ++++
|
||||
src/providers/dp_dyndns.h | 4 +++
|
||||
src/providers/ldap/sdap_dyndns.c | 72 +++++++++++++++++++++++++++++++++++-----
|
||||
5 files changed, 87 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
|
||||
index 938a443e027b9bf83c75c240a7d6b2a0876b92c8..ff43ea37066514a87934d07b141e680416dcc05b 100644
|
||||
--- a/src/man/sssd-ad.5.xml
|
||||
+++ b/src/man/sssd-ad.5.xml
|
||||
@@ -754,15 +754,16 @@ ad_gpo_map_deny = +my_pam_service
|
||||
<listitem>
|
||||
<para>
|
||||
Optional. Applicable only when dyndns_update
|
||||
- is true. Choose the interface whose IP address
|
||||
- should be used for dynamic DNS updates.
|
||||
- </para>
|
||||
- <para>
|
||||
- NOTE: This option currently supports only one interface.
|
||||
+ is true. Choose the interface or a list of interfaces
|
||||
+ whose IP addresses should be used for dynamic DNS
|
||||
+ updates.
|
||||
</para>
|
||||
<para>
|
||||
Default: Use the IP address of the AD LDAP connection
|
||||
</para>
|
||||
+ <para>
|
||||
+ Example: dyndns_iface = em1, vnet1, vnet2
|
||||
+ </para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml
|
||||
index 0716b6235f93965170983856b930799bfded6258..d450c2fadbb1713096ff766bf536702195cfd137 100644
|
||||
--- a/src/man/sssd-ipa.5.xml
|
||||
+++ b/src/man/sssd-ipa.5.xml
|
||||
@@ -166,11 +166,12 @@
|
||||
<listitem>
|
||||
<para>
|
||||
Optional. Applicable only when dyndns_update
|
||||
- is true. Choose the interface whose IP address
|
||||
- should be used for dynamic DNS updates.
|
||||
+ is true. Choose the interface or a list of interfaces
|
||||
+ whose IP addresses should be used for dynamic DNS
|
||||
+ updates.
|
||||
</para>
|
||||
<para>
|
||||
- NOTE: This option currently supports only one interface.
|
||||
+ NOTE: This option currently supports multiple interfaces.
|
||||
</para>
|
||||
<para>
|
||||
NOTE: While it is still possible to use the old
|
||||
@@ -181,6 +182,9 @@
|
||||
<para>
|
||||
Default: Use the IP address of the IPA LDAP connection
|
||||
</para>
|
||||
+ <para>
|
||||
+ Example: dyndns_iface = em1, vnet1, vnet2
|
||||
+ </para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
diff --git a/src/providers/dp_dyndns.c b/src/providers/dp_dyndns.c
|
||||
index 2ac43a108ff6197d9e2662198a6da976ca348e76..76562840ef1d427629e41617b871caaedab779d4 100644
|
||||
--- a/src/providers/dp_dyndns.c
|
||||
+++ b/src/providers/dp_dyndns.c
|
||||
@@ -49,6 +49,12 @@ struct sss_iface_addr {
|
||||
struct sockaddr_storage *addr;
|
||||
};
|
||||
|
||||
+void sss_iface_addr_concatenate(struct sss_iface_addr **list,
|
||||
+ struct sss_iface_addr *list2)
|
||||
+{
|
||||
+ DLIST_CONCATENATE((*list), list2, struct sss_iface_addr*);
|
||||
+}
|
||||
+
|
||||
struct sss_iface_addr *
|
||||
sss_iface_addr_add(TALLOC_CTX *mem_ctx, struct sss_iface_addr **list,
|
||||
struct sockaddr_storage *ss)
|
||||
diff --git a/src/providers/dp_dyndns.h b/src/providers/dp_dyndns.h
|
||||
index 23b833dace58a0ecbb1e2e21963a55186f1d06a8..deba112538ad22cd7f59be07934778ee9d4361e7 100644
|
||||
--- a/src/providers/dp_dyndns.h
|
||||
+++ b/src/providers/dp_dyndns.h
|
||||
@@ -128,4 +128,8 @@ nsupdate_get_addrs_recv(struct tevent_req *req,
|
||||
struct sss_iface_addr **_addrlist,
|
||||
size_t *_count);
|
||||
|
||||
+void
|
||||
+sss_iface_addr_concatenate(struct sss_iface_addr **list,
|
||||
+ struct sss_iface_addr *list2);
|
||||
+
|
||||
#endif /* DP_DYNDNS_H_ */
|
||||
diff --git a/src/providers/ldap/sdap_dyndns.c b/src/providers/ldap/sdap_dyndns.c
|
||||
index e99a4f6687035928f6775c38b9df6b2a06d38f38..f5929cff3db6f724efcedeb963e3a12d04f6e1d3 100644
|
||||
--- a/src/providers/ldap/sdap_dyndns.c
|
||||
+++ b/src/providers/ldap/sdap_dyndns.c
|
||||
@@ -482,6 +482,65 @@ static void sdap_dyndns_get_addrs_done(struct tevent_req *subreq);
|
||||
static errno_t sdap_dyndns_add_ldap_conn(struct sdap_dyndns_get_addrs_state *state,
|
||||
struct sdap_handle *sh);
|
||||
|
||||
+static errno_t get_ifaces_addrs(TALLOC_CTX *mem_ctx,
|
||||
+ const char *iface,
|
||||
+ struct sss_iface_addr **_result)
|
||||
+{
|
||||
+ struct sss_iface_addr *result_addrs = NULL;
|
||||
+ struct sss_iface_addr *intf_addrs;
|
||||
+ TALLOC_CTX *tmp_ctx;
|
||||
+ char **list_of_intfs;
|
||||
+ int num_of_intfs;
|
||||
+ errno_t ret;
|
||||
+ int i;
|
||||
+
|
||||
+ tmp_ctx = talloc_new(NULL);
|
||||
+ if (tmp_ctx == NULL) {
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = split_on_separator(tmp_ctx, iface, ',', true, true, &list_of_intfs,
|
||||
+ &num_of_intfs);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "Parsing names of interfaces failed - %d:[%s].\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < num_of_intfs; i++) {
|
||||
+ ret = sss_iface_addr_list_get(tmp_ctx, list_of_intfs[i], &intf_addrs);
|
||||
+ if (ret == EOK) {
|
||||
+ if (result_addrs != NULL) {
|
||||
+ /* If there is already an existing list, head of this existing
|
||||
+ * list will be considered as parent talloc context for the
|
||||
+ * new list.
|
||||
+ */
|
||||
+ talloc_steal(result_addrs, intf_addrs);
|
||||
+ }
|
||||
+ sss_iface_addr_concatenate(&result_addrs, intf_addrs);
|
||||
+ } else if (ret == ENOENT) {
|
||||
+ /* non-critical failure */
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "Cannot get interface %s or there are no addresses "
|
||||
+ "bind to it.\n", list_of_intfs[i]);
|
||||
+ } else {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Cannot get list of addresses from interface %s - %d:[%s]\n",
|
||||
+ list_of_intfs[i], ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+ *_result = talloc_steal(mem_ctx, result_addrs);
|
||||
+
|
||||
+done:
|
||||
+ talloc_free(tmp_ctx);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static struct tevent_req *
|
||||
sdap_dyndns_get_addrs_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
@@ -500,14 +559,11 @@ sdap_dyndns_get_addrs_send(TALLOC_CTX *mem_ctx,
|
||||
}
|
||||
|
||||
if (iface) {
|
||||
- ret = sss_iface_addr_list_get(state, iface, &state->addresses);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(ret == ENOENT ? SSSDBG_MINOR_FAILURE : SSSDBG_OP_FAILURE,
|
||||
- "Cannot get list of addresses from interface %s\n", iface);
|
||||
- /* non critical failure */
|
||||
- if (ret == ENOENT) {
|
||||
- ret = EOK;
|
||||
- }
|
||||
+ ret = get_ifaces_addrs(state, iface, &state->addresses);
|
||||
+ if (ret != EOK || state->addresses == NULL) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "get_ifaces_addrs() failed: %d:[%s]\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
}
|
||||
/* We're done. Just fake an async request completion */
|
||||
goto done;
|
||||
--
|
||||
2.5.0
|
||||
|
107
0005-DYNDNS-special-value-for-dyndns_iface-option.patch
Normal file
107
0005-DYNDNS-special-value-for-dyndns_iface-option.patch
Normal file
@ -0,0 +1,107 @@
|
||||
From ef7a48d5acc481a207ac2821fc43651641f1b298 Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Reichl <preichl@redhat.com>
|
||||
Date: Tue, 14 Jul 2015 04:21:34 -0400
|
||||
Subject: [PATCH 05/14] DYNDNS: special value '*' for dyndns_iface option
|
||||
|
||||
Option dyndns_iface has now special value '*' which implies that IPs
|
||||
from add interfaces should be sent during DDNS update.
|
||||
---
|
||||
src/man/sssd-ad.5.xml | 6 ++++--
|
||||
src/man/sssd-ipa.5.xml | 9 ++++-----
|
||||
src/providers/dp_dyndns.c | 20 ++++++++++++++++----
|
||||
3 files changed, 24 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
|
||||
index ff43ea37066514a87934d07b141e680416dcc05b..3cbc10520098372d984d00425d03832d002d6672 100644
|
||||
--- a/src/man/sssd-ad.5.xml
|
||||
+++ b/src/man/sssd-ad.5.xml
|
||||
@@ -756,10 +756,12 @@ ad_gpo_map_deny = +my_pam_service
|
||||
Optional. Applicable only when dyndns_update
|
||||
is true. Choose the interface or a list of interfaces
|
||||
whose IP addresses should be used for dynamic DNS
|
||||
- updates.
|
||||
+ updates. Special value <quote>*</quote> implies that
|
||||
+ IPs from all interfaces should be used.
|
||||
</para>
|
||||
<para>
|
||||
- Default: Use the IP address of the AD LDAP connection
|
||||
+ Default: Use the IP addresses of the interface which
|
||||
+ is used for AD LDAP connection
|
||||
</para>
|
||||
<para>
|
||||
Example: dyndns_iface = em1, vnet1, vnet2
|
||||
diff --git a/src/man/sssd-ipa.5.xml b/src/man/sssd-ipa.5.xml
|
||||
index d450c2fadbb1713096ff766bf536702195cfd137..2e985991fde10827aff0e7c8e67f29a009683450 100644
|
||||
--- a/src/man/sssd-ipa.5.xml
|
||||
+++ b/src/man/sssd-ipa.5.xml
|
||||
@@ -168,10 +168,8 @@
|
||||
Optional. Applicable only when dyndns_update
|
||||
is true. Choose the interface or a list of interfaces
|
||||
whose IP addresses should be used for dynamic DNS
|
||||
- updates.
|
||||
- </para>
|
||||
- <para>
|
||||
- NOTE: This option currently supports multiple interfaces.
|
||||
+ updates. Special value <quote>*</quote> implies that
|
||||
+ IPs from all interfaces should be used.
|
||||
</para>
|
||||
<para>
|
||||
NOTE: While it is still possible to use the old
|
||||
@@ -180,7 +178,8 @@
|
||||
in their config file.
|
||||
</para>
|
||||
<para>
|
||||
- Default: Use the IP address of the IPA LDAP connection
|
||||
+ Default: Use the IP addresses of the interface which
|
||||
+ is used for IPA LDAP connection
|
||||
</para>
|
||||
<para>
|
||||
Example: dyndns_iface = em1, vnet1, vnet2
|
||||
diff --git a/src/providers/dp_dyndns.c b/src/providers/dp_dyndns.c
|
||||
index 76562840ef1d427629e41617b871caaedab779d4..03389acfba13e566540ca8b0570c0d009173575f 100644
|
||||
--- a/src/providers/dp_dyndns.c
|
||||
+++ b/src/providers/dp_dyndns.c
|
||||
@@ -42,6 +42,9 @@
|
||||
#define DYNDNS_TIMEOUT 15
|
||||
#endif /* DYNDNS_TIMEOUT */
|
||||
|
||||
+/* MASK represents special value for matching all interfaces */
|
||||
+#define MASK "*"
|
||||
+
|
||||
struct sss_iface_addr {
|
||||
struct sss_iface_addr *next;
|
||||
struct sss_iface_addr *prev;
|
||||
@@ -171,6 +174,16 @@ ok_for_dns(struct sockaddr *sa)
|
||||
return true;
|
||||
}
|
||||
|
||||
+static bool supported_address_family(sa_family_t sa_family)
|
||||
+{
|
||||
+ return sa_family == AF_INET || sa_family == AF_INET6;
|
||||
+}
|
||||
+
|
||||
+static bool matching_name(const char *ifname, const char *ifname2)
|
||||
+{
|
||||
+ return (strcmp(MASK, ifname) == 0) || (strcasecmp(ifname, ifname2) == 0);
|
||||
+}
|
||||
+
|
||||
/* Collect IP addresses associated with an interface */
|
||||
errno_t
|
||||
sss_iface_addr_list_get(TALLOC_CTX *mem_ctx, const char *ifname,
|
||||
@@ -200,10 +213,9 @@ sss_iface_addr_list_get(TALLOC_CTX *mem_ctx, const char *ifname,
|
||||
if (!ifa->ifa_addr) continue;
|
||||
|
||||
/* Add IP addresses to the list */
|
||||
- if ((ifa->ifa_addr->sa_family == AF_INET ||
|
||||
- ifa->ifa_addr->sa_family == AF_INET6) &&
|
||||
- strcasecmp(ifa->ifa_name, ifname) == 0 &&
|
||||
- ok_for_dns(ifa->ifa_addr)) {
|
||||
+ if (supported_address_family(ifa->ifa_addr->sa_family)
|
||||
+ && matching_name(ifname, ifa->ifa_name)
|
||||
+ && ok_for_dns(ifa->ifa_addr)) {
|
||||
|
||||
/* Add this address to the IP address list */
|
||||
address = talloc_zero(mem_ctx, struct sss_iface_addr);
|
||||
--
|
||||
2.5.0
|
||||
|
130
0006-TESTS-dyndns-tests-support-AAAA-addresses.patch
Normal file
130
0006-TESTS-dyndns-tests-support-AAAA-addresses.patch
Normal file
@ -0,0 +1,130 @@
|
||||
From cef454da178e7e7f097fade886f4d06ba6aa0f4f Mon Sep 17 00:00:00 2001
|
||||
From: Pavel Reichl <preichl@redhat.com>
|
||||
Date: Wed, 15 Jul 2015 10:58:38 -0400
|
||||
Subject: [PATCH 06/14] TESTS: dyndns tests support AAAA addresses
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2558
|
||||
---
|
||||
src/tests/cmocka/test_dyndns.c | 51 +++++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 38 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/src/tests/cmocka/test_dyndns.c b/src/tests/cmocka/test_dyndns.c
|
||||
index 3214e90c063ea9a4cf6f6bc6507bf4e37b7d23a4..e9d42cea37472b38ae2eb900368f2ce3f409fefc 100644
|
||||
--- a/src/tests/cmocka/test_dyndns.c
|
||||
+++ b/src/tests/cmocka/test_dyndns.c
|
||||
@@ -97,7 +97,9 @@ int __wrap_getifaddrs(struct ifaddrs **_ifap)
|
||||
struct ifaddrs *ifap_head = NULL;
|
||||
char *name;
|
||||
char *straddr;
|
||||
+ int ad_family;
|
||||
struct sockaddr_in *sa;
|
||||
+ void *dst;
|
||||
|
||||
while ((name = sss_mock_ptr_type(char *)) != NULL) {
|
||||
straddr = sss_mock_ptr_type(char *);
|
||||
@@ -105,6 +107,7 @@ int __wrap_getifaddrs(struct ifaddrs **_ifap)
|
||||
errno = EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
+ ad_family = sss_mock_type(int);
|
||||
|
||||
ifap = talloc_zero(global_mock_context, struct ifaddrs);
|
||||
if (ifap == NULL) {
|
||||
@@ -127,15 +130,33 @@ int __wrap_getifaddrs(struct ifaddrs **_ifap)
|
||||
|
||||
/* Do not alocate directly on ifap->ifa_addr to
|
||||
* avoid alignment warnings */
|
||||
- sa = talloc(ifap, struct sockaddr_in);
|
||||
+ if (ad_family == AF_INET) {
|
||||
+ sa = talloc(ifap, struct sockaddr_in);
|
||||
+ } else if (ad_family == AF_INET6) {
|
||||
+ sa = (struct sockaddr_in *) talloc(ifap, struct sockaddr_in6);
|
||||
+ } else {
|
||||
+ errno = EINVAL;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
if (sa == NULL) {
|
||||
errno = ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
- sa->sin_family = AF_INET;
|
||||
+
|
||||
+ sa->sin_family = ad_family;
|
||||
+
|
||||
+ if (ad_family == AF_INET) {
|
||||
+ dst = &sa->sin_addr;
|
||||
+ } else if (ad_family == AF_INET6) {
|
||||
+ dst = &((struct sockaddr_in6 *)sa)->sin6_addr;
|
||||
+ } else {
|
||||
+ errno = EINVAL;
|
||||
+ goto fail;
|
||||
+ }
|
||||
|
||||
/* convert straddr into ifa_addr */
|
||||
- if (inet_pton(AF_INET, straddr, &sa->sin_addr) != 1) {
|
||||
+ if (inet_pton(ad_family, straddr, dst) != 1) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -167,12 +188,16 @@ static void dyndns_test_done(struct tevent_req *req)
|
||||
ctx->tctx->done = true;
|
||||
}
|
||||
|
||||
-void will_return_getifaddrs(const char *ifname, const char *straddr)
|
||||
+void will_return_getifaddrs(const char *ifname, const char *straddr,
|
||||
+ int af_family)
|
||||
{
|
||||
will_return(__wrap_getifaddrs, ifname);
|
||||
if (ifname) {
|
||||
will_return(__wrap_getifaddrs, straddr);
|
||||
}
|
||||
+ if (straddr) {
|
||||
+ will_return(__wrap_getifaddrs, af_family);
|
||||
+ }
|
||||
}
|
||||
|
||||
void dyndns_test_get_ifaddr(void **state)
|
||||
@@ -182,9 +207,9 @@ void dyndns_test_get_ifaddr(void **state)
|
||||
char straddr[128];
|
||||
|
||||
check_leaks_push(dyndns_test_ctx);
|
||||
- will_return_getifaddrs("eth0", "192.168.0.1");
|
||||
- will_return_getifaddrs("eth1", "192.168.0.2");
|
||||
- will_return_getifaddrs(NULL, NULL); /* sentinel */
|
||||
+ will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
|
||||
+ will_return_getifaddrs("eth1", "192.168.0.2", AF_INET);
|
||||
+ will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
|
||||
ret = sss_iface_addr_list_get(dyndns_test_ctx, "eth0", &addrlist);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
@@ -212,9 +237,9 @@ void dyndns_test_get_multi_ifaddr(void **state)
|
||||
char straddr[128];
|
||||
|
||||
check_leaks_push(dyndns_test_ctx);
|
||||
- will_return_getifaddrs("eth0", "192.168.0.2");
|
||||
- will_return_getifaddrs("eth0", "192.168.0.1");
|
||||
- will_return_getifaddrs(NULL, NULL); /* sentinel */
|
||||
+ will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
|
||||
+ will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
|
||||
+ will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
|
||||
ret = sss_iface_addr_list_get(dyndns_test_ctx, "eth0", &addrlist);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
@@ -253,9 +278,9 @@ void dyndns_test_get_ifaddr_enoent(void **state)
|
||||
struct sss_iface_addr *addrlist = NULL;
|
||||
|
||||
check_leaks_push(dyndns_test_ctx);
|
||||
- will_return_getifaddrs("eth0", "192.168.0.1");
|
||||
- will_return_getifaddrs("eth1", "192.168.0.2");
|
||||
- will_return_getifaddrs(NULL, NULL); /* sentinel */
|
||||
+ will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
|
||||
+ will_return_getifaddrs("eth1", "192.168.0.2", AF_INET);
|
||||
+ will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
|
||||
ret = sss_iface_addr_list_get(dyndns_test_ctx, "non_existing_interface",
|
||||
&addrlist);
|
||||
assert_int_equal(ret, ENOENT);
|
||||
--
|
||||
2.5.0
|
||||
|
@ -0,0 +1,88 @@
|
||||
From 2322de0bd2fdc6b2ca64969df35662ab962620a4 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Tue, 21 Jul 2015 11:44:03 +0200
|
||||
Subject: [PATCH 07/14] IPA: Remove MPG groups if getgrgid was called before
|
||||
getpw()
|
||||
|
||||
https://fedorahosted.org/sssd/ticket/2724
|
||||
|
||||
This bug only affects IPA clients that are connected to IPA servers with
|
||||
AD trust and ID mapping in effect.
|
||||
|
||||
If an IPA client calls getgrgid() for an ID that matches a user, the
|
||||
user's private group would be returned and stored as a group entry.
|
||||
|
||||
Subsequent queries for that user would fail, because MPG domains impose
|
||||
uniqueness restriction for both the ID and name space across groups and
|
||||
users.
|
||||
|
||||
To work around that, we remove the UPG groups in MPG domains during a
|
||||
group lookup.
|
||||
|
||||
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||||
---
|
||||
src/providers/ipa/ipa_s2n_exop.c | 41 ++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 39 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
|
||||
index 812a4bbd707faf5c184594b562c148d1e704fd58..1e6368dc7ef1a6f60b541409f7f6740d602f0d43 100644
|
||||
--- a/src/providers/ipa/ipa_s2n_exop.c
|
||||
+++ b/src/providers/ipa/ipa_s2n_exop.c
|
||||
@@ -1764,6 +1764,7 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
|
||||
int tret;
|
||||
struct sysdb_attrs *gid_override_attrs = NULL;
|
||||
char ** exop_grouplist;
|
||||
+ struct ldb_message *msg;
|
||||
|
||||
tmp_ctx = talloc_new(NULL);
|
||||
if (tmp_ctx == NULL) {
|
||||
@@ -2005,8 +2006,44 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
|
||||
attrs->a.user.pw_dir, attrs->a.user.pw_shell,
|
||||
NULL, attrs->sysdb_attrs, NULL,
|
||||
timeout, now);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_user failed.\n");
|
||||
+ if (ret == EEXIST && dom->mpg == true) {
|
||||
+ /* This handles the case where getgrgid() was called for
|
||||
+ * this user, so a group was created in the cache
|
||||
+ */
|
||||
+ ret = sysdb_search_group_by_name(tmp_ctx, dom, name, NULL, &msg);
|
||||
+ if (ret != EOK) {
|
||||
+ /* Fail even on ENOENT, the group must be around */
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Could not delete MPG group [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_delete_group(dom, NULL, attrs->a.user.pw_uid);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "sysdb_delete_group failed for MPG group [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ ret = sysdb_store_user(dom, name, NULL,
|
||||
+ attrs->a.user.pw_uid,
|
||||
+ gid, attrs->a.user.pw_gecos,
|
||||
+ attrs->a.user.pw_dir,
|
||||
+ attrs->a.user.pw_shell,
|
||||
+ NULL, attrs->sysdb_attrs, NULL,
|
||||
+ timeout, now);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "sysdb_store_user failed for MPG user [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "sysdb_store_user failed [%d]: %s\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
goto done;
|
||||
}
|
||||
|
||||
--
|
||||
2.5.0
|
||||
|
27
0008-IPA-Better-debugging.patch
Normal file
27
0008-IPA-Better-debugging.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From f2fd03807a6a7d92b706f0964bd1bcf172766cd6 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 22 Jul 2015 15:17:57 +0200
|
||||
Subject: [PATCH 08/14] IPA: Better debugging
|
||||
|
||||
Reviewed-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
src/providers/ipa/ipa_subdomains_server.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
|
||||
index cd8c6301c4e4fbbf194ca98ce7a7bfe6215b381c..a9e2c1f700ef47716be868bad68590b8d5d0d42a 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains_server.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains_server.c
|
||||
@@ -623,6 +623,9 @@ ipa_server_trust_add_send(TALLOC_CTX *mem_ctx,
|
||||
|
||||
immediate:
|
||||
if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Could not add trusted subdomain %s from forest %s\n",
|
||||
+ subdom->name, state->forest);
|
||||
tevent_req_error(req, ret);
|
||||
} else {
|
||||
tevent_req_done(req);
|
||||
--
|
||||
2.5.0
|
||||
|
50
0009-UTIL-Lower-debug-level-in-perform_checks.patch
Normal file
50
0009-UTIL-Lower-debug-level-in-perform_checks.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From b5e5c04b5af74537c95213a72d4c916b50c05588 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 22 Jul 2015 16:29:09 +0200
|
||||
Subject: [PATCH 09/14] UTIL: Lower debug level in perform_checks()
|
||||
|
||||
Failures in perform_checks() don't have to be fatal, therefore the debug
|
||||
messages shouldn't be either.
|
||||
|
||||
Reviewed-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
src/util/check_and_open.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/util/check_and_open.c b/src/util/check_and_open.c
|
||||
index 59b90bf4b96731e385fcf92ed8bc251cb94abfda..b40ae2003e3de22ce9e4ca07cecc68e18a7abab4 100644
|
||||
--- a/src/util/check_and_open.c
|
||||
+++ b/src/util/check_and_open.c
|
||||
@@ -99,12 +99,12 @@ static errno_t perform_checks(struct stat *stat_buf,
|
||||
}
|
||||
|
||||
if ((mode & S_IFMT) != (st_mode & S_IFMT)) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "File is not the right type.\n");
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "File is not the right type.\n");
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if ((st_mode & ALLPERMS) != (mode & ALLPERMS)) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS,
|
||||
"File has the wrong (bit masked) mode [%.7o], "
|
||||
"expected [%.7o].\n",
|
||||
(st_mode & ALLPERMS), (mode & ALLPERMS));
|
||||
@@ -112,12 +112,12 @@ static errno_t perform_checks(struct stat *stat_buf,
|
||||
}
|
||||
|
||||
if (uid != (uid_t)(-1) && stat_buf->st_uid != uid) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "File must be owned by uid [%d].\n", uid);
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "File must be owned by uid [%d].\n", uid);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (gid != (gid_t)(-1) && stat_buf->st_gid != gid) {
|
||||
- DEBUG(SSSDBG_CRIT_FAILURE, "File must be owned by gid [%d].\n", gid);
|
||||
+ DEBUG(SSSDBG_TRACE_LIBS, "File must be owned by gid [%d].\n", gid);
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
--
|
||||
2.5.0
|
||||
|
116
0010-IPA-Handle-sssd-owned-keytabs-when-running-as-root.patch
Normal file
116
0010-IPA-Handle-sssd-owned-keytabs-when-running-as-root.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From 629fba06bc02e6ff4b25680532d298552fa55b22 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 22 Jul 2015 17:20:11 +0200
|
||||
Subject: [PATCH 10/14] IPA: Handle sssd-owned keytabs when running as root
|
||||
|
||||
https://fedorahosted.org/sssd/ticket/2718
|
||||
|
||||
This patch handles the case where the keytab is created with sssd:sssd
|
||||
ownership (perhaps by the IPA oddjob script) but SSSD runs as root,
|
||||
which is the default in many distributions.
|
||||
|
||||
Reviewed-by: Alexander Bokovoy <abokovoy@redhat.com>
|
||||
---
|
||||
src/providers/ipa/ipa_subdomains.h | 3 ++
|
||||
src/providers/ipa/ipa_subdomains_server.c | 46 +++++++++++++++++++++++++------
|
||||
2 files changed, 41 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_subdomains.h b/src/providers/ipa/ipa_subdomains.h
|
||||
index 5bc63a173a1a8967eb5de30a2da84a81377d3900..2302c5f03e80de2ea1efad424769e777cd6dd8d5 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains.h
|
||||
+++ b/src/providers/ipa/ipa_subdomains.h
|
||||
@@ -94,6 +94,9 @@ struct ipa_server_mode_ctx {
|
||||
|
||||
struct ipa_ad_server_ctx *trusts;
|
||||
struct ipa_ext_groups *ext_groups;
|
||||
+
|
||||
+ uid_t kt_owner_uid;
|
||||
+ uid_t kt_owner_gid;
|
||||
};
|
||||
|
||||
int ipa_ad_subdom_init(struct be_ctx *be_ctx,
|
||||
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
|
||||
index a9e2c1f700ef47716be868bad68590b8d5d0d42a..4bfea61e6dd0a02f6b723a39f7ba236c914009b0 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains_server.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains_server.c
|
||||
@@ -520,16 +520,28 @@ static errno_t ipa_getkeytab_recv(struct tevent_req *req, int *child_status)
|
||||
return EOK;
|
||||
}
|
||||
|
||||
-static errno_t ipa_check_keytab(const char *keytab)
|
||||
+static errno_t ipa_check_keytab(const char *keytab,
|
||||
+ uid_t kt_owner_uid,
|
||||
+ gid_t kt_owner_gid)
|
||||
{
|
||||
errno_t ret;
|
||||
|
||||
ret = check_file(keytab, getuid(), getgid(), S_IFREG|0600, 0, NULL, false);
|
||||
- if (ret != EOK) {
|
||||
- if (ret != ENOENT) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, "Failed to check for %s\n", keytab);
|
||||
- } else {
|
||||
- DEBUG(SSSDBG_TRACE_FUNC, "Keytab %s is not present\n", keytab);
|
||||
+ if (ret == ENOENT) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Keytab %s is not present\n", keytab);
|
||||
+ goto done;
|
||||
+ } else if (ret != EOK) {
|
||||
+ if (kt_owner_uid) {
|
||||
+ ret = check_file(keytab, kt_owner_uid, kt_owner_gid,
|
||||
+ S_IFREG|0600, 0, NULL, false);
|
||||
+ }
|
||||
+
|
||||
+ if (ret != EOK) {
|
||||
+ if (ret != ENOENT) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "Failed to check for %s\n", keytab);
|
||||
+ } else {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC, "Keytab %s is not present\n", keytab);
|
||||
+ }
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
@@ -648,7 +660,9 @@ static errno_t ipa_server_trust_add_1way(struct tevent_req *req)
|
||||
return EIO;
|
||||
}
|
||||
|
||||
- ret = ipa_check_keytab(state->keytab);
|
||||
+ ret = ipa_check_keytab(state->keytab,
|
||||
+ state->id_ctx->server_mode->kt_owner_uid,
|
||||
+ state->id_ctx->server_mode->kt_owner_gid);
|
||||
if (ret == EOK) {
|
||||
DEBUG(SSSDBG_TRACE_FUNC,
|
||||
"Keytab already present, can add the trust\n");
|
||||
@@ -704,7 +718,9 @@ static void ipa_server_trust_1way_kt_done(struct tevent_req *subreq)
|
||||
DEBUG(SSSDBG_TRACE_FUNC,
|
||||
"Keytab successfully retrieved to %s\n", state->keytab);
|
||||
|
||||
- ret = ipa_check_keytab(state->keytab);
|
||||
+ ret = ipa_check_keytab(state->keytab,
|
||||
+ state->id_ctx->server_mode->kt_owner_uid,
|
||||
+ state->id_ctx->server_mode->kt_owner_gid);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE, "ipa_check_keytab failed: %d\n", ret);
|
||||
tevent_req_error(req, ret);
|
||||
@@ -1029,6 +1045,20 @@ int ipa_ad_subdom_init(struct be_ctx *be_ctx,
|
||||
id_ctx->server_mode->hostname = hostname;
|
||||
id_ctx->server_mode->trusts = NULL;
|
||||
id_ctx->server_mode->ext_groups = NULL;
|
||||
+ id_ctx->server_mode->kt_owner_uid = 0;
|
||||
+ id_ctx->server_mode->kt_owner_gid = 0;
|
||||
+
|
||||
+ if (getuid() == 0) {
|
||||
+ /* We need to handle keytabs created by IPA oddjob script gracefully
|
||||
+ * even if we're running as root and IPA creates them as the SSSD user
|
||||
+ */
|
||||
+ ret = sss_user_by_name_or_uid(SSSD_USER,
|
||||
+ &id_ctx->server_mode->kt_owner_uid,
|
||||
+ &id_ctx->server_mode->kt_owner_gid);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get ID of %s\n", SSSD_USER);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
ret = ipa_ad_subdom_reinit(be_ctx, be_ctx->ev,
|
||||
be_ctx, id_ctx, be_ctx->domain);
|
||||
--
|
||||
2.5.0
|
||||
|
@ -0,0 +1,47 @@
|
||||
From 4c4bc726cfc0207681c00fc386e3707d47bfe3a4 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Mon, 10 Aug 2015 12:40:30 +0200
|
||||
Subject: [PATCH 11/14] LDAP: use ldb_binary_encode when printing attribute
|
||||
values
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/providers/ldap/sdap_utils.c | 11 ++++++++++-
|
||||
1 file changed, 10 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/providers/ldap/sdap_utils.c b/src/providers/ldap/sdap_utils.c
|
||||
index f5ce8ee54f60a6c4c4cdbd5e50b20d973c175e83..9da46ea70bf80e7f4d12fdfc7d1c97e99de8d000 100644
|
||||
--- a/src/providers/ldap/sdap_utils.c
|
||||
+++ b/src/providers/ldap/sdap_utils.c
|
||||
@@ -35,6 +35,7 @@ sdap_attrs_add_ldap_attr(struct sysdb_attrs *ldap_attrs,
|
||||
const char *objname = name ?: "object";
|
||||
const char *desc = attr_desc ?: attr_name;
|
||||
unsigned int num_values, i;
|
||||
+ char *printable;
|
||||
|
||||
ret = sysdb_attrs_get_el(ldap_attrs, attr_name, &el);
|
||||
if (ret) {
|
||||
@@ -50,8 +51,16 @@ sdap_attrs_add_ldap_attr(struct sysdb_attrs *ldap_attrs,
|
||||
} else {
|
||||
num_values = multivalued ? el->num_values : 1;
|
||||
for (i = 0; i < num_values; i++) {
|
||||
+ printable = ldb_binary_encode(ldap_attrs, el->values[i]);
|
||||
+ if (printable == NULL) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE, "ldb_binary_encode failed..\n");
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
DEBUG(SSSDBG_TRACE_INTERNAL, "Adding %s [%s] to attributes "
|
||||
- "of [%s].\n", desc, el->values[i].data, objname);
|
||||
+ "of [%s].\n", desc, printable, objname);
|
||||
+
|
||||
+ talloc_zfree(printable);
|
||||
|
||||
ret = sysdb_attrs_add_mem(attrs, attr_name, el->values[i].data,
|
||||
el->values[i].length);
|
||||
--
|
||||
2.5.0
|
||||
|
@ -0,0 +1,50 @@
|
||||
From 4c8af4a9bd8b0cdfa6820b3a39ae958869957dcb Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Mon, 10 Aug 2015 12:40:39 +0200
|
||||
Subject: [PATCH 12/14] IPA: Change the default of ldap_user_certificate to
|
||||
userCertificate;binary
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This is safe from ldb point of view, because ldb gurantees the data is
|
||||
NULL-terminated. We must be careful before we save the data, though.
|
||||
|
||||
Resolves:
|
||||
https://fedorahosted.org/sssd/ticket/2742
|
||||
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/man/sssd-ldap.5.xml | 2 +-
|
||||
src/providers/ipa/ipa_opts.h | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
|
||||
index f14090843fd32141ad4f491b69868aa7b2412301..0239f656e4fab7d8d85a922fdd0978acd80a236b 100644
|
||||
--- a/src/man/sssd-ldap.5.xml
|
||||
+++ b/src/man/sssd-ldap.5.xml
|
||||
@@ -821,7 +821,7 @@
|
||||
certificate of the user.
|
||||
</para>
|
||||
<para>
|
||||
- Default: no set in the general case, userCertificate
|
||||
+ Default: no set in the general case, userCertificate;binary
|
||||
for IPA
|
||||
</para>
|
||||
</listitem>
|
||||
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
|
||||
index 253c0715355536cc181c57beed5326a77e87e464..2f92ad765a1ca53611ed82e5e749c39d6f20a150 100644
|
||||
--- a/src/providers/ipa/ipa_opts.h
|
||||
+++ b/src/providers/ipa/ipa_opts.h
|
||||
@@ -203,7 +203,7 @@ struct sdap_attr_map ipa_user_map[] = {
|
||||
{ "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
|
||||
{ "ldap_user_ssh_public_key", "ipaSshPubKey", SYSDB_SSH_PUBKEY, NULL },
|
||||
{ "ldap_user_auth_type", "ipaUserAuthType", SYSDB_AUTH_TYPE, NULL },
|
||||
- { "ldap_user_certificate", "userCertificate", SYSDB_USER_CERT, NULL },
|
||||
+ { "ldap_user_certificate", "userCertificate;binary", SYSDB_USER_CERT, NULL },
|
||||
SDAP_ATTR_MAP_TERMINATOR
|
||||
};
|
||||
|
||||
--
|
||||
2.5.0
|
||||
|
377
0013-UTIL-Provide-a-common-interface-to-safely-create-tem.patch
Normal file
377
0013-UTIL-Provide-a-common-interface-to-safely-create-tem.patch
Normal file
@ -0,0 +1,377 @@
|
||||
From e3f5577a446e1f6f37c1dfd2c7d6c95f5c4551ab Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Wed, 12 Aug 2015 12:41:44 +0200
|
||||
Subject: [PATCH 13/14] UTIL: Provide a common interface to safely create
|
||||
temporary files
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
src/tests/cmocka/test_utils.c | 175 ++++++++++++++++++++++++++++++++++++++++++
|
||||
src/util/util.c | 127 ++++++++++++++++++++++++++++++
|
||||
src/util/util.h | 21 +++++
|
||||
3 files changed, 323 insertions(+)
|
||||
|
||||
diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c
|
||||
index d3d00feda0bdd4048519f90ba48ae9d1042a95a1..c7ebe0997ec00197e8852bedbcf26ef1f6394fc3 100644
|
||||
--- a/src/tests/cmocka/test_utils.c
|
||||
+++ b/src/tests/cmocka/test_utils.c
|
||||
@@ -1212,6 +1212,168 @@ void test_fix_domain_in_name_list(void **state)
|
||||
talloc_free(dom);
|
||||
}
|
||||
|
||||
+struct unique_file_test_ctx {
|
||||
+ char *filename;
|
||||
+};
|
||||
+
|
||||
+static int unique_file_test_setup(void **state)
|
||||
+{
|
||||
+ struct unique_file_test_ctx *test_ctx;
|
||||
+
|
||||
+ assert_true(leak_check_setup());
|
||||
+ check_leaks_push(global_talloc_context);
|
||||
+
|
||||
+ test_ctx = talloc_zero(global_talloc_context, struct unique_file_test_ctx);
|
||||
+ assert_non_null(test_ctx);
|
||||
+
|
||||
+ test_ctx->filename = talloc_strdup(test_ctx, "test_unique_file_XXXXXX");
|
||||
+ assert_non_null(test_ctx);
|
||||
+
|
||||
+ *state = test_ctx;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int unique_file_test_teardown(void **state)
|
||||
+{
|
||||
+ struct unique_file_test_ctx *test_ctx;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ test_ctx = talloc_get_type(*state, struct unique_file_test_ctx);
|
||||
+
|
||||
+ errno = 0;
|
||||
+ ret = unlink(test_ctx->filename);
|
||||
+ if (ret != 0 && errno != ENOENT) {
|
||||
+ fail();
|
||||
+ }
|
||||
+
|
||||
+ talloc_free(test_ctx);
|
||||
+ assert_true(check_leaks_pop(global_talloc_context) == true);
|
||||
+ assert_true(leak_check_teardown());
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void assert_destructor(TALLOC_CTX *owner,
|
||||
+ struct unique_file_test_ctx *test_ctx)
|
||||
+{
|
||||
+ int fd;
|
||||
+ errno_t ret;
|
||||
+ char *check_filename;
|
||||
+
|
||||
+ /* Test that the destructor works */
|
||||
+ if (owner == NULL) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ check_filename = talloc_strdup(test_ctx, test_ctx->filename);
|
||||
+ assert_non_null(check_filename);
|
||||
+
|
||||
+ talloc_free(owner);
|
||||
+
|
||||
+ ret = check_and_open_readonly(test_ctx->filename, &fd,
|
||||
+ geteuid(), getegid(),
|
||||
+ (S_IRUSR | S_IWUSR | S_IFREG), 0);
|
||||
+ close(fd);
|
||||
+ assert_int_not_equal(ret, EOK);
|
||||
+}
|
||||
+
|
||||
+static void sss_unique_file_test(struct unique_file_test_ctx *test_ctx,
|
||||
+ bool test_destructor)
|
||||
+{
|
||||
+ int fd;
|
||||
+ errno_t ret;
|
||||
+ struct stat sb;
|
||||
+ TALLOC_CTX *owner = NULL;
|
||||
+
|
||||
+ if (test_destructor) {
|
||||
+ owner = talloc_new(test_ctx);
|
||||
+ assert_non_null(owner);
|
||||
+ }
|
||||
+
|
||||
+ fd = sss_unique_file(owner, test_ctx->filename, &ret);
|
||||
+ assert_int_not_equal(fd, -1);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ ret = check_fd(fd, geteuid(), getegid(),
|
||||
+ (S_IRUSR | S_IWUSR | S_IFREG), 0, &sb);
|
||||
+ close(fd);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ assert_destructor(owner, test_ctx);
|
||||
+}
|
||||
+
|
||||
+static void test_sss_unique_file(void **state)
|
||||
+{
|
||||
+ struct unique_file_test_ctx *test_ctx;
|
||||
+ test_ctx = talloc_get_type(*state, struct unique_file_test_ctx);
|
||||
+ sss_unique_file_test(test_ctx, false);
|
||||
+}
|
||||
+
|
||||
+static void test_sss_unique_file_destruct(void **state)
|
||||
+{
|
||||
+ struct unique_file_test_ctx *test_ctx;
|
||||
+ test_ctx = talloc_get_type(*state, struct unique_file_test_ctx);
|
||||
+ sss_unique_file_test(test_ctx, true);
|
||||
+}
|
||||
+
|
||||
+static void test_sss_unique_file_neg(void **state)
|
||||
+{
|
||||
+ int fd;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ fd = sss_unique_file(NULL, discard_const("badpattern"), &ret);
|
||||
+ assert_int_equal(fd, -1);
|
||||
+ assert_int_equal(ret, EINVAL);
|
||||
+}
|
||||
+
|
||||
+static void sss_unique_filename_test(struct unique_file_test_ctx *test_ctx,
|
||||
+ bool test_destructor)
|
||||
+{
|
||||
+ int fd;
|
||||
+ errno_t ret;
|
||||
+ char *tmp_filename;
|
||||
+ TALLOC_CTX *owner = NULL;
|
||||
+
|
||||
+ tmp_filename = talloc_strdup(test_ctx, test_ctx->filename);
|
||||
+ assert_non_null(tmp_filename);
|
||||
+
|
||||
+ if (test_destructor) {
|
||||
+ owner = talloc_new(test_ctx);
|
||||
+ assert_non_null(owner);
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_unique_filename(owner, test_ctx->filename);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ assert_int_equal(strncmp(test_ctx->filename,
|
||||
+ tmp_filename,
|
||||
+ strlen(tmp_filename) - sizeof("XXXXXX")),
|
||||
+ 0);
|
||||
+
|
||||
+ ret = check_and_open_readonly(test_ctx->filename, &fd,
|
||||
+ geteuid(), getegid(),
|
||||
+ (S_IRUSR | S_IWUSR | S_IFREG), 0);
|
||||
+ close(fd);
|
||||
+ assert_int_equal(ret, EOK);
|
||||
+
|
||||
+ assert_destructor(owner, test_ctx);
|
||||
+}
|
||||
+
|
||||
+static void test_sss_unique_filename(void **state)
|
||||
+{
|
||||
+ struct unique_file_test_ctx *test_ctx;
|
||||
+
|
||||
+ test_ctx = talloc_get_type(*state, struct unique_file_test_ctx);
|
||||
+ sss_unique_filename_test(test_ctx, false);
|
||||
+}
|
||||
+
|
||||
+static void test_sss_unique_filename_destruct(void **state)
|
||||
+{
|
||||
+ struct unique_file_test_ctx *test_ctx;
|
||||
+
|
||||
+ test_ctx = talloc_get_type(*state, struct unique_file_test_ctx);
|
||||
+ sss_unique_filename_test(test_ctx, true);
|
||||
+}
|
||||
+
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
poptContext pc;
|
||||
@@ -1275,6 +1437,19 @@ int main(int argc, const char *argv[])
|
||||
cmocka_unit_test_setup_teardown(test_fix_domain_in_name_list,
|
||||
confdb_test_setup,
|
||||
confdb_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_sss_unique_file,
|
||||
+ unique_file_test_setup,
|
||||
+ unique_file_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_sss_unique_file_destruct,
|
||||
+ unique_file_test_setup,
|
||||
+ unique_file_test_teardown),
|
||||
+ cmocka_unit_test(test_sss_unique_file_neg),
|
||||
+ cmocka_unit_test_setup_teardown(test_sss_unique_filename,
|
||||
+ unique_file_test_setup,
|
||||
+ unique_file_test_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_sss_unique_filename_destruct,
|
||||
+ unique_file_test_setup,
|
||||
+ unique_file_test_teardown),
|
||||
};
|
||||
|
||||
/* Set debug level to invalid value so we can deside if -d 0 was used. */
|
||||
diff --git a/src/util/util.c b/src/util/util.c
|
||||
index cfd26a58b31048996e9669163b821282b219b2de..61e5efedce45ba4a70d57ce19406eafe8373692c 100644
|
||||
--- a/src/util/util.c
|
||||
+++ b/src/util/util.c
|
||||
@@ -957,3 +957,130 @@ errno_t sss_utc_to_time_t(const char *str, const char *format, time_t *_unix_tim
|
||||
*_unix_time = ut;
|
||||
return EOK;
|
||||
}
|
||||
+
|
||||
+struct tmpfile_watch {
|
||||
+ const char *filename;
|
||||
+};
|
||||
+
|
||||
+static int unlink_dbg(const char *filename)
|
||||
+{
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = unlink(filename);
|
||||
+ if (ret != 0) {
|
||||
+ if (errno == 2) {
|
||||
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
||||
+ "File already removed: [%s]\n", filename);
|
||||
+ return 0;
|
||||
+ } else {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Cannot remove temporary file [%s]\n", filename);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int unique_filename_destructor(void *memptr)
|
||||
+{
|
||||
+ struct tmpfile_watch *tw = talloc_get_type(memptr, struct tmpfile_watch);
|
||||
+
|
||||
+ if (tw == NULL || tw->filename == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "BUG: Wrong private pointer\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Unlinking [%s]\n", tw->filename);
|
||||
+
|
||||
+ return unlink_dbg(tw->filename);
|
||||
+}
|
||||
+
|
||||
+static struct tmpfile_watch *tmpfile_watch_set(TALLOC_CTX *owner,
|
||||
+ const char *filename)
|
||||
+{
|
||||
+ struct tmpfile_watch *tw = NULL;
|
||||
+
|
||||
+ tw = talloc_zero(owner, struct tmpfile_watch);
|
||||
+ if (tw == NULL) {
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ tw->filename = talloc_strdup(tw, filename);
|
||||
+ if (tw->filename == NULL) {
|
||||
+ talloc_free(tw);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ talloc_set_destructor((TALLOC_CTX *) tw,
|
||||
+ unique_filename_destructor);
|
||||
+ return tw;
|
||||
+}
|
||||
+
|
||||
+int sss_unique_file_ex(TALLOC_CTX *owner,
|
||||
+ char *path_tmpl,
|
||||
+ mode_t file_umask,
|
||||
+ errno_t *_err)
|
||||
+{
|
||||
+ size_t tmpl_len;
|
||||
+ errno_t ret;
|
||||
+ int fd = -1;
|
||||
+ mode_t old_umask;
|
||||
+ struct tmpfile_watch *tw = NULL;
|
||||
+
|
||||
+ tmpl_len = strlen(path_tmpl);
|
||||
+ if (tmpl_len < 6 || strcmp(path_tmpl + (tmpl_len - 6), "XXXXXX") != 0) {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Template too short or doesn't end with XXXXXX!\n");
|
||||
+ ret = EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ old_umask = umask(file_umask);
|
||||
+ fd = mkstemp(path_tmpl);
|
||||
+ umask(old_umask);
|
||||
+ if (fd == -1) {
|
||||
+ ret = errno;
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "mkstemp(\"%s\") failed [%d]: %s!\n",
|
||||
+ path_tmpl, ret, strerror(ret));
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (owner != NULL) {
|
||||
+ tw = tmpfile_watch_set(owner, path_tmpl);
|
||||
+ if (tw == NULL) {
|
||||
+ unlink_dbg(path_tmpl);
|
||||
+ ret = ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = EOK;
|
||||
+done:
|
||||
+ if (_err) {
|
||||
+ *_err = ret;
|
||||
+ }
|
||||
+ return fd;
|
||||
+}
|
||||
+
|
||||
+int sss_unique_file(TALLOC_CTX *owner,
|
||||
+ char *path_tmpl,
|
||||
+ errno_t *_err)
|
||||
+{
|
||||
+ return sss_unique_file_ex(owner, path_tmpl, 077, _err);
|
||||
+}
|
||||
+
|
||||
+errno_t sss_unique_filename(TALLOC_CTX *owner, char *path_tmpl)
|
||||
+{
|
||||
+ int fd;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ fd = sss_unique_file(owner, path_tmpl, &ret);
|
||||
+ /* We only care about a unique file name */
|
||||
+ if (fd >= 0) {
|
||||
+ close(fd);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/util/util.h b/src/util/util.h
|
||||
index 3d90cf0d1024b93016987a4d3e8a515359fd974d..ecbed1c9843b16ba6cf31927c6fd3db8c72aefde 100644
|
||||
--- a/src/util/util.h
|
||||
+++ b/src/util/util.h
|
||||
@@ -653,4 +653,25 @@ int get_seuser(TALLOC_CTX *mem_ctx, const char *login_name,
|
||||
/* convert time from generalized form to unix time */
|
||||
errno_t sss_utc_to_time_t(const char *str, const char *format, time_t *unix_time);
|
||||
|
||||
+/* Creates a unique file using mkstemp with provided umask. The template
|
||||
+ * must end with XXXXXX. Returns the fd, sets _err to an errno value on error.
|
||||
+ *
|
||||
+ * Prefer using sss_unique_file() as it uses a secure umask internally.
|
||||
+ */
|
||||
+int sss_unique_file_ex(TALLOC_CTX *mem_ctx,
|
||||
+ char *path_tmpl,
|
||||
+ mode_t file_umask,
|
||||
+ errno_t *_err);
|
||||
+int sss_unique_file(TALLOC_CTX *owner,
|
||||
+ char *path_tmpl,
|
||||
+ errno_t *_err);
|
||||
+
|
||||
+/* Creates a unique filename using mkstemp with secure umask. The template
|
||||
+ * must end with XXXXXX
|
||||
+ *
|
||||
+ * path_tmpl must be a talloc context. Destructor would be set on the filename
|
||||
+ * so that it's guaranteed the file is removed.
|
||||
+ */
|
||||
+int sss_unique_filename(TALLOC_CTX *owner, char *path_tmpl);
|
||||
+
|
||||
#endif /* __SSSD_UTIL_H__ */
|
||||
--
|
||||
2.5.0
|
||||
|
447
0014-IPA-Always-re-fetch-the-keytab-from-the-IPA-server.patch
Normal file
447
0014-IPA-Always-re-fetch-the-keytab-from-the-IPA-server.patch
Normal file
@ -0,0 +1,447 @@
|
||||
From b2d318b91bb9d6ea1bef827031b980b8d6ec7b44 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Hrozek <jhrozek@redhat.com>
|
||||
Date: Fri, 24 Jul 2015 13:13:08 +0200
|
||||
Subject: [PATCH 14/14] IPA: Always re-fetch the keytab from the IPA server
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Even if a keytab for one-way trust exists, re-fetch the keytab again and
|
||||
try to use it. Fall back to the previous one if it exists.
|
||||
|
||||
This is in order to allow the admin to re-establish the trust keytabs
|
||||
with a simple sssd restart.
|
||||
|
||||
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
||||
---
|
||||
Makefile.am | 2 +
|
||||
src/providers/ipa/ipa_subdomains.c | 4 +-
|
||||
src/providers/ipa/ipa_subdomains_server.c | 83 +++++++++----
|
||||
src/tests/cmocka/test_ipa_subdomains_server.c | 166 ++++++++++++++++++++++++--
|
||||
4 files changed, 221 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index b8cbc6df23ded1edb945a709b6dbe1c44eb54017..4e58b4f419607272f35363875054320af0899dcf 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -2501,6 +2501,8 @@ test_ipa_subdom_server_LDFLAGS = \
|
||||
-Wl,-wrap,krb5_kt_default \
|
||||
-Wl,-wrap,execle \
|
||||
-Wl,-wrap,execve \
|
||||
+ -Wl,-wrap,rename \
|
||||
+ -Wl,-wrap,sss_unique_filename \
|
||||
$(NULL)
|
||||
test_ipa_subdom_server_LDADD = \
|
||||
$(PAM_LIBS) \
|
||||
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
|
||||
index cf72784473747c67d44a5d887faf867cfe62ce2b..c688ddb9bb9b643e0695c1901a4ca467f71853da 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains.c
|
||||
@@ -264,7 +264,7 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
|
||||
ret = get_idmap_data_from_range(r, domain_name, &name1, &sid1, &rid1,
|
||||
&range1, &mapping1);
|
||||
if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, ("get_idmap_data_from_range failed.\n"));
|
||||
+ DEBUG(SSSDBG_OP_FAILURE, "get_idmap_data_from_range failed.\n");
|
||||
goto done;
|
||||
}
|
||||
for (d = 0; d < c; d++) {
|
||||
@@ -272,7 +272,7 @@ static errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
|
||||
&sid2, &rid2, &range2, &mapping2);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
- ("get_idmap_data_from_range failed.\n"));
|
||||
+ "get_idmap_data_from_range failed.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
|
||||
index 4bfea61e6dd0a02f6b723a39f7ba236c914009b0..dfecab1bc362b5772379bae6d51f9cef8443f225 100644
|
||||
--- a/src/providers/ipa/ipa_subdomains_server.c
|
||||
+++ b/src/providers/ipa/ipa_subdomains_server.c
|
||||
@@ -445,6 +445,17 @@ static void ipa_getkeytab_exec(const char *ccache,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
+ /* ipa-getkeytab cannot add keys to an empty file, let's unlink it and only
|
||||
+ * use the filename */
|
||||
+ ret = unlink(keytab_path);
|
||||
+ if (ret == -1) {
|
||||
+ ret = errno;
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "Failed to unlink the temporary ccname [%d][%s]\n",
|
||||
+ ret, sss_strerror(ret));
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
errno = 0;
|
||||
ret = execle(IPA_GETKEYTAB_PATH, IPA_GETKEYTAB_PATH,
|
||||
"-r", "-s", server, "-p", principal, "-k", keytab_path, NULL,
|
||||
@@ -561,6 +572,7 @@ struct ipa_server_trust_add_state {
|
||||
uint32_t direction;
|
||||
const char *forest;
|
||||
const char *keytab;
|
||||
+ char *new_keytab;
|
||||
const char *principal;
|
||||
const char *forest_realm;
|
||||
const char *ccache;
|
||||
@@ -660,21 +672,20 @@ static errno_t ipa_server_trust_add_1way(struct tevent_req *req)
|
||||
return EIO;
|
||||
}
|
||||
|
||||
- ret = ipa_check_keytab(state->keytab,
|
||||
- state->id_ctx->server_mode->kt_owner_uid,
|
||||
- state->id_ctx->server_mode->kt_owner_gid);
|
||||
- if (ret == EOK) {
|
||||
- DEBUG(SSSDBG_TRACE_FUNC,
|
||||
- "Keytab already present, can add the trust\n");
|
||||
- return EOK;
|
||||
- } else if (ret != ENOENT) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE,
|
||||
- "Failed to check for keytab: %d\n", ret);
|
||||
+ state->new_keytab = talloc_asprintf(state, "%sXXXXXX", state->keytab);
|
||||
+ if (state->new_keytab == NULL) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot set up ipa_get_keytab\n");
|
||||
+ return ENOMEM;
|
||||
+ }
|
||||
+
|
||||
+ ret = sss_unique_filename(state, state->new_keytab);
|
||||
+ if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create temporary keytab name\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
DEBUG(SSSDBG_TRACE_FUNC,
|
||||
- "No keytab for %s\n", state->subdom->name);
|
||||
+ "Will re-fetch keytab for %s\n", state->subdom->name);
|
||||
|
||||
hostname = dp_opt_get_string(state->id_ctx->ipa_options->basic,
|
||||
IPA_HOSTNAME);
|
||||
@@ -691,7 +702,7 @@ static errno_t ipa_server_trust_add_1way(struct tevent_req *req)
|
||||
state->ccache,
|
||||
hostname,
|
||||
state->principal,
|
||||
- state->keytab);
|
||||
+ state->new_keytab);
|
||||
if (subreq == NULL) {
|
||||
return ENOMEM;
|
||||
}
|
||||
@@ -710,23 +721,49 @@ static void ipa_server_trust_1way_kt_done(struct tevent_req *subreq)
|
||||
ret = ipa_getkeytab_recv(subreq, NULL);
|
||||
talloc_zfree(subreq);
|
||||
if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, "ipa_getkeytab_recv failed: %d\n", ret);
|
||||
- tevent_req_error(req, ret);
|
||||
- return;
|
||||
+ /* Do not fail here, but try to check and use the previous keytab,
|
||||
+ * if any */
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE, "ipa_getkeytab_recv failed: %d\n", ret);
|
||||
+ } else {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "Keytab successfully retrieved to %s\n", state->new_keytab);
|
||||
}
|
||||
|
||||
- DEBUG(SSSDBG_TRACE_FUNC,
|
||||
- "Keytab successfully retrieved to %s\n", state->keytab);
|
||||
-
|
||||
- ret = ipa_check_keytab(state->keytab,
|
||||
+ ret = ipa_check_keytab(state->new_keytab,
|
||||
state->id_ctx->server_mode->kt_owner_uid,
|
||||
state->id_ctx->server_mode->kt_owner_gid);
|
||||
- if (ret != EOK) {
|
||||
- DEBUG(SSSDBG_OP_FAILURE, "ipa_check_keytab failed: %d\n", ret);
|
||||
- tevent_req_error(req, ret);
|
||||
- return;
|
||||
+ if (ret == EOK) {
|
||||
+ ret = rename(state->new_keytab, state->keytab);
|
||||
+ if (ret == -1) {
|
||||
+ ret = errno;
|
||||
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
||||
+ "rename failed [%d][%s].\n", ret, strerror(ret));
|
||||
+ tevent_req_error(req, ret);
|
||||
+ return;
|
||||
+ }
|
||||
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Keytab renamed to %s\n", state->keytab);
|
||||
+ } else if (ret != EOK) {
|
||||
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
||||
+ "Trying to recover and use the previous keytab, if available\n");
|
||||
+ ret = ipa_check_keytab(state->keytab,
|
||||
+ state->id_ctx->server_mode->kt_owner_uid,
|
||||
+ state->id_ctx->server_mode->kt_owner_gid);
|
||||
+ if (ret == EOK) {
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "The previous keytab %s contains the expected principal\n",
|
||||
+ state->keytab);
|
||||
+ } else {
|
||||
+ DEBUG(SSSDBG_OP_FAILURE,
|
||||
+ "Cannot use the old keytab: %d\n", ret);
|
||||
+ /* Nothing we can do now */
|
||||
+ tevent_req_error(req, ret);
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
|
||||
+ DEBUG(SSSDBG_TRACE_FUNC,
|
||||
+ "Keytab %s contains the expected principals\n", state->new_keytab);
|
||||
+
|
||||
ret = ipa_server_trust_add_step(req);
|
||||
if (ret != EOK) {
|
||||
DEBUG(SSSDBG_OP_FAILURE,
|
||||
diff --git a/src/tests/cmocka/test_ipa_subdomains_server.c b/src/tests/cmocka/test_ipa_subdomains_server.c
|
||||
index a4cb8c2b7538dc84b74e0227205b73780844b652..fb9bd80e299c05fa230599d442fa361ae757dcd3 100644
|
||||
--- a/src/tests/cmocka/test_ipa_subdomains_server.c
|
||||
+++ b/src/tests/cmocka/test_ipa_subdomains_server.c
|
||||
@@ -66,33 +66,79 @@
|
||||
#define ONEWAY_PRINC DOM_FLAT"$"
|
||||
#define ONEWAY_AUTHID ONEWAY_PRINC"@"SUBDOM_REALM
|
||||
|
||||
+static bool global_rename_called;
|
||||
+
|
||||
krb5_error_code __wrap_krb5_kt_default(krb5_context context, krb5_keytab *id)
|
||||
{
|
||||
return krb5_kt_resolve(context, KEYTAB_PATH, id);
|
||||
}
|
||||
|
||||
-static void create_dummy_keytab(void)
|
||||
+static void create_dummy_keytab(const char *dummy_kt)
|
||||
{
|
||||
errno_t ret;
|
||||
|
||||
- assert_non_null(ONEWAY_KEYTAB);
|
||||
+ assert_non_null(dummy_kt);
|
||||
mock_keytab_with_contents(global_talloc_context,
|
||||
- ONEWAY_KEYTAB, ONEWAY_AUTHID);
|
||||
+ dummy_kt, ONEWAY_AUTHID);
|
||||
|
||||
- ret = access(ONEWAY_KEYTAB, R_OK);
|
||||
+ ret = access(dummy_kt, R_OK);
|
||||
assert_int_equal(ret, 0);
|
||||
}
|
||||
|
||||
+static int wrap_exec(void)
|
||||
+{
|
||||
+ const char *test_kt;
|
||||
+ const char *fail_creating_kt;
|
||||
+
|
||||
+ test_kt = getenv("TEST_KT_ENV");
|
||||
+ if (test_kt == NULL) {
|
||||
+ _exit(1);
|
||||
+ }
|
||||
+ unsetenv("TEST_KT_ENV");
|
||||
+
|
||||
+ fail_creating_kt = getenv("KT_CREATE_FAIL");
|
||||
+ if (fail_creating_kt != NULL) {
|
||||
+ _exit(1);
|
||||
+ }
|
||||
+
|
||||
+ create_dummy_keytab(test_kt);
|
||||
+ _exit(0);
|
||||
+
|
||||
+ return 1; /* Should not happen */
|
||||
+}
|
||||
+
|
||||
int __wrap_execle(const char *path, const char *arg, ...)
|
||||
{
|
||||
- create_dummy_keytab();
|
||||
- _exit(0);
|
||||
+ return wrap_exec();
|
||||
}
|
||||
|
||||
int __wrap_execve(const char *path, const char *arg, ...)
|
||||
{
|
||||
- create_dummy_keytab();
|
||||
- _exit(0);
|
||||
+ return wrap_exec();
|
||||
+}
|
||||
+
|
||||
+errno_t __real_sss_unique_filename(TALLOC_CTX *owner, char *path_tmpl);
|
||||
+
|
||||
+errno_t __wrap_sss_unique_filename(TALLOC_CTX *owner, char *path_tmpl)
|
||||
+{
|
||||
+ int ret;
|
||||
+ int sret;
|
||||
+
|
||||
+ ret = __real_sss_unique_filename(owner, path_tmpl);
|
||||
+ if (ret == EOK) {
|
||||
+
|
||||
+ sret = setenv("TEST_KT_ENV", path_tmpl, 1);
|
||||
+ assert_int_equal(sret, 0);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+int __real_rename(const char *old, const char *new);
|
||||
+
|
||||
+int __wrap_rename(const char *old, const char *new)
|
||||
+{
|
||||
+ global_rename_called = true;
|
||||
+ return __real_rename(old, new);
|
||||
}
|
||||
|
||||
struct trust_test_ctx {
|
||||
@@ -100,6 +146,7 @@ struct trust_test_ctx {
|
||||
struct be_ctx *be_ctx;
|
||||
|
||||
struct ipa_id_ctx *ipa_ctx;
|
||||
+ bool expect_rename;
|
||||
};
|
||||
|
||||
static struct ipa_id_ctx *mock_ipa_ctx(TALLOC_CTX *mem_ctx,
|
||||
@@ -244,6 +291,8 @@ static int test_ipa_server_create_trusts_setup(void **state)
|
||||
|
||||
mock_keytab_with_contents(test_ctx, KEYTAB_PATH, KEYTAB_TEST_PRINC);
|
||||
|
||||
+ global_rename_called = false;
|
||||
+
|
||||
*state = test_ctx;
|
||||
return 0;
|
||||
}
|
||||
@@ -260,6 +309,11 @@ static int test_ipa_server_create_trusts_teardown(void **state)
|
||||
unlink(ONEWAY_KEYTAB);
|
||||
/* Ignore failures */
|
||||
|
||||
+ /* If a test needs this variable, it should be set again in
|
||||
+ * each test
|
||||
+ */
|
||||
+ unsetenv("KT_CREATE_FAIL");
|
||||
+
|
||||
talloc_free(test_ctx);
|
||||
return 0;
|
||||
}
|
||||
@@ -612,6 +666,8 @@ static void test_ipa_server_create_oneway(void **state)
|
||||
|
||||
assert_null(test_ctx->ipa_ctx->server_mode->trusts);
|
||||
|
||||
+ test_ctx->expect_rename = true;
|
||||
+
|
||||
req = ipa_server_create_trusts_send(test_ctx,
|
||||
test_ctx->tctx->ev,
|
||||
test_ctx->be_ctx,
|
||||
@@ -635,6 +691,8 @@ static void test_ipa_server_create_trusts_oneway(struct tevent_req *req)
|
||||
talloc_zfree(req);
|
||||
assert_int_equal(ret, EOK);
|
||||
|
||||
+ assert_true(test_ctx->expect_rename == global_rename_called);
|
||||
+
|
||||
ret = access(ONEWAY_KEYTAB, R_OK);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
@@ -674,10 +732,46 @@ static void test_ipa_server_create_oneway_kt_exists(void **state)
|
||||
|
||||
add_test_1way_subdomains(test_ctx);
|
||||
|
||||
- create_dummy_keytab();
|
||||
+ create_dummy_keytab(ONEWAY_KEYTAB);
|
||||
ret = access(ONEWAY_KEYTAB, R_OK);
|
||||
assert_int_equal(ret, 0);
|
||||
|
||||
+ test_ctx->expect_rename = true;
|
||||
+
|
||||
+ assert_null(test_ctx->ipa_ctx->server_mode->trusts);
|
||||
+
|
||||
+ req = ipa_server_create_trusts_send(test_ctx,
|
||||
+ test_ctx->tctx->ev,
|
||||
+ test_ctx->be_ctx,
|
||||
+ test_ctx->ipa_ctx,
|
||||
+ test_ctx->be_ctx->domain);
|
||||
+ assert_non_null(req);
|
||||
+
|
||||
+ tevent_req_set_callback(req, test_ipa_server_create_trusts_oneway, test_ctx);
|
||||
+
|
||||
+ ret = test_ev_loop(test_ctx->tctx);
|
||||
+ assert_int_equal(ret, ERR_OK);
|
||||
+}
|
||||
+
|
||||
+/* Test scenario where a keytab already exists, but refresh fails. In this case,
|
||||
+ * sssd should attempt to reuse the previous keytab
|
||||
+ */
|
||||
+static void test_ipa_server_create_oneway_kt_refresh_fallback(void **state)
|
||||
+{
|
||||
+ struct trust_test_ctx *test_ctx =
|
||||
+ talloc_get_type(*state, struct trust_test_ctx);
|
||||
+ struct tevent_req *req;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ add_test_1way_subdomains(test_ctx);
|
||||
+
|
||||
+ create_dummy_keytab(ONEWAY_KEYTAB);
|
||||
+ ret = access(ONEWAY_KEYTAB, R_OK);
|
||||
+ assert_int_equal(ret, 0);
|
||||
+
|
||||
+ setenv("KT_CREATE_FAIL", "1", 1);
|
||||
+ test_ctx->expect_rename = false;
|
||||
+
|
||||
assert_null(test_ctx->ipa_ctx->server_mode->trusts);
|
||||
|
||||
req = ipa_server_create_trusts_send(test_ctx,
|
||||
@@ -693,6 +787,54 @@ static void test_ipa_server_create_oneway_kt_exists(void **state)
|
||||
assert_int_equal(ret, ERR_OK);
|
||||
}
|
||||
|
||||
+/* Tests case where there's no keytab and retrieving fails. Just fail the
|
||||
+ * request in that case
|
||||
+ */
|
||||
+static void test_ipa_server_create_trusts_oneway_fail(struct tevent_req *req);
|
||||
+
|
||||
+static void test_ipa_server_create_oneway_kt_refresh_fail(void **state)
|
||||
+{
|
||||
+ struct trust_test_ctx *test_ctx =
|
||||
+ talloc_get_type(*state, struct trust_test_ctx);
|
||||
+ struct tevent_req *req;
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ add_test_1way_subdomains(test_ctx);
|
||||
+
|
||||
+ setenv("KT_CREATE_FAIL", "1", 1);
|
||||
+ test_ctx->expect_rename = false;
|
||||
+
|
||||
+ assert_null(test_ctx->ipa_ctx->server_mode->trusts);
|
||||
+
|
||||
+ req = ipa_server_create_trusts_send(test_ctx,
|
||||
+ test_ctx->tctx->ev,
|
||||
+ test_ctx->be_ctx,
|
||||
+ test_ctx->ipa_ctx,
|
||||
+ test_ctx->be_ctx->domain);
|
||||
+ assert_non_null(req);
|
||||
+
|
||||
+ tevent_req_set_callback(req,
|
||||
+ test_ipa_server_create_trusts_oneway_fail,
|
||||
+ test_ctx);
|
||||
+
|
||||
+ ret = test_ev_loop(test_ctx->tctx);
|
||||
+ assert_int_equal(ret, ERR_OK);
|
||||
+}
|
||||
+
|
||||
+static void test_ipa_server_create_trusts_oneway_fail(struct tevent_req *req)
|
||||
+{
|
||||
+ struct trust_test_ctx *test_ctx = \
|
||||
+ tevent_req_callback_data(req, struct trust_test_ctx);
|
||||
+ errno_t ret;
|
||||
+
|
||||
+ ret = ipa_server_create_trusts_recv(req);
|
||||
+ assert_int_not_equal(ret, EOK);
|
||||
+
|
||||
+ assert_true(test_ctx->expect_rename == global_rename_called);
|
||||
+
|
||||
+ test_ev_done(test_ctx->tctx, EOK);
|
||||
+}
|
||||
+
|
||||
static void test_ipa_server_trust_oneway_init(void **state)
|
||||
{
|
||||
struct trust_test_ctx *test_ctx =
|
||||
@@ -749,6 +891,12 @@ int main(int argc, const char *argv[])
|
||||
cmocka_unit_test_setup_teardown(test_ipa_server_create_oneway_kt_exists,
|
||||
test_ipa_server_create_trusts_setup,
|
||||
test_ipa_server_create_trusts_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_ipa_server_create_oneway_kt_refresh_fallback,
|
||||
+ test_ipa_server_create_trusts_setup,
|
||||
+ test_ipa_server_create_trusts_teardown),
|
||||
+ cmocka_unit_test_setup_teardown(test_ipa_server_create_oneway_kt_refresh_fail,
|
||||
+ test_ipa_server_create_trusts_setup,
|
||||
+ test_ipa_server_create_trusts_teardown),
|
||||
cmocka_unit_test_setup_teardown(test_ipa_server_trust_oneway_init,
|
||||
test_ipa_server_create_trusts_setup,
|
||||
test_ipa_server_create_trusts_teardown),
|
||||
--
|
||||
2.5.0
|
||||
|
18
sssd.spec
18
sssd.spec
@ -29,7 +29,7 @@
|
||||
|
||||
Name: sssd
|
||||
Version: 1.13.0
|
||||
Release: 4%{?dist}
|
||||
Release: 5%{?dist}
|
||||
Group: Applications/System
|
||||
Summary: System Security Services Daemon
|
||||
License: GPLv3+
|
||||
@ -40,6 +40,18 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
|
||||
### Patches ###
|
||||
Patch0001: 0001-SSSDConfig-return-list-for-list_active_domains.patch
|
||||
Patch0002: 0002-KRB5-Return-right-data-provider-error-code.patch
|
||||
Patch0003: 0003-DYNDNS-sss_iface_addr_list_get-return-ENOENT.patch
|
||||
Patch0004: 0004-DYNDNS-support-mult.-interfaces-for-dyndns_iface-opt.patch
|
||||
Patch0005: 0005-DYNDNS-special-value-for-dyndns_iface-option.patch
|
||||
Patch0006: 0006-TESTS-dyndns-tests-support-AAAA-addresses.patch
|
||||
Patch0007: 0007-IPA-Remove-MPG-groups-if-getgrgid-was-called-before-.patch
|
||||
Patch0008: 0008-IPA-Better-debugging.patch
|
||||
Patch0009: 0009-UTIL-Lower-debug-level-in-perform_checks.patch
|
||||
Patch0010: 0010-IPA-Handle-sssd-owned-keytabs-when-running-as-root.patch
|
||||
Patch0011: 0011-LDAP-use-ldb_binary_encode-when-printing-attribute-v.patch
|
||||
Patch0012: 0012-IPA-Change-the-default-of-ldap_user_certificate-to-u.patch
|
||||
Patch0013: 0013-UTIL-Provide-a-common-interface-to-safely-create-tem.patch
|
||||
Patch0014: 0014-IPA-Always-re-fetch-the-keytab-from-the-IPA-server.patch
|
||||
|
||||
### Dependencies ###
|
||||
Requires: sssd-common = %{version}-%{release}
|
||||
@ -1012,10 +1024,14 @@ fi
|
||||
%{_libdir}/%{name}/modules/libwbclient.so
|
||||
|
||||
%changelog
|
||||
* Mon Sep 07 2015 Lukas Slebodnik <lslebodn@redhat.com> - 1.13.0-5
|
||||
- Backport upstream patches required by FreeIPA 4.2.1
|
||||
|
||||
* Tue Jul 21 2015 Lukas Slebodnik <lslebodn@redhat.com> - 1.13.0-4
|
||||
- Fix ipa-migration bug
|
||||
- Resolves: upstream #2719 - IPA: returned unknown dp error code with disabled
|
||||
migration mode
|
||||
|
||||
* Wed Jul 08 2015 Lukas Slebodnik <lslebodn@redhat.com> - 1.13.0-3
|
||||
- New upstream release 1.13.0
|
||||
- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.13.0
|
||||
|
Loading…
Reference in New Issue
Block a user