New upstream release 1.13.4

- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.13.4
This commit is contained in:
Lukas Slebodnik 2016-04-14 12:56:06 +02:00
parent 6b01857bc5
commit 19237d03ed
111 changed files with 8 additions and 20583 deletions

1
.gitignore vendored
View File

@ -67,3 +67,4 @@ sssd-1.2.91.tar.gz
/sssd-1.13.1.tar.gz /sssd-1.13.1.tar.gz
/sssd-1.13.2.tar.gz /sssd-1.13.2.tar.gz
/sssd-1.13.3.tar.gz /sssd-1.13.3.tar.gz
/sssd-1.13.4.tar.gz

View File

@ -1,43 +0,0 @@
From 207813a4dffb033dde6e3f4c08946864dcf6064a Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 18 Dec 2015 13:16:29 +0100
Subject: [PATCH 01/49] nfs idmap: fix infinite loop
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves:
https://fedorahosted.org/sssd/ticket/2909
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Noam Meltzer <tsnoam@gmail.com>
(cherry picked from commit 2a256e4e4b64891fe846e933589506daa68aa13e)
---
src/sss_client/nfs/sss_nfs_client.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/sss_client/nfs/sss_nfs_client.c b/src/sss_client/nfs/sss_nfs_client.c
index 64cb67a8b75ec04c1d6fa03905f5427bbe6c1e82..8fd993005606a52217dc306f1816c3f88a283aa0 100644
--- a/src/sss_client/nfs/sss_nfs_client.c
+++ b/src/sss_client/nfs/sss_nfs_client.c
@@ -157,7 +157,7 @@ static int get_user_from_mc(char *name, size_t len, uid_t uid)
goto done;
}
buf = p;
- rc = sss_nss_mc_getpwuid(uid, &pwd, buf, BUF_LEN);
+ rc = sss_nss_mc_getpwuid(uid, &pwd, buf, buflen);
} while (rc == ERANGE);
if (rc == 0) {
@@ -198,7 +198,7 @@ static int get_group_from_mc(char *name, size_t len, id_t gid)
goto done;
}
buf = p;
- rc = sss_nss_mc_getgrgid(gid, &grp, buf, BUF_LEN);
+ rc = sss_nss_mc_getgrgid(gid, &grp, buf, buflen);
} while (rc == ERANGE);
if (rc == 0) {
--
2.5.0

View File

@ -1,32 +0,0 @@
From 86c589c8e334e24dfdea910c85da14ebd77972ac Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 14 Dec 2015 17:16:13 +0100
Subject: [PATCH 02/49] Use right domain for user lookups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Related to https://fedorahosted.org/sssd/ticket/2910
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit cc1370dab6de99e50ac41126b500382f0aaa73ae)
---
src/providers/ldap/sdap_async_groups.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index c2a618d40cef14e64c899f3982153ab0bcde8358..b154bd079577c49883acbd36a557f6ba56ed017e 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -2474,7 +2474,7 @@ static errno_t sdap_nested_group_populate_users(TALLOC_CTX *mem_ctx,
ret = ENOMEM;
goto done;
}
- ret = sysdb_search_users(tmp_ctx, domain, filter,
+ ret = sysdb_search_users(tmp_ctx, user_dom, filter,
search_attrs, &count, &msgs);
talloc_zfree(filter);
talloc_zfree(clean_orig_dn);
--
2.5.0

View File

@ -1,114 +0,0 @@
From 1a3304eb0fdeec439c9e9fb64f7b5069c7ac6620 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 15 Dec 2015 17:20:18 +0100
Subject: [PATCH 03/49] sdap_save_grpmem: determine domain by SID if possible
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves https://fedorahosted.org/sssd/ticket/2910
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 0c1fe8a15cced95e8451ad4c9260c5e4ecca45f1)
---
src/providers/ldap/sdap_async_groups.c | 48 +++++++++++++++++++++++++---------
1 file changed, 35 insertions(+), 13 deletions(-)
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index b154bd079577c49883acbd36a557f6ba56ed017e..24c9f4d39fecfa9806e4dbe23c2395d201bbf9a0 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -874,6 +874,7 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx,
const char *group_name;
char **userdns = NULL;
size_t nuserdns = 0;
+ struct sss_domain_info *group_dom = NULL;
int ret;
if (dom->ignore_group_members) {
@@ -884,7 +885,34 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx,
return EOK;
}
- ret = sdap_get_group_primary_name(memctx, opts, attrs, dom, &group_name);
+ ret = sysdb_attrs_get_string(attrs, SYSDB_SID_STR, &group_sid);
+ if (ret != EOK) {
+ /* Try harder. */
+ ret = sdap_attrs_get_sid_str(memctx, opts->idmap_ctx, attrs,
+ opts->group_map[SDAP_AT_GROUP_OBJECTSID].sys_name,
+ discard_const(&group_sid));
+ if (ret != EOK) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Failed to get group sid\n");
+ group_sid = NULL;
+ }
+ }
+
+ if (group_sid != NULL) {
+ group_dom = sss_get_domain_by_sid_ldap_fallback(get_domains_head(dom),
+ group_sid);
+ if (group_dom == NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC, "SID [%s] does not belong to any known "
+ "domain, using [%s].\n", group_sid,
+ dom->name);
+ }
+ }
+
+ if (group_dom == NULL) {
+ group_dom = dom;
+ }
+
+ ret = sdap_get_group_primary_name(memctx, opts, attrs, group_dom,
+ &group_name);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "Failed to get group name\n");
goto fail;
@@ -895,7 +923,7 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx,
* are reported with tokenGroups, too
*/
if (opts->schema_type == SDAP_SCHEMA_AD) {
- ret = sdap_dn_by_primary_gid(memctx, attrs, dom, opts,
+ ret = sdap_dn_by_primary_gid(memctx, attrs, group_dom, opts,
&userdns, &nuserdns);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE,
@@ -910,15 +938,9 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx,
* https://fedorahosted.org/sssd/ticket/2522
*/
if (opts->schema_type == SDAP_SCHEMA_IPA_V1) {
- ret = sysdb_attrs_get_string(attrs, SYSDB_SID_STR, &group_sid);
- if (ret != EOK) {
- DEBUG(SSSDBG_TRACE_FUNC, "Failed to get group sid\n");
- group_sid = NULL;
- }
-
if (group_sid != NULL) {
- ret = retain_extern_members(memctx, dom, group_name, group_sid,
- &userdns, &nuserdns);
+ ret = retain_extern_members(memctx, group_dom, group_name,
+ group_sid, &userdns, &nuserdns);
if (ret != EOK) {
DEBUG(SSSDBG_TRACE_INTERNAL,
"retain_extern_members failed: %d:[%s].\n",
@@ -949,7 +971,7 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx,
goto fail;
}
- ret = sdap_fill_memberships(opts, group_attrs, ctx, dom, ghosts,
+ ret = sdap_fill_memberships(opts, group_attrs, ctx, group_dom, ghosts,
el->values, el->num_values,
userdns, nuserdns);
if (ret) {
@@ -960,8 +982,8 @@ static int sdap_save_grpmem(TALLOC_CTX *memctx,
}
}
- ret = sysdb_store_group(dom, group_name, 0, group_attrs,
- dom->group_timeout, now);
+ ret = sysdb_store_group(group_dom, group_name, 0, group_attrs,
+ group_dom->group_timeout, now);
if (ret) {
DEBUG(SSSDBG_MINOR_FAILURE, "sysdb_store_group failed: [%d][%s].\n",
ret, strerror(ret));
--
2.5.0

View File

@ -1,69 +0,0 @@
From ac80cf29e6f04550f35172345bec0577340b3c47 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 5 Jan 2016 13:46:55 +0100
Subject: [PATCH 04/49] ipa_s2n_save_objects(): use configured user and group
timeout
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves https://fedorahosted.org/sssd/ticket/2899
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit acce97e8d97e81a9e660d46c4e3c00bcb423c035)
---
src/providers/ipa/ipa_s2n_exop.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index bcd11749fbde4cae2a47b9b2182138ae04f2d6bc..d101a437dfaf2829013f9e3e3705a7161c654d78 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -1743,7 +1743,6 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
{
int ret;
time_t now;
- uint64_t timeout = 10*60*60; /* FIXME: find a better timeout ! */
struct sss_nss_homedir_ctx homedir_ctx;
char *name = NULL;
char *realm;
@@ -1947,7 +1946,7 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
* SYSDB_INITGR_EXPIRE will be set.*/
ret = sysdb_attrs_add_time_t(attrs->sysdb_attrs,
SYSDB_INITGR_EXPIRE,
- time(NULL) + timeout);
+ time(NULL) + dom->user_timeout);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"sysdb_attrs_add_time_t failed.\n");
@@ -2006,7 +2005,7 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
gid, attrs->a.user.pw_gecos,
attrs->a.user.pw_dir, attrs->a.user.pw_shell,
NULL, attrs->sysdb_attrs, NULL,
- timeout, now);
+ dom->user_timeout, now);
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
@@ -2034,7 +2033,7 @@ 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);
+ dom->user_timeout, now);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE,
"sysdb_store_user failed for MPG user [%d]: %s\n",
@@ -2174,7 +2173,8 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
}
ret = sysdb_store_group(dom, name, attrs->a.group.gr_gid,
- attrs->sysdb_attrs, timeout, now);
+ attrs->sysdb_attrs, dom->group_timeout,
+ now);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_group failed.\n");
goto done;
--
2.5.0

View File

@ -1,44 +0,0 @@
From 81dfc2be7f2ea92e5fe9749f1b5b64b6c7b12f21 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 6 Jan 2016 18:09:16 +0100
Subject: [PATCH 05/49] SPEC: Change package ownership of
%{pubconfpath}/krb5.include.d
krb5 domain mapping files are stored to the directory
%{pubconfpath}/krb5.include.d. It can be stored by ipa or ad provider.
However this directory was owned by sub-package sssd-ipa. And ad provider
can be installed without this package. Therefore %{pubconfpath}/krb5.include.d
should be owned by common dependency.
The owner of this directory was also fixed to sssd.
It's already done by make install. It was changed only in spec file.
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit b978d3e423c18d5697e6c1398c07e444e6f98e3f)
---
contrib/sssd.spec.in | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in
index 710ba92209d4a4d6e45b63bf7bf693fd5ec5f490..9855e11a8bb0ff3f50ceeae98f383c514011cc90 100644
--- a/contrib/sssd.spec.in
+++ b/contrib/sssd.spec.in
@@ -765,6 +765,7 @@ rm -rf $RPM_BUILD_ROOT
%files krb5-common
%defattr(-,root,root,-)
%doc COPYING
+%attr(755,sssd,sssd) %dir %{pubconfpath}/krb5.include.d
%attr(4750,root,sssd) %{_libexecdir}/%{servicename}/ldap_child
%attr(4750,root,sssd) %{_libexecdir}/%{servicename}/krb5_child
@@ -782,7 +783,6 @@ rm -rf $RPM_BUILD_ROOT
%files ipa -f sssd_ipa.lang
%defattr(-,root,root,-)
%doc COPYING
-%attr(755,root,root) %dir %{pubconfpath}/krb5.include.d
%attr(700,sssd,sssd) %dir %{keytabdir}
%{_libdir}/%{name}/libsss_ipa.so
%attr(4750,root,sssd) %{_libexecdir}/%{servicename}/selinux_child
--
2.5.0

View File

@ -1,89 +0,0 @@
From cce018a29027fe531de9191cdc905ab201deb133 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 5 Jan 2016 13:20:14 +0100
Subject: [PATCH 06/49] AD SRV: prefer site-local DCs in LDAP ping
Resolves:
https://fedorahosted.org/sssd/ticket/2765
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit a1c6869c67fcf4971ac843315b97bf46893ca92d)
---
src/providers/ad/ad_srv.c | 40 ++++++++++++++++++++++++++++++----------
1 file changed, 30 insertions(+), 10 deletions(-)
diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c
index 123aac6a4a73a60b5d597d9b34eb5fbd7865f8d3..e719272520cee11739431a686a6cf09aaf76947e 100644
--- a/src/providers/ad/ad_srv.c
+++ b/src/providers/ad/ad_srv.c
@@ -118,7 +118,8 @@ static void ad_get_dc_servers_done(struct tevent_req *subreq);
static struct tevent_req *ad_get_dc_servers_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct resolv_ctx *resolv_ctx,
- const char *domain)
+ const char *discovery_domain,
+ const char *site)
{
struct ad_get_dc_servers_state *state = NULL;
struct tevent_req *req = NULL;
@@ -133,21 +134,39 @@ static struct tevent_req *ad_get_dc_servers_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- domains = talloc_zero_array(state, const char *, 2);
+ domains = talloc_zero_array(state, const char *, 3);
if (domains == NULL) {
ret = ENOMEM;
goto immediately;
}
- domains[0] = talloc_strdup(domains, domain);
- if (domains[0] == NULL) {
- ret = ENOMEM;
- goto immediately;
+ if (site == NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Looking up domain controllers in domain "
+ "%s\n", discovery_domain);
+
+ domains[0] = talloc_strdup(domains, discovery_domain);
+ if (domains[0] == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+ } else {
+ DEBUG(SSSDBG_TRACE_FUNC, "Looking up domain controllers in domain "
+ "%s and site %s\n", discovery_domain, site);
+
+ domains[0] = talloc_asprintf(state, AD_SITE_DOMAIN_FMT,
+ site, discovery_domain);
+ if (domains[0] == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ domains[1] = talloc_strdup(domains, discovery_domain);
+ if (domains[1] == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
}
- DEBUG(SSSDBG_TRACE_FUNC, "Looking up domain controllers in domain %s\n",
- domain);
-
subreq = fo_discover_srv_send(state, ev, resolv_ctx,
"ldap", FO_PROTO_TCP, domains);
if (subreq == NULL) {
@@ -692,7 +711,8 @@ struct tevent_req *ad_srv_plugin_send(TALLOC_CTX *mem_ctx,
DEBUG(SSSDBG_TRACE_FUNC, "About to find domain controllers\n");
subreq = ad_get_dc_servers_send(state, ev, ctx->be_res->resolv,
- state->discovery_domain);
+ state->discovery_domain,
+ state->ctx->ad_site_override);
if (subreq == NULL) {
ret = ENOMEM;
goto immediately;
--
2.5.0

View File

@ -1,86 +0,0 @@
From a83b56cc7cf9b74299475727ff41f61f42002f4a Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 21 Dec 2015 15:51:09 +0100
Subject: [PATCH 07/49] ldap: remove originalMeberOf if there is no memberOf
Since originalMemerberOf is not mapped directly to an original attribute
and is handled specially it is not automatically removed if there is no
memberOf in the original object anymore. This patch put
originalMemerberOf on the list of attribute which should be removed in
that case.
Resolves https://fedorahosted.org/sssd/ticket/2917
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 9a2f018c0f68a3ada4cea4128a861a7f85893f22)
---
src/providers/ipa/ipa_s2n_exop.c | 12 +++++++++++-
src/providers/ldap/ldap_common.c | 8 +++++++-
2 files changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
index d101a437dfaf2829013f9e3e3705a7161c654d78..1d233cd52c18b4b6ed753bd92d186ac02ed2cb80 100644
--- a/src/providers/ipa/ipa_s2n_exop.c
+++ b/src/providers/ipa/ipa_s2n_exop.c
@@ -1764,6 +1764,8 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
struct sysdb_attrs *gid_override_attrs = NULL;
char ** exop_grouplist;
struct ldb_message *msg;
+ struct ldb_message_element *el = NULL;
+ const char *missing[] = {NULL, NULL};
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
@@ -1993,6 +1995,12 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
}
}
+ ret = sysdb_attrs_get_el_ext(attrs->sysdb_attrs,
+ SYSDB_ORIG_MEMBEROF, false, &el);
+ if (ret == ENOENT) {
+ missing[0] = SYSDB_ORIG_MEMBEROF;
+ }
+
ret = sysdb_transaction_start(dom->sysdb);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
@@ -2004,7 +2012,9 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
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,
+ NULL, attrs->sysdb_attrs,
+ missing[0] == NULL ? NULL
+ : discard_const(missing),
dom->user_timeout, now);
if (ret == EEXIST && dom->mpg == true) {
/* This handles the case where getgrgid() was called for
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index aa4c6cb851a5735e051ef2c024ca0171a4f61148..df4d52bc7426033852899c49bc0fa7a0f1aa9ed6 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -780,7 +780,7 @@ errno_t list_missing_attrs(TALLOC_CTX *mem_ctx,
/* Allocate the maximum possible values for missing_attrs, to
* be on the safe side
*/
- missing = talloc_array(tmp_ctx, char *, attr_count);
+ missing = talloc_array(tmp_ctx, char *, attr_count + 2);
if (!missing) {
ret = ENOMEM;
goto done;
@@ -831,6 +831,12 @@ errno_t list_missing_attrs(TALLOC_CTX *mem_ctx,
/* Attribute could not be found. Add to the missing list */
missing[k] = talloc_steal(missing, sysdb_name);
k++;
+
+ /* Remove originalMemberOf as well if MemberOf is missing */
+ if (strcmp(sysdb_name, SYSDB_MEMBEROF) == 0) {
+ missing[k] = talloc_strdup(missing, SYSDB_ORIG_MEMBEROF);
+ k++;
+ }
}
}
--
2.5.0

View File

@ -1,37 +0,0 @@
From d0bd229965c51af3dfe79d21a5fcd25cc1903b0c Mon Sep 17 00:00:00 2001
From: Petr Cech <pcech@redhat.com>
Date: Mon, 11 Jan 2016 06:18:33 -0500
Subject: [PATCH 08/49] KRB5: Adding DNS SRV lookup for krb5 provider
This patch add DNS SRV lookup for krb5 provider.
Resolves:
https://fedorahosted.org/sssd/ticket/2888
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 684191e61d891b1c34f3742a40d5a2ed6a1192dd)
---
src/providers/krb5/krb5_init.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/providers/krb5/krb5_init.c b/src/providers/krb5/krb5_init.c
index f1c63107642fba8441ff563bd9ecd7eff233d65c..4f36d905b1d5e89466998fba946f9f6f6915f51d 100644
--- a/src/providers/krb5/krb5_init.c
+++ b/src/providers/krb5/krb5_init.c
@@ -169,6 +169,13 @@ int sssm_krb5_auth_init(struct be_ctx *bectx,
}
talloc_set_destructor((TALLOC_CTX *) ctx, krb5_ctx_re_destructor);
+ ret = be_fo_set_dns_srv_lookup_plugin(bectx, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to set SRV lookup plugin "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto fail;
+ }
+
*ops = &krb5_auth_ops;
*pvt_auth_data = ctx;
return EOK;
--
2.5.0

View File

@ -1,49 +0,0 @@
From b516864d5216fa6cf7238c3ea777f060cde383ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 13 Jan 2016 13:15:09 +0100
Subject: [PATCH 09/49] SDAP: do not fail if refs are found but not processed
It is possible to end up with not-processed referrals when
using AD provider and ldap_referrals=true.
Resolves:
https://fedorahosted.org/sssd/ticket/2906
Reviewed-by: Stephen Gallagher <sgallagh@redhat.com>
(cherry picked from commit 468495d91d536603a1c485424275b6dcf2bb83de)
---
src/providers/ldap/sdap_async.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
index 668bd7b465bbfefad13ab0b7061cd16a05dfbef1..5260aafebf7570291876b2433dbcf44ffb5b0011 100644
--- a/src/providers/ldap/sdap_async.c
+++ b/src/providers/ldap/sdap_async.c
@@ -1653,16 +1653,6 @@ static void generic_ext_search_handler(struct tevent_req *subreq,
}
if (ref_count > 0) {
- if (dp_opt_get_bool(opts->basic, SDAP_REFERRALS)) {
- /* We got back referrals here, but they should have
- * been processed internally by openldap libs.
- * This should never happen.
- */
- talloc_free(refs);
- tevent_req_error(req, EINVAL);
- return;
- }
-
/* We will ignore referrals in the generic handler */
DEBUG(SSSDBG_TRACE_ALL,
"Request included referrals which were ignored.\n");
@@ -1674,6 +1664,7 @@ static void generic_ext_search_handler(struct tevent_req *subreq,
}
}
+ talloc_free(refs);
tevent_req_done(req);
}
--
2.5.0

View File

@ -1,35 +0,0 @@
From 70828dd44d1c35a9084d39f8420e1b984fb2fcaa Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Mon, 2 Nov 2015 14:59:49 +0100
Subject: [PATCH 10/49] sudo: remove unused param name in sdap_sudo_get_usn()
Reviewed-by: Petr Cech <pcech@redhat.com>
(cherry picked from commit e307c269fe1dc94a1771b459c5925e449ba7668b)
---
src/providers/ldap/sdap_sudo_cache.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/providers/ldap/sdap_sudo_cache.c b/src/providers/ldap/sdap_sudo_cache.c
index 27203c227064bdcd918cda67bb93a5d62b42e4bd..56e84ce8f26338ea5856eb5c76627641eee93df1 100644
--- a/src/providers/ldap/sdap_sudo_cache.c
+++ b/src/providers/ldap/sdap_sudo_cache.c
@@ -28,7 +28,6 @@
static errno_t sdap_sudo_get_usn(TALLOC_CTX *mem_ctx,
struct sysdb_attrs *attrs,
struct sdap_attr_map *map,
- const char *name,
char **_usn)
{
const char *usn;
@@ -86,7 +85,7 @@ sdap_save_native_sudorule(TALLOC_CTX *mem_ctx,
return ret;
}
- ret = sdap_sudo_get_usn(mem_ctx, attrs, map, rule_name, _usn);
+ ret = sdap_sudo_get_usn(mem_ctx, attrs, map, _usn);
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, "Could not read USN from %s\n", rule_name);
*_usn = NULL;
--
2.5.0

View File

@ -1,62 +0,0 @@
From d58ae3b51f2f87e7ff1024ae25cb996ce91cae55 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Sun, 11 Oct 2015 22:33:08 +0200
Subject: [PATCH 11/49] sudo: remove unused param. in ldap_get_sudo_options
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Remove unused talloc memory context.
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit 8835ecb2ff5126629993a6b6d3fb0bb7baa3b765)
---
src/providers/ldap/ldap_common.h | 3 +--
src/providers/ldap/ldap_options.c | 3 +--
src/providers/ldap/sdap_sudo.c | 2 +-
3 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index f552520a0503908f82b845f8e813cf67306ec954..ae45fb71b5cf7edab618a829057357bea2d6844b 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -167,8 +167,7 @@ int ldap_get_options(TALLOC_CTX *memctx,
const char *conf_path,
struct sdap_options **_opts);
-int ldap_get_sudo_options(TALLOC_CTX *memctx,
- struct confdb_ctx *cdb,
+int ldap_get_sudo_options(struct confdb_ctx *cdb,
const char *conf_path,
struct sdap_options *opts,
bool *use_host_filter,
diff --git a/src/providers/ldap/ldap_options.c b/src/providers/ldap/ldap_options.c
index 7ad6071508d0abbb33984c697b833cf12f9e4df9..cf49e41abbea78c1b1fd79e2e0713fba279971be 100644
--- a/src/providers/ldap/ldap_options.c
+++ b/src/providers/ldap/ldap_options.c
@@ -343,8 +343,7 @@ done:
return ret;
}
-int ldap_get_sudo_options(TALLOC_CTX *memctx,
- struct confdb_ctx *cdb,
+int ldap_get_sudo_options(struct confdb_ctx *cdb,
const char *conf_path,
struct sdap_options *opts,
bool *use_host_filter,
diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c
index 24642344491dfb93f039bde6a0bfe8fd3e24a80d..550784842c6e6162d153785940c1e37a51b5dc1f 100644
--- a/src/providers/ldap/sdap_sudo.c
+++ b/src/providers/ldap/sdap_sudo.c
@@ -76,7 +76,7 @@ int sdap_sudo_init(struct be_ctx *be_ctx,
* so we don't have current usn values available */
sudo_ctx->full_refresh_done = false;
- ret = ldap_get_sudo_options(id_ctx, be_ctx->cdb,
+ ret = ldap_get_sudo_options(be_ctx->cdb,
be_ctx->conf_path, id_ctx->opts,
&sudo_ctx->use_host_filter,
&sudo_ctx->include_regexp,
--
2.5.0

View File

@ -1,383 +0,0 @@
From a9845c875e430e00cfb49a39b09c8595ff8e3416 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 1 Dec 2015 13:08:36 +0100
Subject: [PATCH 12/49] SDAP: Add request that iterates over all search bases
We often need to iterate over many search bases but we always use
mostly copy&paste iterator. This will reduce code duplication and
simplify code flow.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit d0599eaa9369fd867953e3c58b8d7bb445525ff5)
---
Makefile.am | 2 +
src/providers/ldap/ldap_common.h | 9 +-
src/providers/ldap/sdap.c | 2 +-
src/providers/ldap/sdap_ops.c | 232 +++++++++++++++++++++++++++++++++++++++
src/providers/ldap/sdap_ops.h | 44 ++++++++
src/providers/ldap/sdap_utils.c | 6 +-
6 files changed, 288 insertions(+), 7 deletions(-)
create mode 100644 src/providers/ldap/sdap_ops.c
create mode 100644 src/providers/ldap/sdap_ops.h
diff --git a/Makefile.am b/Makefile.am
index 1937dcbebc4f29c4ffe72eeeb67cdb5344a8e7d1..095b1cfd62f49d266df278e1736d48ed5ef4fa7a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -628,6 +628,7 @@ dist_noinst_HEADERS = \
src/providers/ldap/sdap_users.h \
src/providers/ldap/sdap_dyndns.h \
src/providers/ldap/sdap_async_enum.h \
+ src/providers/ldap/sdap_ops.h \
src/providers/ipa/ipa_common.h \
src/providers/ipa/ipa_config.h \
src/providers/ipa/ipa_access.h \
@@ -2836,6 +2837,7 @@ libsss_ldap_common_la_SOURCES = \
src/providers/ldap/sdap_refresh.c \
src/providers/ldap/sdap_utils.c \
src/providers/ldap/sdap_domain.c \
+ src/providers/ldap/sdap_ops.c \
src/providers/ldap/sdap.c \
src/util/user_info_msg.c \
src/util/sss_ldap.c \
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index ae45fb71b5cf7edab618a829057357bea2d6844b..66434dd0e8bc82649fecd67b1394cb6b102a7d49 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -264,9 +264,12 @@ errno_t list_missing_attrs(TALLOC_CTX *mem_ctx,
bool sdap_is_secure_uri(const char *uri);
-char *sdap_get_id_specific_filter(TALLOC_CTX *mem_ctx,
- const char *base_filter,
- const char *extra_filter);
+char *sdap_combine_filters(TALLOC_CTX *mem_ctx,
+ const char *base_filter,
+ const char *extra_filter);
+
+#define sdap_get_id_specific_filter(mem_ctx, base_filter, extra_filter) \
+ sdap_combine_filters((mem_ctx), (base_filter), (extra_filter))
char *sdap_get_access_filter(TALLOC_CTX *mem_ctx,
const char *base_filter);
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index fcdc4028efe97bba13f265a8cfd7c75fa6b7a07c..f9b9ff7e6913c406547f36d341300b936e121693 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -312,7 +312,7 @@ int sdap_get_map(TALLOC_CTX *memctx,
char *name;
int i, ret;
- map = talloc_array(memctx, struct sdap_attr_map, num_entries);
+ map = talloc_zero_array(memctx, struct sdap_attr_map, num_entries + 1);
if (!map) {
return ENOMEM;
}
diff --git a/src/providers/ldap/sdap_ops.c b/src/providers/ldap/sdap_ops.c
new file mode 100644
index 0000000000000000000000000000000000000000..b2f2c35d0bf49682f522993390cfec2f451bf366
--- /dev/null
+++ b/src/providers/ldap/sdap_ops.c
@@ -0,0 +1,232 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2015 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 <talloc.h>
+#include <tevent.h>
+
+#include "util/util.h"
+#include "providers/ldap/sdap.h"
+#include "providers/ldap/sdap_async.h"
+#include "providers/ldap/ldap_common.h"
+
+struct sdap_search_bases_state {
+ struct tevent_context *ev;
+ struct sdap_options *opts;
+ struct sdap_handle *sh;
+ const char *filter;
+ const char **attrs;
+ struct sdap_attr_map *map;
+ int map_num_attrs;
+ int timeout;
+ bool allow_paging;
+
+ size_t base_iter;
+ struct sdap_search_base *cur_base;
+ struct sdap_search_base **bases;
+
+ size_t reply_count;
+ struct sysdb_attrs **reply;
+};
+
+static errno_t sdap_search_bases_next_base(struct tevent_req *req);
+static void sdap_search_bases_done(struct tevent_req *subreq);
+
+struct tevent_req *sdap_search_bases_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sdap_options *opts,
+ struct sdap_handle *sh,
+ struct sdap_search_base **bases,
+ struct sdap_attr_map *map,
+ bool allow_paging,
+ int timeout,
+ const char *filter,
+ const char **attrs)
+{
+ struct tevent_req *req;
+ struct sdap_search_bases_state *state;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state, struct sdap_search_bases_state);
+ if (req == NULL) {
+ return NULL;
+ }
+
+ if (bases == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "No search base specified!\n");
+ ret = ERR_INTERNAL;
+ goto immediately;
+ }
+
+ if (map == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "No attribute map specified!\n");
+ ret = ERR_INTERNAL;
+ goto immediately;
+ }
+
+ state->ev = ev;
+ state->opts = opts;
+ state->sh = sh;
+ state->bases = bases;
+ state->map = map;
+ state->filter = filter;
+ state->attrs = attrs;
+ state->allow_paging = allow_paging;
+
+ state->timeout = timeout == 0
+ ? dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT)
+ : timeout;
+
+ for (state->map_num_attrs = 0;
+ state->map[state->map_num_attrs].opt_name != NULL;
+ state->map_num_attrs++) {
+ /* no op */;
+ }
+
+ if (state->attrs == NULL) {
+ ret = build_attrs_from_map(state, state->map, state->map_num_attrs,
+ NULL, &state->attrs, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to build attrs from map "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto immediately;
+ }
+ }
+
+ state->base_iter = 0;
+ ret = sdap_search_bases_next_base(req);
+ if (ret == EAGAIN) {
+ /* asynchronous processing */
+ return req;
+ }
+
+immediately:
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
+ tevent_req_post(req, ev);
+
+ return req;
+}
+
+static errno_t sdap_search_bases_next_base(struct tevent_req *req)
+{
+ struct sdap_search_bases_state *state;
+ struct tevent_req *subreq;
+ char *filter;
+
+ state = tevent_req_data(req, struct sdap_search_bases_state);
+ state->cur_base = state->bases[state->base_iter];
+ if (state->cur_base == NULL) {
+ return EOK;
+ }
+
+ /* Combine lookup and search base filters. */
+ filter = sdap_combine_filters(state, state->filter,
+ state->cur_base->filter);
+ if (filter == NULL) {
+ return ENOMEM;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, "Issuing LDAP lookup with base [%s]\n",
+ state->cur_base->basedn);
+
+ subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
+ state->cur_base->basedn,
+ state->cur_base->scope, filter,
+ state->attrs, state->map,
+ state->map_num_attrs, state->timeout,
+ state->allow_paging);
+ if (subreq == NULL) {
+ return ENOMEM;
+ }
+
+ tevent_req_set_callback(subreq, sdap_search_bases_done, req);
+
+ state->base_iter++;
+ return EAGAIN;
+}
+
+static void sdap_search_bases_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req;
+ struct sdap_search_bases_state *state;
+ struct sysdb_attrs **attrs;
+ size_t count;
+ size_t i;
+ int ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct sdap_search_bases_state);
+
+ DEBUG(SSSDBG_TRACE_FUNC, "Receiving data from base [%s]\n",
+ state->cur_base->basedn);
+
+ ret = sdap_get_generic_recv(subreq, state, &count, &attrs);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ /* Add rules to result. */
+ if (count > 0) {
+ state->reply = talloc_realloc(state, state->reply, struct sysdb_attrs *,
+ state->reply_count + count);
+ if (state->reply == NULL) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+
+ for (i = 0; i < count; i++) {
+ state->reply[state->reply_count + i] = talloc_steal(state->reply,
+ attrs[i]);
+ }
+
+ state->reply_count += count;
+ }
+
+ /* Try next search base. */
+ ret = sdap_search_bases_next_base(req);
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else if (ret != EAGAIN) {
+ tevent_req_error(req, ret);
+ }
+
+ return;
+}
+
+int sdap_search_bases_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ size_t *reply_count,
+ struct sysdb_attrs ***reply)
+{
+ struct sdap_search_bases_state *state =
+ tevent_req_data(req, struct sdap_search_bases_state);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ *reply_count = state->reply_count;
+ *reply = talloc_steal(mem_ctx, state->reply);
+
+ return EOK;
+}
diff --git a/src/providers/ldap/sdap_ops.h b/src/providers/ldap/sdap_ops.h
new file mode 100644
index 0000000000000000000000000000000000000000..bc53ff8701c26ca00d5c07b441b170d615bda2ee
--- /dev/null
+++ b/src/providers/ldap/sdap_ops.h
@@ -0,0 +1,44 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2015 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/>.
+*/
+
+#ifndef _SDAP_OPS_H_
+#define _SDAP_OPS_H_
+
+#include <talloc.h>
+#include <tevent.h>
+#include "providers/ldap/ldap_common.h"
+
+struct tevent_req *sdap_search_bases_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sdap_options *opts,
+ struct sdap_handle *sh,
+ struct sdap_search_base **bases,
+ struct sdap_attr_map *map,
+ bool allow_paging,
+ int timeout,
+ const char *filter,
+ const char **attrs);
+
+int sdap_search_bases_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ size_t *reply_count,
+ struct sysdb_attrs ***reply);
+
+#endif /* _SDAP_OPS_H_ */
diff --git a/src/providers/ldap/sdap_utils.c b/src/providers/ldap/sdap_utils.c
index 9da46ea70bf80e7f4d12fdfc7d1c97e99de8d000..7a96f81a1db2644b698e5a5baaed19366a305c6b 100644
--- a/src/providers/ldap/sdap_utils.c
+++ b/src/providers/ldap/sdap_utils.c
@@ -149,9 +149,9 @@ errno_t deref_string_to_val(const char *str, int *val)
return EOK;
}
-char *sdap_get_id_specific_filter(TALLOC_CTX *mem_ctx,
- const char *base_filter,
- const char *extra_filter)
+char *sdap_combine_filters(TALLOC_CTX *mem_ctx,
+ const char *base_filter,
+ const char *extra_filter)
{
char *filter = NULL;
--
2.5.0

View File

@ -1,369 +0,0 @@
From ca05bdf79d3ef60b0747db10b0ba0be48163841d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 1 Dec 2015 15:27:41 +0100
Subject: [PATCH 13/49] SDAP: rename sdap_get_id_specific_filter
More generic name is used now since it is not used only for id
filters. Probably all references will be deleted when the code
uses sdap_search_in_bases istead of custom search base iterators.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 92ec40e6aa25f75903ffdb166a8ec56b67bfd77d)
---
src/providers/ipa/ipa_hbac_rules.c | 5 ++---
src/providers/ipa/ipa_hbac_services.c | 10 ++++------
src/providers/ipa/ipa_hosts.c | 8 ++++----
src/providers/ipa/ipa_netgroups.c | 2 +-
src/providers/ipa/ipa_selinux_maps.c | 4 ++--
src/providers/ipa/ipa_subdomains.c | 4 ++--
src/providers/ldap/ldap_common.h | 3 ---
src/providers/ldap/sdap_async_autofs.c | 6 ++----
src/providers/ldap/sdap_async_groups.c | 3 +--
src/providers/ldap/sdap_async_groups_ad.c | 3 +--
src/providers/ldap/sdap_async_initgroups.c | 22 ++++++++--------------
src/providers/ldap/sdap_async_initgroups_ad.c | 3 +--
src/providers/ldap/sdap_async_nested_groups.c | 6 ++----
src/providers/ldap/sdap_async_netgroups.c | 3 +--
src/providers/ldap/sdap_async_services.c | 3 +--
src/providers/ldap/sdap_async_sudo.c | 4 ++--
src/providers/ldap/sdap_async_users.c | 3 +--
17 files changed, 35 insertions(+), 57 deletions(-)
diff --git a/src/providers/ipa/ipa_hbac_rules.c b/src/providers/ipa/ipa_hbac_rules.c
index ffef6dc4ce4229f2063d1b00308892bd3765f398..1a812a383d49386ad9e02b2a84f759f399b20c75 100644
--- a/src/providers/ipa/ipa_hbac_rules.c
+++ b/src/providers/ipa/ipa_hbac_rules.c
@@ -206,9 +206,8 @@ ipa_hbac_rule_info_next(struct tevent_req *req,
}
talloc_zfree(state->cur_filter);
- state->cur_filter = sdap_get_id_specific_filter(state,
- state->rules_filter,
- base->filter);
+ state->cur_filter = sdap_combine_filters(state, state->rules_filter,
+ base->filter);
if (state->cur_filter == NULL) {
return ENOMEM;
}
diff --git a/src/providers/ipa/ipa_hbac_services.c b/src/providers/ipa/ipa_hbac_services.c
index 35ee003effb5ac933843cbc3bd662f81a58246ad..cf8ce84bf54f2d22bd5cd19d88e647889742a41e 100644
--- a/src/providers/ipa/ipa_hbac_services.c
+++ b/src/providers/ipa/ipa_hbac_services.c
@@ -137,9 +137,8 @@ static errno_t ipa_hbac_service_info_next(struct tevent_req *req,
}
talloc_zfree(state->cur_filter);
- state->cur_filter = sdap_get_id_specific_filter(state,
- state->service_filter,
- base->filter);
+ state->cur_filter = sdap_combine_filters(state, state->service_filter,
+ base->filter);
if (state->cur_filter == NULL) {
return ENOMEM;
}
@@ -251,9 +250,8 @@ ipa_hbac_servicegroup_info_next(struct tevent_req *req,
}
talloc_zfree(state->cur_filter);
- state->cur_filter = sdap_get_id_specific_filter(state,
- state->service_filter,
- base->filter);
+ state->cur_filter = sdap_combine_filters(state, state->service_filter,
+ base->filter);
if (state->cur_filter == NULL) {
return ENOMEM;
}
diff --git a/src/providers/ipa/ipa_hosts.c b/src/providers/ipa/ipa_hosts.c
index 64f80f082cdda57949e1b01efe46d6f76faa1734..5966e3c74778433fbfc04c053547dc5e358f710a 100644
--- a/src/providers/ipa/ipa_hosts.c
+++ b/src/providers/ipa/ipa_hosts.c
@@ -154,8 +154,8 @@ static errno_t ipa_host_info_next(struct tevent_req *req,
}
talloc_zfree(state->cur_filter);
- state->cur_filter = sdap_get_id_specific_filter(state, state->host_filter,
- base->filter);
+ state->cur_filter = sdap_combine_filters(state, state->host_filter,
+ base->filter);
if (state->cur_filter == NULL) {
return ENOMEM;
}
@@ -292,8 +292,8 @@ static errno_t ipa_hostgroup_info_next(struct tevent_req *req,
}
talloc_zfree(state->cur_filter);
- state->cur_filter = sdap_get_id_specific_filter(state, state->host_filter,
- base->filter);
+ state->cur_filter = sdap_combine_filters(state, state->host_filter,
+ base->filter);
if (state->cur_filter == NULL) {
return ENOMEM;
}
diff --git a/src/providers/ipa/ipa_netgroups.c b/src/providers/ipa/ipa_netgroups.c
index 6f004e034a77de1049c2e127e82ce49d3e7400f3..a19e5e03d7025cbd9eed12261f586a4eae22b4a3 100644
--- a/src/providers/ipa/ipa_netgroups.c
+++ b/src/providers/ipa/ipa_netgroups.c
@@ -254,7 +254,7 @@ static errno_t ipa_netgr_next_base(struct tevent_req *req)
netgr_bases = state->ipa_opts->id->sdom->netgroup_search_bases;
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(
+ state->filter = sdap_combine_filters(
state,
state->base_filter,
netgr_bases[state->netgr_base_iter]->filter);
diff --git a/src/providers/ipa/ipa_selinux_maps.c b/src/providers/ipa/ipa_selinux_maps.c
index 315cc7de40d8262619c86bb897bb16da45ea66c2..9abac4d00a3d1ebf599a0c47c2e8c7f374e20a58 100644
--- a/src/providers/ipa/ipa_selinux_maps.c
+++ b/src/providers/ipa/ipa_selinux_maps.c
@@ -121,8 +121,8 @@ ipa_selinux_get_maps_next(struct tevent_req *req,
}
talloc_zfree(state->cur_filter);
- state->cur_filter = sdap_get_id_specific_filter(state, state->maps_filter,
- base->filter);
+ state->cur_filter = sdap_combine_filters(state, state->maps_filter,
+ base->filter);
if (state->cur_filter == NULL) {
return ENOMEM;
}
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index 70a2933757688d0cc758a56d20649bf5e7f43436..cd78506ffc59c392da4e834c764c9ca82dbc89b0 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -726,8 +726,8 @@ ipa_subdomains_handler_get(struct ipa_subdomains_req_ctx *ctx,
}
talloc_free(ctx->current_filter);
- ctx->current_filter = sdap_get_id_specific_filter(ctx, params->filter,
- base->filter);
+ ctx->current_filter = sdap_combine_filters(ctx, params->filter,
+ base->filter);
if (ctx->current_filter == NULL) {
return ENOMEM;
}
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 66434dd0e8bc82649fecd67b1394cb6b102a7d49..e5fee51e742a69d8876f2829f75b2af5f020ef6f 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -268,9 +268,6 @@ char *sdap_combine_filters(TALLOC_CTX *mem_ctx,
const char *base_filter,
const char *extra_filter);
-#define sdap_get_id_specific_filter(mem_ctx, base_filter, extra_filter) \
- sdap_combine_filters((mem_ctx), (base_filter), (extra_filter))
-
char *sdap_get_access_filter(TALLOC_CTX *mem_ctx,
const char *base_filter);
diff --git a/src/providers/ldap/sdap_async_autofs.c b/src/providers/ldap/sdap_async_autofs.c
index 1db8d2067a691ac93844d97dd2d53422b1ca3ad2..85cc8928139196ba25caef2e3fc46b004c85f073 100644
--- a/src/providers/ldap/sdap_async_autofs.c
+++ b/src/providers/ldap/sdap_async_autofs.c
@@ -313,8 +313,7 @@ automntmaps_process_members_next_base(struct tevent_req *req)
tevent_req_data(req, struct automntmaps_process_members_state);
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(state,
- state->base_filter,
+ state->filter = sdap_combine_filters(state, state->base_filter,
state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
@@ -493,8 +492,7 @@ sdap_get_automntmap_next_base(struct tevent_req *req)
state = tevent_req_data(req, struct sdap_get_automntmap_state);
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(state,
- state->base_filter,
+ state->filter = sdap_combine_filters(state, state->base_filter,
state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 24c9f4d39fecfa9806e4dbe23c2395d201bbf9a0..31e0b86a94f1c3969c8fcafe463c591423a835f0 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -1891,8 +1891,7 @@ static errno_t sdap_get_groups_next_base(struct tevent_req *req)
state = tevent_req_data(req, struct sdap_get_groups_state);
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(state,
- state->base_filter,
+ state->filter = sdap_combine_filters(state, state->base_filter,
state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
diff --git a/src/providers/ldap/sdap_async_groups_ad.c b/src/providers/ldap/sdap_async_groups_ad.c
index 8db587c96d569fc691486b252ff8f2c7d96e29c2..3f842b26dacd5a58b8254125287b98633cf29ae8 100644
--- a/src/providers/ldap/sdap_async_groups_ad.c
+++ b/src/providers/ldap/sdap_async_groups_ad.c
@@ -141,8 +141,7 @@ sdap_get_ad_match_rule_members_next_base(struct tevent_req *req)
state = tevent_req_data(req, struct sdap_ad_match_rule_state);
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(state,
- state->base_filter,
+ state->filter = sdap_combine_filters(state, state->base_filter,
state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index f451c4630cd5a8a7edb9f38c1e090a9a833c9cb5..1e5f5ab49896b234bec0c7a2c1429f30d90ae32a 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -493,9 +493,8 @@ static errno_t sdap_initgr_rfc2307_next_base(struct tevent_req *req)
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(
- state, state->base_filter,
- state->search_bases[state->base_iter]->filter);
+ state->filter = sdap_combine_filters( state, state->base_filter,
+ state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
}
@@ -1667,10 +1666,8 @@ static errno_t sdap_initgr_rfc2307bis_next_base(struct tevent_req *req)
state = tevent_req_data(req, struct sdap_initgr_rfc2307bis_state);
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(
- state,
- state->base_filter,
- state->search_bases[state->base_iter]->filter);
+ state->filter = sdap_combine_filters(state, state->base_filter,
+ state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
}
@@ -2430,9 +2427,8 @@ static errno_t rfc2307bis_nested_groups_next_base(struct tevent_req *req)
state = tevent_req_data(req, struct sdap_rfc2307bis_nested_ctx);
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(
- state, state->base_filter,
- state->search_bases[state->base_iter]->filter);
+ state->filter = sdap_combine_filters(state, state->base_filter,
+ state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
}
@@ -2798,10 +2794,8 @@ static errno_t sdap_get_initgr_next_base(struct tevent_req *req)
state = tevent_req_data(req, struct sdap_get_initgr_state);
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(
- state,
- state->user_base_filter,
- state->user_search_bases[state->user_base_iter]->filter);
+ state->filter = sdap_combine_filters(state, state->user_base_filter,
+ state->user_search_bases[state->user_base_iter]->filter);
if (!state->filter) {
return ENOMEM;
}
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index e210db978c6b1cc9beea99f25cc58bec2670f66d..76b14a55b2619b22928e13f5513a7ef33cafbe5f 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -170,8 +170,7 @@ sdap_get_ad_match_rule_initgroups_next_base(struct tevent_req *req)
state = tevent_req_data(req, struct sdap_ad_match_rule_initgr_state);
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(state,
- state->base_filter,
+ state->filter = sdap_combine_filters(state, state->base_filter,
state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c
index 08e199869ad16c3b19d998a2a28eae9a0dd0a371..af25430eacd4de7ea2e2872b0d9e34c8515c22db 100644
--- a/src/providers/ldap/sdap_async_nested_groups.c
+++ b/src/providers/ldap/sdap_async_nested_groups.c
@@ -1589,8 +1589,7 @@ sdap_nested_group_lookup_user_send(TALLOC_CTX *mem_ctx,
}
/* use search base filter if needed */
- filter = sdap_get_id_specific_filter(state, base_filter,
- member->user_filter);
+ filter = sdap_combine_filters(state, base_filter, member->user_filter);
if (filter == NULL) {
ret = ENOMEM;
goto immediately;
@@ -1733,8 +1732,7 @@ sdap_nested_group_lookup_group_send(TALLOC_CTX *mem_ctx,
}
/* use search base filter if needed */
- filter = sdap_get_id_specific_filter(state, base_filter,
- member->group_filter);
+ filter = sdap_combine_filters(state, base_filter, member->group_filter);
if (filter == NULL) {
ret = ENOMEM;
goto immediately;
diff --git a/src/providers/ldap/sdap_async_netgroups.c b/src/providers/ldap/sdap_async_netgroups.c
index e50f2508707fbd43374d5afef7360274afb18fa6..ae8e56b3cd5ed127c0293c1d6702de952cc646a7 100644
--- a/src/providers/ldap/sdap_async_netgroups.c
+++ b/src/providers/ldap/sdap_async_netgroups.c
@@ -624,8 +624,7 @@ static errno_t sdap_get_netgroups_next_base(struct tevent_req *req)
state = tevent_req_data(req, struct sdap_get_netgroups_state);
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(state,
- state->base_filter,
+ state->filter = sdap_combine_filters(state, state->base_filter,
state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
diff --git a/src/providers/ldap/sdap_async_services.c b/src/providers/ldap/sdap_async_services.c
index 54f3ffb7440df8808f2dfb4806314b9c795f7acc..72758f2469561bc14d2ae21507e96857bbe48737 100644
--- a/src/providers/ldap/sdap_async_services.c
+++ b/src/providers/ldap/sdap_async_services.c
@@ -129,8 +129,7 @@ sdap_get_services_next_base(struct tevent_req *req)
state = tevent_req_data(req, struct sdap_get_services_state);
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(state,
- state->base_filter,
+ state->filter = sdap_combine_filters(state, state->base_filter,
state->search_bases[state->base_iter]->filter);
if (!state->filter) {
return ENOMEM;
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index fd9aecba98838ba01453cc4eed827c9e5a2fa9e2..421b5712a80de990be83729e9c40c06c175a77fc 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -125,7 +125,7 @@ static errno_t sdap_sudo_load_sudoers_next_base(struct tevent_req *req)
}
/* Combine lookup and search base filters. */
- filter = sdap_get_id_specific_filter(state, state->filter, base->filter);
+ filter = sdap_combine_filters(state, state->filter, base->filter);
if (filter == NULL) {
return ENOMEM;
}
@@ -467,7 +467,7 @@ static char *sdap_sudo_get_filter(TALLOC_CTX *mem_ctx,
goto done;
}
- filter = sdap_get_id_specific_filter(tmp_ctx, rule_filter, host_filter);
+ filter = sdap_combine_filters(tmp_ctx, rule_filter, host_filter);
if (filter == NULL) {
goto done;
}
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
index 865439cadeb4f9f9452b1549663691c29e52f27b..25dd40dfff08d08f25856bd1f00dfd3bb5eeb3d5 100644
--- a/src/providers/ldap/sdap_async_users.c
+++ b/src/providers/ldap/sdap_async_users.c
@@ -682,8 +682,7 @@ static errno_t sdap_search_user_next_base(struct tevent_req *req)
state = tevent_req_data(req, struct sdap_search_user_state);
talloc_zfree(state->filter);
- state->filter = sdap_get_id_specific_filter(state,
- state->base_filter,
+ state->filter = sdap_combine_filters(state, state->base_filter,
state->search_bases[state->base_iter]->filter);
if (state->filter == NULL) {
return ENOMEM;
--
2.5.0

View File

@ -1,37 +0,0 @@
From d3a3e06085cd25ce09f122ff04917d09743752a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 18 Dec 2015 14:23:56 +0100
Subject: [PATCH 14/49] SDAP: support empty filters in sdap_combine_filters()
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 1d3f5fc2802c218916e6d6bc98eeaed79c66bafe)
---
src/providers/ldap/sdap_utils.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/providers/ldap/sdap_utils.c b/src/providers/ldap/sdap_utils.c
index 7a96f81a1db2644b698e5a5baaed19366a305c6b..47921b8768b9c4c4b2d40a5eb28e28bf48238210 100644
--- a/src/providers/ldap/sdap_utils.c
+++ b/src/providers/ldap/sdap_utils.c
@@ -155,8 +155,10 @@ char *sdap_combine_filters(TALLOC_CTX *mem_ctx,
{
char *filter = NULL;
- if (!extra_filter) {
+ if (extra_filter == NULL || extra_filter[0] == '\0') {
return talloc_strdup(mem_ctx, base_filter);
+ } else if (base_filter == NULL || base_filter[0] == '\0') {
+ return talloc_strdup(mem_ctx, extra_filter);
}
if (extra_filter[0] == '(') {
@@ -166,5 +168,6 @@ char *sdap_combine_filters(TALLOC_CTX *mem_ctx,
filter = talloc_asprintf(mem_ctx, "(&%s(%s))",
base_filter, extra_filter);
}
+
return filter; /* NULL or not */
}
--
2.5.0

View File

@ -1,216 +0,0 @@
From 1acd58fd1a2bb992ea3f4546433eb3ea69772801 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 16 Dec 2015 13:49:02 +0100
Subject: [PATCH 15/49] SUDO: use sdap_search_bases instead custom sb iterator
Removes code duplication.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit e9ae5cd285dcc8fa232e16f9c7a29f18537272f2)
---
src/providers/ldap/sdap_async_sudo.c | 133 +++++++----------------------------
1 file changed, 26 insertions(+), 107 deletions(-)
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index 421b5712a80de990be83729e9c40c06c175a77fc..d7780d38405a2705e25a9c983aca2736548a624e 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -29,27 +29,16 @@
#include "providers/dp_backend.h"
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap.h"
-#include "providers/ldap/sdap_async.h"
+#include "providers/ldap/sdap_ops.h"
#include "providers/ldap/sdap_sudo.h"
#include "providers/ldap/sdap_sudo_cache.h"
#include "db/sysdb_sudo.h"
struct sdap_sudo_load_sudoers_state {
- struct tevent_context *ev;
- struct sdap_options *opts;
- struct sdap_handle *sh;
-
- int timeout;
- const char **attrs;
- const char *filter;
- size_t base_iter;
- struct sdap_search_base **search_bases;
-
struct sysdb_attrs **rules;
size_t num_rules;
};
-static errno_t sdap_sudo_load_sudoers_next_base(struct tevent_req *req);
static void sdap_sudo_load_sudoers_done(struct tevent_req *subreq);
static struct tevent_req *
@@ -60,7 +49,9 @@ sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
const char *ldap_filter)
{
struct tevent_req *req;
+ struct tevent_req *subreq;
struct sdap_sudo_load_sudoers_state *state;
+ struct sdap_search_base **sb;
int ret;
req = tevent_req_create(mem_ctx, &state,
@@ -69,133 +60,61 @@ sdap_sudo_load_sudoers_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- state->ev = ev;
- state->opts = opts;
- state->sh = sh;
- state->base_iter = 0;
- state->search_bases = opts->sdom->sudo_search_bases;
- state->filter = ldap_filter;
- state->timeout = dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT);
state->rules = NULL;
state->num_rules = 0;
- if (state->search_bases == NULL) {
+ sb = opts->sdom->sudo_search_bases;
+ if (sb == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
"SUDOERS lookup request without a search base\n");
ret = EINVAL;
goto immediately;
}
- /* create attrs from map */
- ret = build_attrs_from_map(state, opts->sudorule_map, SDAP_OPTS_SUDO,
- NULL, &state->attrs, NULL);
- if (ret != EOK) {
- goto immediately;
- }
+ DEBUG(SSSDBG_TRACE_FUNC, "About to fetch sudo rules\n");
- /* begin search */
- ret = sdap_sudo_load_sudoers_next_base(req);
- if (ret == EAGAIN) {
- /* asynchronous processing */
- return req;
- }
-
-immediately:
- if (ret == EOK) {
- tevent_req_done(req);
- } else {
- tevent_req_error(req, ret);
- }
- tevent_req_post(req, ev);
-
- return req;
-}
-
-static errno_t sdap_sudo_load_sudoers_next_base(struct tevent_req *req)
-{
- struct sdap_sudo_load_sudoers_state *state;
- struct sdap_search_base *base;
- struct tevent_req *subreq;
- char *filter;
-
- state = tevent_req_data(req, struct sdap_sudo_load_sudoers_state);
- base = state->search_bases[state->base_iter];
- if (base == NULL) {
- return EOK;
- }
-
- /* Combine lookup and search base filters. */
- filter = sdap_combine_filters(state, state->filter, base->filter);
- if (filter == NULL) {
- return ENOMEM;
- }
-
- DEBUG(SSSDBG_TRACE_FUNC, "Searching for sudo rules with base [%s]\n",
- base->basedn);
-
- subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
- base->basedn, base->scope, filter,
- state->attrs, state->opts->sudorule_map,
- SDAP_OPTS_SUDO, state->timeout, true);
+ subreq = sdap_search_bases_send(state, ev, opts, sh, sb,
+ opts->sudorule_map, true, 0,
+ ldap_filter, NULL);
if (subreq == NULL) {
- return ENOMEM;
+ ret = ENOMEM;
+ goto immediately;
}
tevent_req_set_callback(subreq, sdap_sudo_load_sudoers_done, req);
- state->base_iter++;
- return EAGAIN;
+ ret = EOK;
+
+immediately:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ tevent_req_post(req, ev);
+ }
+
+ return req;
}
static void sdap_sudo_load_sudoers_done(struct tevent_req *subreq)
{
struct tevent_req *req;
struct sdap_sudo_load_sudoers_state *state;
- struct sdap_search_base *search_base;
- struct sysdb_attrs **attrs = NULL;
- size_t count;
- int ret;
- size_t i;
+ errno_t ret;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_sudo_load_sudoers_state);
- search_base = state->search_bases[state->base_iter - 1];
- DEBUG(SSSDBG_TRACE_FUNC, "Receiving sudo rules with base [%s]\n",
- search_base->basedn);
-
- ret = sdap_get_generic_recv(subreq, state, &count, &attrs);
+ ret = sdap_search_bases_recv(subreq, state, &state->num_rules,
+ &state->rules);
talloc_zfree(subreq);
if (ret != EOK) {
tevent_req_error(req, ret);
return;
}
- /* Add rules to result. */
- if (count > 0) {
- state->rules = talloc_realloc(state, state->rules,
- struct sysdb_attrs *,
- state->num_rules + count);
- if (state->rules == NULL) {
- tevent_req_error(req, ENOMEM);
- return;
- }
+ DEBUG(SSSDBG_IMPORTANT_INFO, "Received %zu sudo rules\n",
+ state->num_rules);
- for (i = 0; i < count; i++) {
- state->rules[state->num_rules + i] = talloc_steal(state->rules,
- attrs[i]);
- }
-
- state->num_rules += count;
- }
-
- /* Try next search base. */
- ret = sdap_sudo_load_sudoers_next_base(req);
- if (ret == EOK) {
- tevent_req_done(req);
- } else if (ret != EAGAIN) {
- tevent_req_error(req, ret);
- }
+ tevent_req_done(req);
return;
}
--
2.5.0

View File

@ -1,988 +0,0 @@
From 154d886c35318cabfb174e6791d3361ce760cdcd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 16 Dec 2015 14:42:04 +0100
Subject: [PATCH 16/49] SUDO: make sudo sysdb interface more reusable
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 68abbe716bed7c8d6790d9bec168ef44469306a1)
---
Makefile.am | 2 -
src/db/sysdb.c | 98 ++++++++++++
src/db/sysdb.h | 7 +
src/db/sysdb_sudo.c | 286 +++++++++++++++++++++++++++--------
src/db/sysdb_sudo.h | 17 +--
src/providers/ldap/sdap_async_sudo.c | 121 ++-------------
src/providers/ldap/sdap_sudo.c | 1 -
src/providers/ldap/sdap_sudo_cache.c | 183 ----------------------
src/providers/ldap/sdap_sudo_cache.h | 37 -----
9 files changed, 354 insertions(+), 398 deletions(-)
delete mode 100644 src/providers/ldap/sdap_sudo_cache.c
delete mode 100644 src/providers/ldap/sdap_sudo_cache.h
diff --git a/Makefile.am b/Makefile.am
index 095b1cfd62f49d266df278e1736d48ed5ef4fa7a..29dd73edf3e6770e4280945f69c9d266f3d8c4c4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -618,7 +618,6 @@ dist_noinst_HEADERS = \
src/providers/ldap/sdap_access.h \
src/providers/ldap/sdap_async.h \
src/providers/ldap/sdap_async_private.h \
- src/providers/ldap/sdap_sudo_cache.h \
src/providers/ldap/sdap_sudo.h \
src/providers/ldap/sdap_autofs.h \
src/providers/ldap/sdap_id_op.h \
@@ -2859,7 +2858,6 @@ libsss_ldap_common_la_LDFLAGS = \
if BUILD_SUDO
libsss_ldap_common_la_SOURCES += \
- src/providers/ldap/sdap_sudo_cache.c \
src/providers/ldap/sdap_async_sudo.c \
src/providers/ldap/sdap_async_sudo_hostinfo.c \
src/providers/ldap/sdap_sudo_refresh.c \
diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index a71364d7c4b600eafd10fafa6641eac7b2292764..d4366a3c76f114bf113567754a1e0417afe664e3 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -2013,3 +2013,101 @@ errno_t sysdb_msg2attrs(TALLOC_CTX *mem_ctx, size_t count,
return EOK;
}
+
+int sysdb_compare_usn(const char *a, const char *b)
+{
+ size_t len_a;
+ size_t len_b;
+
+ if (a == NULL) {
+ return -1;
+ }
+
+ if (b == NULL) {
+ return 1;
+ }
+
+ len_a = strlen(a);
+ len_b = strlen(b);
+
+ /* trim leading zeros */
+ while (len_a > 0 && *a == '0') {
+ a++;
+ len_a--;
+ }
+
+ while (len_b > 0 && *b == '0') {
+ b++;
+ len_b--;
+ }
+
+ /* less digits means lower number */
+ if (len_a < len_b) {
+ return -1;
+ }
+
+ /* more digits means bigger number */
+ if (len_a > len_b) {
+ return 1;
+ }
+
+ /* now we can compare digits since alphabetical order is the same
+ * as numeric order */
+ return strcmp(a, b);
+}
+
+errno_t sysdb_get_highest_usn(TALLOC_CTX *mem_ctx,
+ struct sysdb_attrs **attrs,
+ size_t num_attrs,
+ char **_usn)
+{
+ const char *highest = NULL;
+ const char *current = NULL;
+ char *usn;
+ errno_t ret;
+ size_t i;
+
+ if (num_attrs == 0 || attrs == NULL) {
+ goto done;
+ }
+
+ for (i = 0; i < num_attrs; i++) {
+ ret = sysdb_attrs_get_string(attrs[i], SYSDB_USN, &current);
+ if (ret == ENOENT) {
+ /* USN value is not present, assuming zero. */
+ current = "0";
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Failed to retrieve USN value "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+
+ return ret;
+ }
+
+ if (current == NULL) {
+ continue;
+ }
+
+ if (highest == NULL) {
+ highest = current;
+ continue;
+ }
+
+ if (sysdb_compare_usn(current, highest) > 0 ) {
+ highest = current;
+ }
+ }
+
+done:
+ if (highest == NULL) {
+ usn = talloc_strdup(mem_ctx, "0");
+ } else {
+ usn = talloc_strdup(mem_ctx, highest);
+ }
+
+ if (usn == NULL) {
+ return ENOMEM;
+ }
+
+ *_usn = usn;
+ return EOK;
+}
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index ad1bf75b7437730af4a56d97e8f9868073e678aa..2e797fd7fa39163c2ab6a10e51228e0f1af3f9e3 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -386,6 +386,13 @@ errno_t sysdb_msg2attrs(TALLOC_CTX *mem_ctx, size_t count,
struct ldb_message **msgs,
struct sysdb_attrs ***attrs);
+int sysdb_compare_usn(const char *a, const char *b);
+
+errno_t sysdb_get_highest_usn(TALLOC_CTX *mem_ctx,
+ struct sysdb_attrs **attrs,
+ size_t num_attrs,
+ char **_usn);
+
/* convert an ldb error into an errno error */
int sysdb_error_to_errno(int ldberr);
diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c
index 784ac8af3ae5cb08f30eb9631c7ffa4aa92bde23..76116abacb20219f0c1dcdde755e8268e10fd293 100644
--- a/src/db/sysdb_sudo.c
+++ b/src/db/sysdb_sudo.c
@@ -27,6 +27,8 @@
#include "db/sysdb_private.h"
#include "db/sysdb_sudo.h"
+#define SUDO_ALL_FILTER "(" SYSDB_OBJECTCLASS "=" SYSDB_SUDO_CACHE_OC ")"
+
#define NULL_CHECK(val, rval, label) do { \
if (!val) { \
rval = ENOMEM; \
@@ -427,41 +429,6 @@ done:
return ret;
}
-errno_t
-sysdb_save_sudorule(struct sss_domain_info *domain,
- const char *rule_name,
- struct sysdb_attrs *attrs)
-{
- errno_t ret;
-
- DEBUG(SSSDBG_TRACE_FUNC, "Adding sudo rule %s\n", rule_name);
-
- ret = sysdb_attrs_add_string(attrs, SYSDB_OBJECTCLASS,
- SYSDB_SUDO_CACHE_OC);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Could not set rule object class [%d]: %s\n",
- ret, strerror(ret));
- return ret;
- }
-
- ret = sysdb_attrs_add_string(attrs, SYSDB_NAME, rule_name);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Could not set name attribute [%d]: %s\n",
- ret, strerror(ret));
- return ret;
- }
-
- ret = sysdb_store_custom(domain, rule_name,
- SUDORULE_SUBDIR, attrs);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_store_custom failed [%d]: %s\n",
- ret, strerror(ret));
- return ret;
- }
-
- return EOK;
-}
-
static errno_t sysdb_sudo_set_refresh_time(struct sss_domain_info *domain,
const char *attr_name,
time_t value)
@@ -615,6 +582,26 @@ errno_t sysdb_sudo_get_last_full_refresh(struct sss_domain_info *domain,
/* ==================== Purge functions ==================== */
+static const char *
+sysdb_sudo_get_rule_name(struct sysdb_attrs *rule)
+{
+ const char *name;
+ errno_t ret;
+
+ ret = sysdb_attrs_get_string(rule, SYSDB_SUDO_CACHE_AT_CN, &name);
+ if (ret == ERANGE) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Warning: found rule that contains none "
+ "or multiple CN values. It will be skipped.\n");
+ return NULL;
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to obtain rule name [%d]: %s\n",
+ ret, strerror(ret));
+ return NULL;
+ }
+
+ return name;
+}
+
static errno_t sysdb_sudo_purge_all(struct sss_domain_info *domain)
{
struct ldb_dn *base_dn = NULL;
@@ -627,6 +614,8 @@ static errno_t sysdb_sudo_purge_all(struct sss_domain_info *domain)
base_dn = sysdb_custom_subtree_dn(tmp_ctx, domain, SUDORULE_SUBDIR);
NULL_CHECK(base_dn, ret, done);
+ DEBUG(SSSDBG_TRACE_FUNC, "Deleting all cached sudo rules\n");
+
ret = sysdb_delete_recursive(domain->sysdb, base_dn, true);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, "sysdb_delete_recursive failed.\n");
@@ -639,42 +628,74 @@ done:
return ret;
}
-errno_t sysdb_sudo_purge_byname(struct sss_domain_info *domain,
- const char *name)
+static errno_t
+sysdb_sudo_purge_byname(struct sss_domain_info *domain,
+ const char *name)
{
DEBUG(SSSDBG_TRACE_INTERNAL, "Deleting sudo rule %s\n", name);
return sysdb_delete_custom(domain, name, SUDORULE_SUBDIR);
}
-errno_t sysdb_sudo_purge_byfilter(struct sss_domain_info *domain,
- const char *filter)
+static errno_t
+sysdb_sudo_purge_byrules(struct sss_domain_info *dom,
+ struct sysdb_attrs **rules,
+ size_t num_rules)
+{
+ const char *name;
+ errno_t ret;
+ size_t i;
+
+ DEBUG(SSSDBG_TRACE_FUNC, "About to remove rules from sudo cache\n");
+
+ if (num_rules == 0 || rules == NULL) {
+ return EOK;
+ }
+
+ for (i = 0; i < num_rules; i++) {
+ name = sysdb_sudo_get_rule_name(rules[i]);
+ if (name == NULL) {
+ continue;
+ }
+
+ ret = sysdb_sudo_purge_byname(dom, name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Failed to delete rule "
+ "%s [%d]: %s\n", name, ret, sss_strerror(ret));
+ continue;
+ }
+ }
+
+ return EOK;
+}
+
+static errno_t
+sysdb_sudo_purge_byfilter(struct sss_domain_info *domain,
+ const char *filter)
{
TALLOC_CTX *tmp_ctx;
- size_t count;
+ struct sysdb_attrs **rules;
struct ldb_message **msgs;
- const char *name;
- int i;
+ size_t count;
errno_t ret;
- errno_t sret;
- bool in_transaction = false;
const char *attrs[] = { SYSDB_OBJECTCLASS,
SYSDB_NAME,
SYSDB_SUDO_CACHE_AT_CN,
NULL };
- /* just purge all if there's no filter */
- if (!filter) {
+ if (filter == NULL || strcmp(filter, SUDO_ALL_FILTER) == 0) {
return sysdb_sudo_purge_all(domain);
}
tmp_ctx = talloc_new(NULL);
- NULL_CHECK(tmp_ctx, ret, done);
+ if (tmp_ctx == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
- /* match entries based on the filter and remove them one by one */
ret = sysdb_search_custom(tmp_ctx, domain, filter,
SUDORULE_SUBDIR, attrs,
&count, &msgs);
- if (ret == ENOENT) {
+ if (ret == ENOENT || count == 0) {
DEBUG(SSSDBG_TRACE_FUNC, "No rules matched\n");
ret = EOK;
goto done;
@@ -683,24 +704,165 @@ errno_t sysdb_sudo_purge_byfilter(struct sss_domain_info *domain,
goto done;
}
+ ret = sysdb_msg2attrs(tmp_ctx, count, msgs, &rules);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to convert ldb message to "
+ "sysdb attrs [%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = sysdb_sudo_purge_byrules(domain, rules, count);
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+errno_t sysdb_sudo_purge(struct sss_domain_info *domain,
+ const char *delete_filter,
+ struct sysdb_attrs **rules,
+ size_t num_rules)
+{
+ bool in_transaction = false;
+ errno_t sret;
+ errno_t ret;
+
ret = sysdb_transaction_start(domain->sysdb);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
+ return ret;
+ }
+ in_transaction = true;
+
+ if (delete_filter) {
+ ret = sysdb_sudo_purge_byfilter(domain, delete_filter);
+ } else {
+ ret = sysdb_sudo_purge_byrules(domain, rules, num_rules);
+ }
+
+ if (ret != EOK) {
goto done;
}
+
+ ret = sysdb_transaction_commit(domain->sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
+ goto done;
+ }
+ in_transaction = false;
+
+done:
+ if (in_transaction) {
+ sret = sysdb_transaction_cancel(domain->sysdb);
+ if (sret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Could not cancel transaction\n");
+ }
+ }
+
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to purge sudo cache [%d]: %s\n",
+ ret, sss_strerror(ret));
+ }
+
+ return ret;
+}
+
+static errno_t
+sysdb_sudo_add_sss_attrs(struct sysdb_attrs *rule,
+ const char *name,
+ int cache_timeout,
+ time_t now)
+{
+ time_t expire;
+ errno_t ret;
+
+ ret = sysdb_attrs_add_string(rule, SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to add %s attribute [%d]: %s\n",
+ SYSDB_OBJECTCLASS, ret, strerror(ret));
+ return ret;
+ }
+
+ ret = sysdb_attrs_add_string(rule, SYSDB_NAME, name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to add %s attribute [%d]: %s\n",
+ SYSDB_OBJECTCLASS, ret, strerror(ret));
+ return ret;
+ }
+
+ expire = cache_timeout > 0 ? now + cache_timeout : 0;
+ ret = sysdb_attrs_add_time_t(rule, SYSDB_CACHE_EXPIRE, expire);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to add %s attribute [%d]: %s\n",
+ SYSDB_CACHE_EXPIRE, ret, strerror(ret));
+ return ret;
+ }
+
+ return EOK;
+}
+
+static errno_t
+sysdb_sudo_store_rule(struct sss_domain_info *domain,
+ struct sysdb_attrs *rule,
+ int cache_timeout,
+ time_t now)
+{
+ const char *name;
+ errno_t ret;
+
+ name = sysdb_sudo_get_rule_name(rule);
+ if (name == NULL) {
+ return EINVAL;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, "Adding sudo rule %s\n", name);
+
+ ret = sysdb_sudo_add_sss_attrs(rule, name, cache_timeout, now);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ ret = sysdb_store_custom(domain, name, SUDORULE_SUBDIR, rule);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to store rule %s [%d]: %s\n",
+ name, ret, strerror(ret));
+ return ret;
+ }
+
+ return EOK;
+}
+
+errno_t
+sysdb_sudo_store(struct sss_domain_info *domain,
+ struct sysdb_attrs **rules,
+ size_t num_rules)
+{
+ bool in_transaction = false;
+ errno_t sret;
+ errno_t ret;
+ time_t now;
+ size_t i;
+
+ if (num_rules == 0 || rules == NULL) {
+ return EOK;
+ }
+
+ ret = sysdb_transaction_start(domain->sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
+ return ret;
+ }
in_transaction = true;
- for (i = 0; i < count; i++) {
- name = ldb_msg_find_attr_as_string(msgs[i], SYSDB_NAME, NULL);
- if (name == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "A rule without a name?\n");
- /* skip this one but still delete other entries */
+ now = time(NULL);
+ for (i = 0; i < num_rules; i++) {
+ ret = sysdb_sudo_store_rule(domain, rules[i],
+ domain->sudo_timeout, now);
+ if (ret == EINVAL) {
+ /* Multiple CNs are error on server side, we can just ignore this
+ * rule and save the others. Loud debug message is in logs. */
continue;
- }
-
- ret = sysdb_sudo_purge_byname(domain, name);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Could not delete rule %s\n", name);
+ } else if (ret != EOK) {
goto done;
}
}
@@ -720,6 +882,10 @@ done:
}
}
- talloc_free(tmp_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to store sudo rules [%d]: %s\n",
+ ret, sss_strerror(ret));
+ }
+
return ret;
}
diff --git a/src/db/sysdb_sudo.h b/src/db/sysdb_sudo.h
index fc896c385c6fa71e735b3db763ccee4a0354d007..6dd9ea7bb8ec947f5beceb89fd27bde156c27c36 100644
--- a/src/db/sysdb_sudo.h
+++ b/src/db/sysdb_sudo.h
@@ -78,20 +78,19 @@ sysdb_get_sudo_user_info(TALLOC_CTX *mem_ctx,
const char *username, uid_t *_uid,
char ***groupnames);
-errno_t
-sysdb_save_sudorule(struct sss_domain_info *domain,
- const char *rule_name,
- struct sysdb_attrs *attrs);
-
errno_t sysdb_sudo_set_last_full_refresh(struct sss_domain_info *domain,
time_t value);
errno_t sysdb_sudo_get_last_full_refresh(struct sss_domain_info *domain,
time_t *value);
-errno_t sysdb_sudo_purge_byname(struct sss_domain_info *domain,
- const char *name);
+errno_t sysdb_sudo_purge(struct sss_domain_info *domain,
+ const char *delete_filter,
+ struct sysdb_attrs **rules,
+ size_t num_rules);
-errno_t sysdb_sudo_purge_byfilter(struct sss_domain_info *domain,
- const char *filter);
+errno_t
+sysdb_sudo_store(struct sss_domain_info *domain,
+ struct sysdb_attrs **rules,
+ size_t num_rules);
#endif /* _SYSDB_SUDO_H_ */
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index d7780d38405a2705e25a9c983aca2736548a624e..2fcfa4aec5d4d53f26d40395e99bdce1b41710d4 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -31,7 +31,6 @@
#include "providers/ldap/sdap.h"
#include "providers/ldap/sdap_ops.h"
#include "providers/ldap/sdap_sudo.h"
-#include "providers/ldap/sdap_sudo_cache.h"
#include "db/sysdb_sudo.h"
struct sdap_sudo_load_sudoers_state {
@@ -136,89 +135,6 @@ static int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
return EOK;
}
-static int sdap_sudo_purge_sudoers(struct sss_domain_info *dom,
- const char *filter,
- struct sdap_attr_map *map,
- size_t rules_count,
- struct sysdb_attrs **rules)
-{
- const char *name;
- size_t i;
- errno_t ret;
-
- if (filter == NULL) {
- /* removes downloaded rules from the cache */
- if (rules_count == 0 || rules == NULL) {
- return EOK;
- }
-
- for (i = 0; i < rules_count; i++) {
- ret = sysdb_attrs_get_string(rules[i],
- map[SDAP_AT_SUDO_NAME].sys_name,
- &name);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- "Failed to retrieve rule name: [%s]\n", strerror(ret));
- continue;
- }
-
- ret = sysdb_sudo_purge_byname(dom, name);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- "Failed to delete rule %s: [%s]\n",
- name, strerror(ret));
- continue;
- }
- }
-
- ret = EOK;
- } else {
- /* purge cache by provided filter */
- ret = sysdb_sudo_purge_byfilter(dom, filter);
- if (ret != EOK) {
- goto done;
- }
- }
-
-done:
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "failed to purge sudo rules [%d]: %s\n",
- ret, strerror(ret));
- }
-
- return ret;
-}
-
-static int sdap_sudo_store_sudoers(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- struct sdap_options *opts,
- size_t rules_count,
- struct sysdb_attrs **rules,
- int cache_timeout,
- time_t now,
- char **_usn)
-{
- errno_t ret;
-
- /* Empty sudoers? Done. */
- if (rules_count == 0 || rules == NULL) {
- *_usn = NULL;
- return EOK;
- }
-
- ret = sdap_save_native_sudorule_list(mem_ctx, domain,
- opts->sudorule_map, rules,
- rules_count, cache_timeout, now,
- _usn);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "failed to save sudo rules [%d]: %s\n",
- ret, strerror(ret));
- return ret;
- }
-
- return EOK;
-}
-
static void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, char *usn)
{
unsigned int usn_number;
@@ -230,23 +146,14 @@ static void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, char *usn)
}
if (usn == NULL) {
- /* If the USN value is unknown and we don't have max_sudo_value set
- * (possibly first full refresh which did not find any rule) we will
- * set zero so smart refresh can pick up. */
- if (srv_opts->max_sudo_value == NULL) {
- srv_opts->max_sudo_value = talloc_strdup(srv_opts, "0");
- if (srv_opts->max_sudo_value == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n");
- }
- return;
- }
-
- DEBUG(SSSDBG_TRACE_FUNC, "Empty USN, ignoring\n");
+ DEBUG(SSSDBG_TRACE_FUNC, "Bug: usn is NULL\n");
return;
}
- talloc_zfree(srv_opts->max_sudo_value);
- srv_opts->max_sudo_value = talloc_steal(srv_opts, usn);
+ if (sysdb_compare_usn(usn, srv_opts->max_sudo_value) > 0) {
+ talloc_zfree(srv_opts->max_sudo_value);
+ srv_opts->max_sudo_value = talloc_steal(srv_opts, usn);
+ }
usn_number = strtoul(usn, &endptr, 10);
if ((endptr == NULL || (*endptr == '\0' && endptr != usn))
@@ -625,7 +532,6 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq)
int ret;
errno_t sret;
bool in_transaction = false;
- time_t now;
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_sudo_refresh_state);
@@ -654,17 +560,14 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq)
in_transaction = true;
/* purge cache */
- ret = sdap_sudo_purge_sudoers(state->domain, state->delete_filter,
- state->opts->sudorule_map, rules_count, rules);
+ ret = sysdb_sudo_purge(state->domain, state->delete_filter,
+ rules, rules_count);
if (ret != EOK) {
goto done;
}
/* store rules */
- now = time(NULL);
- ret = sdap_sudo_store_sudoers(state, state->domain,
- state->opts, rules_count, rules,
- state->domain->sudo_timeout, now, &usn);
+ ret = sysdb_sudo_store(state->domain, rules, rules_count);
if (ret != EOK) {
goto done;
}
@@ -680,7 +583,13 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, "Sudoers is successfuly stored in cache\n");
/* remember new usn */
- sdap_sudo_set_usn(state->srv_opts, usn);
+ ret = sysdb_get_highest_usn(state, rules, rules_count, &usn);
+ if (ret == EOK) {
+ sdap_sudo_set_usn(state->srv_opts, usn);
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get highest USN [%d]: %s\n",
+ ret, sss_strerror(ret));
+ }
ret = EOK;
state->num_rules = rules_count;
diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c
index 550784842c6e6162d153785940c1e37a51b5dc1f..10067e9ba779b5224bf21dd7a705c45e7f4e0f99 100644
--- a/src/providers/ldap/sdap_sudo.c
+++ b/src/providers/ldap/sdap_sudo.c
@@ -27,7 +27,6 @@
#include "providers/ldap/sdap.h"
#include "providers/ldap/sdap_async.h"
#include "providers/ldap/sdap_sudo.h"
-#include "providers/ldap/sdap_sudo_cache.h"
#include "db/sysdb_sudo.h"
static void sdap_sudo_handler(struct be_req *breq);
diff --git a/src/providers/ldap/sdap_sudo_cache.c b/src/providers/ldap/sdap_sudo_cache.c
deleted file mode 100644
index 56e84ce8f26338ea5856eb5c76627641eee93df1..0000000000000000000000000000000000000000
--- a/src/providers/ldap/sdap_sudo_cache.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- Authors:
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) 2011 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 <talloc.h>
-
-#include "db/sysdb.h"
-#include "db/sysdb_sudo.h"
-#include "providers/ldap/sdap_sudo_cache.h"
-
-/* ========== Functions specific for the native sudo LDAP schema ========== */
-static errno_t sdap_sudo_get_usn(TALLOC_CTX *mem_ctx,
- struct sysdb_attrs *attrs,
- struct sdap_attr_map *map,
- char **_usn)
-{
- const char *usn;
- errno_t ret;
-
- if (_usn == NULL) {
- return EINVAL;
- }
-
- ret = sysdb_attrs_get_string(attrs, map[SDAP_AT_SUDO_USN].sys_name, &usn);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- "Failed to retrieve USN value: [%s]\n", strerror(ret));
-
- return ret;
- }
-
- *_usn = talloc_strdup(mem_ctx, usn);
- if (*_usn == NULL) {
- return ENOMEM;
- }
-
- return EOK;
-}
-
-static errno_t
-sdap_save_native_sudorule(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- struct sdap_attr_map *map,
- struct sysdb_attrs *attrs,
- int cache_timeout,
- time_t now,
- char **_usn)
-{
- errno_t ret;
- const char *rule_name;
-
- ret = sysdb_attrs_get_string(attrs, map[SDAP_AT_SUDO_NAME].sys_name,
- &rule_name);
- if (ret == ERANGE) {
- DEBUG(SSSDBG_OP_FAILURE, "Warning: found rule that contains none "
- "or multiple CN values. It will be skipped.\n");
- return ret;
- } else if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Could not get rule name [%d]: %s\n",
- ret, strerror(ret));
- return ret;
- }
-
- ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE,
- (cache_timeout ? (now + cache_timeout) : 0));
- if (ret) {
- DEBUG(SSSDBG_OP_FAILURE, "Could not set sysdb cache expire [%d]: %s\n",
- ret, strerror(ret));
- return ret;
- }
-
- ret = sdap_sudo_get_usn(mem_ctx, attrs, map, _usn);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE, "Could not read USN from %s\n", rule_name);
- *_usn = NULL;
- /* but we will store the rule anyway */
- }
-
- ret = sysdb_save_sudorule(domain, rule_name, attrs);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Could not save sudorule %s\n", rule_name);
- return ret;
- }
-
- return ret;
-}
-
-errno_t
-sdap_save_native_sudorule_list(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- struct sdap_attr_map *map,
- struct sysdb_attrs **replies,
- size_t replies_count,
- int cache_timeout,
- time_t now,
- char **_usn)
-{
- TALLOC_CTX *tmp_ctx = NULL;
- char *higher_usn = NULL;
- char *usn_value = NULL;
- errno_t ret, tret;
- bool in_transaction = false;
- size_t i;
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- DEBUG(SSSDBG_FATAL_FAILURE, "talloc_new() failed\n");
- return ENOMEM;
- }
-
- ret = sysdb_transaction_start(domain->sysdb);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Could not start transaction\n");
- goto fail;
- }
- in_transaction = true;
-
- for (i=0; i < replies_count; i++) {
- usn_value = NULL;
- ret = sdap_save_native_sudorule(tmp_ctx, domain, map, replies[i],
- cache_timeout, now, &usn_value);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save sudo rule, "
- "will continue with next...\n");
- continue;
- }
-
- /* find highest usn */
- if (usn_value) {
- if (higher_usn) {
- if ((strlen(usn_value) > strlen(higher_usn)) ||
- (strcmp(usn_value, higher_usn) > 0)) {
- talloc_zfree(higher_usn);
- higher_usn = usn_value;
- } else {
- talloc_zfree(usn_value);
- }
- } else {
- higher_usn = usn_value;
- }
- }
- }
-
- ret = sysdb_transaction_commit(domain->sysdb);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
- goto fail;
- }
- in_transaction = false;
-
- if (higher_usn != NULL) {
- *_usn = talloc_steal(mem_ctx, higher_usn);
- }
-
- ret = EOK;
-fail:
- if (in_transaction) {
- tret = sysdb_transaction_cancel(domain->sysdb);
- if (tret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Could not cancel transaction\n");
- }
- }
-
- talloc_free(tmp_ctx);
-
- return ret;
-}
diff --git a/src/providers/ldap/sdap_sudo_cache.h b/src/providers/ldap/sdap_sudo_cache.h
deleted file mode 100644
index 5a756bf313831267cf34676b392973a1a8e740ec..0000000000000000000000000000000000000000
--- a/src/providers/ldap/sdap_sudo_cache.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- Authors:
- Jakub Hrozek <jhrozek@redhat.com>
-
- Copyright (C) 2011 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/>.
-*/
-
-#ifndef _SDAP_SUDO_CACHE_H_
-#define _SDAP_SUDO_CACHE_H_
-
-#include "src/providers/ldap/sdap.h"
-
-/* Cache functions specific for the native sudo LDAP schema */
-errno_t
-sdap_save_native_sudorule_list(TALLOC_CTX *mem_ctx,
- struct sss_domain_info *domain,
- struct sdap_attr_map *map,
- struct sysdb_attrs **replies,
- size_t replies_count,
- int cache_timeout,
- time_t now,
- char **_usn);
-
-#endif /* _SDAP_SUDO_CACHE_H_ */
--
2.5.0

View File

@ -1,394 +0,0 @@
From 95653f8aa03f44fff011ac1c04c1dac8b460687c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 17 Dec 2015 13:24:39 +0100
Subject: [PATCH 17/49] SUDO: move code shared between ldap and ipa to separate
module
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 85feb8d77a2c832787880944e02104846c4d5376)
---
Makefile.am | 2 +
src/providers/ldap/sdap_async_sudo.c | 31 +------
src/providers/ldap/sdap_sudo_refresh.c | 87 ++-----------------
src/providers/ldap/sdap_sudo_shared.c | 149 +++++++++++++++++++++++++++++++++
src/providers/ldap/sdap_sudo_shared.h | 40 +++++++++
5 files changed, 199 insertions(+), 110 deletions(-)
create mode 100644 src/providers/ldap/sdap_sudo_shared.c
create mode 100644 src/providers/ldap/sdap_sudo_shared.h
diff --git a/Makefile.am b/Makefile.am
index 29dd73edf3e6770e4280945f69c9d266f3d8c4c4..8b57640cacd0e1f30f3d1270a92521c55ba0e026 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -619,6 +619,7 @@ dist_noinst_HEADERS = \
src/providers/ldap/sdap_async.h \
src/providers/ldap/sdap_async_private.h \
src/providers/ldap/sdap_sudo.h \
+ src/providers/ldap/sdap_sudo_shared.h \
src/providers/ldap/sdap_autofs.h \
src/providers/ldap/sdap_id_op.h \
src/providers/ldap/ldap_opts.h \
@@ -2861,6 +2862,7 @@ libsss_ldap_common_la_SOURCES += \
src/providers/ldap/sdap_async_sudo.c \
src/providers/ldap/sdap_async_sudo_hostinfo.c \
src/providers/ldap/sdap_sudo_refresh.c \
+ src/providers/ldap/sdap_sudo_shared.c \
src/providers/ldap/sdap_sudo.c
endif
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index 2fcfa4aec5d4d53f26d40395e99bdce1b41710d4..d26d00f47a5c1fa02705a09c1d3ce02a4d5788a8 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -31,6 +31,7 @@
#include "providers/ldap/sdap.h"
#include "providers/ldap/sdap_ops.h"
#include "providers/ldap/sdap_sudo.h"
+#include "providers/ldap/sdap_sudo_shared.h"
#include "db/sysdb_sudo.h"
struct sdap_sudo_load_sudoers_state {
@@ -135,36 +136,6 @@ static int sdap_sudo_load_sudoers_recv(struct tevent_req *req,
return EOK;
}
-static void sdap_sudo_set_usn(struct sdap_server_opts *srv_opts, char *usn)
-{
- unsigned int usn_number;
- char *endptr = NULL;
-
- if (srv_opts == NULL) {
- DEBUG(SSSDBG_TRACE_FUNC, "Bug: srv_opts is NULL\n");
- return;
- }
-
- if (usn == NULL) {
- DEBUG(SSSDBG_TRACE_FUNC, "Bug: usn is NULL\n");
- return;
- }
-
- if (sysdb_compare_usn(usn, srv_opts->max_sudo_value) > 0) {
- talloc_zfree(srv_opts->max_sudo_value);
- srv_opts->max_sudo_value = talloc_steal(srv_opts, usn);
- }
-
- usn_number = strtoul(usn, &endptr, 10);
- if ((endptr == NULL || (*endptr == '\0' && endptr != usn))
- && (usn_number > srv_opts->last_usn)) {
- srv_opts->last_usn = usn_number;
- }
-
- DEBUG(SSSDBG_FUNC_DATA, "SUDO higher USN value: [%s]\n",
- srv_opts->max_sudo_value);
-}
-
static char *sdap_sudo_build_host_filter(TALLOC_CTX *mem_ctx,
struct sdap_attr_map *map,
char **hostnames,
diff --git a/src/providers/ldap/sdap_sudo_refresh.c b/src/providers/ldap/sdap_sudo_refresh.c
index e3df8f1c5071518af1d1f10cf0e3a19301f78640..5697818ce71240468d2bcaa8af7994ca6b8ea3ef 100644
--- a/src/providers/ldap/sdap_sudo_refresh.c
+++ b/src/providers/ldap/sdap_sudo_refresh.c
@@ -25,6 +25,7 @@
#include "util/util.h"
#include "providers/dp_ptask.h"
#include "providers/ldap/sdap_sudo.h"
+#include "providers/ldap/sdap_sudo_shared.h"
#include "db/sysdb_sudo.h"
struct sdap_sudo_full_refresh_state {
@@ -469,84 +470,10 @@ sdap_sudo_ptask_smart_refresh_recv(struct tevent_req *req)
errno_t
sdap_sudo_ptask_setup(struct be_ctx *be_ctx, struct sdap_sudo_ctx *sudo_ctx)
{
- struct dp_option *opts = sudo_ctx->id_ctx->opts->basic;
- time_t smart;
- time_t full;
- time_t delay;
- time_t last_refresh;
- errno_t ret;
-
- smart = dp_opt_get_int(opts, SDAP_SUDO_SMART_REFRESH_INTERVAL);
- full = dp_opt_get_int(opts, SDAP_SUDO_FULL_REFRESH_INTERVAL);
-
- if (smart == 0 && full == 0) {
- /* We don't allow both types to be disabled. At least smart refresh
- * needs to be enabled. In this case smart refresh will catch up new
- * and modified rules and deleted rules are caught when expired. */
- smart = opts[SDAP_SUDO_SMART_REFRESH_INTERVAL].def_val.number;
-
- DEBUG(SSSDBG_CONF_SETTINGS, "At least smart refresh needs to be "
- "enabled. Setting smart refresh interval to default value "
- "(%ld) seconds.\n", smart);
- } else if (full <= smart) {
- /* In this case it does not make any sense to run smart refresh. */
- smart = 0;
-
- DEBUG(SSSDBG_CONF_SETTINGS, "Smart refresh interval has to be lower "
- "than full refresh interval. Periodical smart refresh will be "
- "disabled.\n");
- }
-
- ret = sysdb_sudo_get_last_full_refresh(be_ctx->domain, &last_refresh);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE, "Unable to obtain time of last full "
- "refresh. Assuming none was performed so far.\n");
- last_refresh = 0;
- }
-
- if (last_refresh == 0) {
- /* If this is the first startup, we need to kick off an refresh
- * immediately, to close a window where clients requesting sudo
- * information won't get an immediate reply with no entries */
- delay = 0;
- } else {
- /* At least one update has previously run, so clients will get cached
- * data. We will delay the refresh so we don't slow down the startup
- * process if this is happening during system boot. */
- delay = 10;
- }
-
- /* Full refresh.
- *
- * Disable when offline and run immediately when SSSD goes back online.
- * Since we have periodical online check we don't have to run this task
- * when offline. */
- ret = be_ptask_create(be_ctx, be_ctx, full, delay, 0, 0, full,
- BE_PTASK_OFFLINE_DISABLE, 0,
- sdap_sudo_ptask_full_refresh_send,
- sdap_sudo_ptask_full_refresh_recv,
- sudo_ctx, "SUDO Full Refresh", NULL);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup full refresh ptask "
- "[%d]: %s\n", ret, sss_strerror(ret));
- return ret;
- }
-
- /* Smart refresh.
- *
- * Disable when offline and reschedule normally when SSSD goes back online.
- * Since we have periodical online check we don't have to run this task
- * when offline. */
- ret = be_ptask_create(be_ctx, be_ctx, smart, delay + smart, smart, 0, smart,
- BE_PTASK_OFFLINE_DISABLE, 0,
- sdap_sudo_ptask_smart_refresh_send,
- sdap_sudo_ptask_smart_refresh_recv,
- sudo_ctx, "SUDO Smart Refresh", NULL);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup smart refresh ptask "
- "[%d]: %s\n", ret, sss_strerror(ret));
- return ret;
- }
-
- return EOK;
+ return sdap_sudo_ptask_setup_generic(be_ctx, sudo_ctx->id_ctx->opts->basic,
+ sdap_sudo_ptask_full_refresh_send,
+ sdap_sudo_ptask_full_refresh_recv,
+ sdap_sudo_ptask_smart_refresh_send,
+ sdap_sudo_ptask_smart_refresh_recv,
+ sudo_ctx);
}
diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c
new file mode 100644
index 0000000000000000000000000000000000000000..86a6acf4758a1d5952f28cf1847a425d1b3b40ec
--- /dev/null
+++ b/src/providers/ldap/sdap_sudo_shared.c
@@ -0,0 +1,149 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2015 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 <errno.h>
+#include <time.h>
+#include <talloc.h>
+
+#include "util/util.h"
+#include "providers/dp_ptask.h"
+#include "providers/ldap/sdap.h"
+#include "providers/ldap/sdap_sudo_shared.h"
+#include "db/sysdb_sudo.h"
+
+errno_t
+sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
+ struct dp_option *opts,
+ be_ptask_send_t full_send_fn,
+ be_ptask_recv_t full_recv_fn,
+ be_ptask_send_t smart_send_fn,
+ be_ptask_recv_t smart_recv_fn,
+ void *pvt)
+{
+ time_t smart;
+ time_t full;
+ time_t delay;
+ time_t last_refresh;
+ errno_t ret;
+
+ smart = dp_opt_get_int(opts, SDAP_SUDO_SMART_REFRESH_INTERVAL);
+ full = dp_opt_get_int(opts, SDAP_SUDO_FULL_REFRESH_INTERVAL);
+
+ if (smart == 0 && full == 0) {
+ /* We don't allow both types to be disabled. At least smart refresh
+ * needs to be enabled. In this case smart refresh will catch up new
+ * and modified rules and deleted rules are caught when expired. */
+ smart = opts[SDAP_SUDO_SMART_REFRESH_INTERVAL].def_val.number;
+
+ DEBUG(SSSDBG_CONF_SETTINGS, "At least smart refresh needs to be "
+ "enabled. Setting smart refresh interval to default value "
+ "(%ld) seconds.\n", smart);
+ } else if (full <= smart) {
+ /* In this case it does not make any sense to run smart refresh. */
+ smart = 0;
+
+ DEBUG(SSSDBG_CONF_SETTINGS, "Smart refresh interval has to be lower "
+ "than full refresh interval. Periodical smart refresh will be "
+ "disabled.\n");
+ }
+
+ ret = sysdb_sudo_get_last_full_refresh(be_ctx->domain, &last_refresh);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to obtain time of last full "
+ "refresh. Assuming none was performed so far.\n");
+ last_refresh = 0;
+ }
+
+ if (last_refresh == 0) {
+ /* If this is the first startup, we need to kick off an refresh
+ * immediately, to close a window where clients requesting sudo
+ * information won't get an immediate reply with no entries */
+ delay = 0;
+ } else {
+ /* At least one update has previously run, so clients will get cached
+ * data. We will delay the refresh so we don't slow down the startup
+ * process if this is happening during system boot. */
+ delay = 10;
+ }
+
+ /* Full refresh.
+ *
+ * Disable when offline and run immediately when SSSD goes back online.
+ * Since we have periodical online check we don't have to run this task
+ * when offline. */
+ ret = be_ptask_create(be_ctx, be_ctx, full, delay, 0, 0, full,
+ BE_PTASK_OFFLINE_DISABLE, 0,
+ full_send_fn, full_recv_fn, pvt,
+ "SUDO Full Refresh", NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup full refresh ptask "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ return ret;
+ }
+
+ /* Smart refresh.
+ *
+ * Disable when offline and reschedule normally when SSSD goes back online.
+ * Since we have periodical online check we don't have to run this task
+ * when offline. */
+ ret = be_ptask_create(be_ctx, be_ctx, smart, delay + smart, smart, 0, smart,
+ BE_PTASK_OFFLINE_DISABLE, 0,
+ smart_send_fn, smart_recv_fn, pvt,
+ "SUDO Smart Refresh", NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup smart refresh ptask "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ return ret;
+ }
+
+ return EOK;
+}
+
+void
+sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
+ char *usn)
+{
+ unsigned int usn_number;
+ char *endptr = NULL;
+
+ if (srv_opts == NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Bug: srv_opts is NULL\n");
+ return;
+ }
+
+ if (usn == NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Bug: usn is NULL\n");
+ return;
+ }
+
+ if (sysdb_compare_usn(usn, srv_opts->max_sudo_value) > 0) {
+ talloc_zfree(srv_opts->max_sudo_value);
+ srv_opts->max_sudo_value = talloc_steal(srv_opts, usn);
+ }
+
+ usn_number = strtoul(usn, &endptr, 10);
+ if ((endptr == NULL || (*endptr == '\0' && endptr != usn))
+ && (usn_number > srv_opts->last_usn)) {
+ srv_opts->last_usn = usn_number;
+ }
+
+ DEBUG(SSSDBG_FUNC_DATA, "SUDO higher USN value: [%s]\n",
+ srv_opts->max_sudo_value);
+}
diff --git a/src/providers/ldap/sdap_sudo_shared.h b/src/providers/ldap/sdap_sudo_shared.h
new file mode 100644
index 0000000000000000000000000000000000000000..bbc6927250cf8a9b4a92eb15bad6c718c76e2f70
--- /dev/null
+++ b/src/providers/ldap/sdap_sudo_shared.h
@@ -0,0 +1,40 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2015 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/>.
+*/
+
+#ifndef _SDAP_SUDO_SHARED_H_
+#define _SDAP_SUDO_SHARED_H_
+
+#include "providers/dp_backend.h"
+#include "providers/dp_ptask.h"
+
+errno_t
+sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
+ struct dp_option *opts,
+ be_ptask_send_t full_send_fn,
+ be_ptask_recv_t full_recv_fn,
+ be_ptask_send_t smart_send_fn,
+ be_ptask_recv_t smart_recv_fn,
+ void *pvt);
+
+void
+sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
+ char *usn);
+
+#endif /* _SDAP_SUDO_SHARED_H_ */
--
2.5.0

View File

@ -1,68 +0,0 @@
From ccf6c568a0bb4a3660297653d96c7fb311b6665f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 18 Dec 2015 11:50:09 +0100
Subject: [PATCH 18/49] SUDO: allow to disable ptask
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit e085a79acfcd5331b6f99748e21765579a9a99f2)
---
src/providers/ldap/sdap_sudo_shared.c | 36 +++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c
index 86a6acf4758a1d5952f28cf1847a425d1b3b40ec..b31d5d27f61b73e71ab8ad0341415ee00e2295cf 100644
--- a/src/providers/ldap/sdap_sudo_shared.c
+++ b/src/providers/ldap/sdap_sudo_shared.c
@@ -88,14 +88,16 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
* Disable when offline and run immediately when SSSD goes back online.
* Since we have periodical online check we don't have to run this task
* when offline. */
- ret = be_ptask_create(be_ctx, be_ctx, full, delay, 0, 0, full,
- BE_PTASK_OFFLINE_DISABLE, 0,
- full_send_fn, full_recv_fn, pvt,
- "SUDO Full Refresh", NULL);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup full refresh ptask "
- "[%d]: %s\n", ret, sss_strerror(ret));
- return ret;
+ if (full > 0) {
+ ret = be_ptask_create(be_ctx, be_ctx, full, delay, 0, 0, full,
+ BE_PTASK_OFFLINE_DISABLE, 0,
+ full_send_fn, full_recv_fn, pvt,
+ "SUDO Full Refresh", NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup full refresh ptask "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ return ret;
+ }
}
/* Smart refresh.
@@ -103,14 +105,16 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
* Disable when offline and reschedule normally when SSSD goes back online.
* Since we have periodical online check we don't have to run this task
* when offline. */
- ret = be_ptask_create(be_ctx, be_ctx, smart, delay + smart, smart, 0, smart,
- BE_PTASK_OFFLINE_DISABLE, 0,
- smart_send_fn, smart_recv_fn, pvt,
- "SUDO Smart Refresh", NULL);
- if (ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup smart refresh ptask "
- "[%d]: %s\n", ret, sss_strerror(ret));
- return ret;
+ if (smart > 0) {
+ ret = be_ptask_create(be_ctx, be_ctx, smart, delay + smart, smart, 0,
+ smart, BE_PTASK_OFFLINE_DISABLE, 0,
+ smart_send_fn, smart_recv_fn, pvt,
+ "SUDO Smart Refresh", NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to setup smart refresh ptask "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ return ret;
+ }
}
return EOK;
--
2.5.0

View File

@ -1,28 +0,0 @@
From 3571ecfed9d76240324f881c7d1faaf62fa2798c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 18 Dec 2015 12:45:53 +0100
Subject: [PATCH 19/49] SUDO: fail on failed request that cannot be retry
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit cad751beaa12e34e15565bc413442b1e80ac0c29)
---
src/providers/ldap/sdap_async_sudo.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/providers/ldap/sdap_async_sudo.c b/src/providers/ldap/sdap_async_sudo.c
index d26d00f47a5c1fa02705a09c1d3ce02a4d5788a8..e3f3da186181a5f3ffbe818073cdbdca1112857a 100644
--- a/src/providers/ldap/sdap_async_sudo.c
+++ b/src/providers/ldap/sdap_async_sudo.c
@@ -518,6 +518,9 @@ static void sdap_sudo_refresh_done(struct tevent_req *subreq)
tevent_req_error(req, ret);
}
return;
+ } else if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
}
DEBUG(SSSDBG_TRACE_FUNC, "Received %zu rules\n", rules_count);
--
2.5.0

View File

@ -1,510 +0,0 @@
From 51e5796950c7e429838d7283441af63171339657 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 10 Dec 2015 14:08:52 +0100
Subject: [PATCH 20/49] IPA: add ipa_get_rdn and ipa_check_rdn
To exploit knowledge of IPA LDAP hierarchy.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit b407fe0474a674bb42f0f42ab47c7f530a07a367)
---
Makefile.am | 22 ++++
src/providers/ipa/ipa_dn.c | 145 ++++++++++++++++++++++++++
src/providers/ipa/ipa_dn.h | 43 ++++++++
src/tests/cmocka/test_ipa_dn.c | 228 +++++++++++++++++++++++++++++++++++++++++
4 files changed, 438 insertions(+)
create mode 100644 src/providers/ipa/ipa_dn.c
create mode 100644 src/providers/ipa/ipa_dn.h
create mode 100644 src/tests/cmocka/test_ipa_dn.c
diff --git a/Makefile.am b/Makefile.am
index 8b57640cacd0e1f30f3d1270a92521c55ba0e026..6efb5ea7f81642292b39a44e7e2029a2757e47ea 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -245,6 +245,7 @@ if HAVE_CMOCKA
test_cert_utils \
test_ldap_id_cleanup \
test_data_provider_be \
+ test_ipa_dn \
$(NULL)
if HAVE_LIBRESOLV
@@ -642,6 +643,7 @@ dist_noinst_HEADERS = \
src/providers/ipa/ipa_hostid.h \
src/providers/ipa/ipa_opts.h \
src/providers/ipa/ipa_srv.h \
+ src/providers/ipa/ipa_dn.h \
src/providers/ad/ad_srv.h \
src/providers/proxy/proxy.h \
src/tools/tools_util.h \
@@ -2631,6 +2633,25 @@ test_data_provider_be_LDADD = \
libdlopen_test_providers.la \
$(NULL)
+test_ipa_dn_SOURCES = \
+ src/providers/ipa/ipa_dn.c \
+ src/tests/cmocka/test_ipa_dn.c \
+ $(NULL)
+test_ipa_dn_CFLAGS = \
+ $(AM_CFLAGS) \
+ -DUNIT_TESTING \
+ $(NULL)
+test_ipa_dn_LDFLAGS = \
+ -Wl,-wrap,_tevent_add_timer \
+ $(NULL)
+test_ipa_dn_LDADD = \
+ $(CMOCKA_LIBS) \
+ $(SSSD_LIBS) \
+ $(SSSD_INTERNAL_LTLIBS) \
+ $(LIBADD_DL) \
+ libsss_test_common.la \
+ $(NULL)
+
endif # HAVE_CMOCKA
noinst_PROGRAMS = pam_test_client
@@ -2983,6 +3004,7 @@ libsss_ipa_la_SOURCES = \
src/providers/ipa/ipa_selinux_maps.c \
src/providers/ipa/ipa_srv.c \
src/providers/ipa/ipa_idmap.c \
+ src/providers/ipa/ipa_dn.c \
src/providers/ad/ad_opts.c \
src/providers/ad/ad_common.c \
src/providers/ad/ad_common.h \
diff --git a/src/providers/ipa/ipa_dn.c b/src/providers/ipa/ipa_dn.c
new file mode 100644
index 0000000000000000000000000000000000000000..c58e014f8c83d39f2c558449702a02dc6fdb0713
--- /dev/null
+++ b/src/providers/ipa/ipa_dn.c
@@ -0,0 +1,145 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2015 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 <talloc.h>
+#include <ldb.h>
+#include "db/sysdb.h"
+#include "providers/ipa/ipa_dn.h"
+
+static bool check_dn(struct ldb_dn *dn,
+ const char *rdn_attr,
+ va_list in_ap)
+{
+ const struct ldb_val *ldbval;
+ const char *strval;
+ const char *ldbattr;
+ const char *attr;
+ const char *val;
+ va_list ap;
+ int num_comp;
+ int comp;
+
+ /* check RDN attribute */
+ ldbattr = ldb_dn_get_rdn_name(dn);
+ if (ldbattr == NULL || strcasecmp(ldbattr, rdn_attr) != 0) {
+ return false;
+ }
+
+ /* Check DN components. First we check if all attr=value pairs match input.
+ * Then we check that the next attribute is a domain component.
+ */
+
+ comp = 1;
+ num_comp = ldb_dn_get_comp_num(dn);
+
+ va_copy(ap, in_ap);
+ while ((attr = va_arg(ap, const char *)) != NULL) {
+ val = va_arg(ap, const char *);
+ if (val == NULL) {
+ goto vafail;
+ }
+
+ if (comp > num_comp) {
+ goto vafail;
+ }
+
+ ldbattr = ldb_dn_get_component_name(dn, comp);
+ if (ldbattr == NULL || strcasecmp(ldbattr, attr) != 0) {
+ goto vafail;
+ }
+
+ ldbval = ldb_dn_get_component_val(dn, comp);
+ if (ldbval == NULL) {
+ goto vafail;
+ }
+
+ strval = (const char *)ldbval->data;
+ if (strval == NULL || strncasecmp(strval, val, ldbval->length) != 0) {
+ goto vafail;
+ }
+
+ comp++;
+ }
+ va_end(ap);
+
+ ldbattr = ldb_dn_get_component_name(dn, comp);
+ if (ldbattr == NULL || strcmp(ldbattr, "dc") != 0) {
+ return false;
+ }
+
+ return true;
+
+vafail:
+ va_end(ap);
+ return false;
+}
+
+errno_t _ipa_get_rdn(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *sysdb,
+ const char *obj_dn,
+ char **_rdn_val,
+ const char *rdn_attr,
+ ...)
+{
+ const struct ldb_val *val;
+ struct ldb_dn *dn;
+ errno_t ret;
+ bool bret;
+ va_list ap;
+ char *rdn;
+
+ dn = ldb_dn_new(mem_ctx, sysdb_ctx_get_ldb(sysdb), obj_dn);
+ if (dn == NULL) {
+ return ENOMEM;
+ }
+
+ va_start(ap, rdn_attr);
+ bret = check_dn(dn, rdn_attr, ap);
+ va_end(ap);
+ if (bret == false) {
+ ret = ENOENT;
+ goto done;
+ }
+
+ if (_rdn_val == NULL) {
+ ret = EOK;
+ goto done;
+ }
+
+ val = ldb_dn_get_rdn_val(dn);
+ if (val == NULL || val->data == NULL) {
+ ret = EINVAL;
+ goto done;
+ }
+
+ rdn = talloc_strndup(mem_ctx, (const char*)val->data, val->length);
+ if (rdn == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ *_rdn_val = rdn;
+
+ ret = EOK;
+
+done:
+ talloc_free(dn);
+ return ret;
+}
diff --git a/src/providers/ipa/ipa_dn.h b/src/providers/ipa/ipa_dn.h
new file mode 100644
index 0000000000000000000000000000000000000000..f889c3ee6548c6d4cf719441bbe2f0c7caa1a579
--- /dev/null
+++ b/src/providers/ipa/ipa_dn.h
@@ -0,0 +1,43 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2015 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/>.
+*/
+
+#ifndef IPA_DN_H_
+#define IPA_DN_H_
+
+#include <talloc.h>
+#include "db/sysdb.h"
+
+errno_t _ipa_get_rdn(TALLOC_CTX *mem_ctx,
+ struct sysdb_ctx *sysdb,
+ const char *obj_dn,
+ char **_rdn_val,
+ const char *rdn_attr,
+ ...);
+
+#define ipa_get_rdn(mem_ctx, sysdb, dn, _rdn_val, rdn_attr, ...) \
+ _ipa_get_rdn(mem_ctx, sysdb, dn, _rdn_val, rdn_attr, ##__VA_ARGS__, NULL)
+
+#define ipa_check_rdn(sysdb, dn, rdn_attr, ...) \
+ _ipa_get_rdn(NULL, sysdb, dn, NULL, rdn_attr, ##__VA_ARGS__, NULL)
+
+#define ipa_check_rdn_bool(sysdb, dn, rdn_attr, ...) \
+ ((bool)(ipa_check_rdn(sysdb, dn, rdn_attr, ##__VA_ARGS__) == EOK))
+
+#endif /* IPA_DN_H_ */
diff --git a/src/tests/cmocka/test_ipa_dn.c b/src/tests/cmocka/test_ipa_dn.c
new file mode 100644
index 0000000000000000000000000000000000000000..a6e26ec31ff25519ad895ef934dac0e3a3dd83ae
--- /dev/null
+++ b/src/tests/cmocka/test_ipa_dn.c
@@ -0,0 +1,228 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2015 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 <talloc.h>
+#include <errno.h>
+#include <popt.h>
+
+#include "tests/cmocka/common_mock.h"
+#include "providers/ipa/ipa_dn.h"
+
+#define TESTS_PATH "tp_" BASE_FILE_STEM
+#define TEST_CONF_DB "test_ipa_dn_conf.ldb"
+#define TEST_DOM_NAME "ipa_dn_test"
+#define TEST_ID_PROVIDER "ipa"
+
+struct ipa_dn_test_ctx {
+ struct sss_test_ctx *tctx;
+ struct sysdb_ctx *sysdb;
+};
+
+static int ipa_dn_test_setup(void **state)
+{
+ struct ipa_dn_test_ctx *test_ctx = NULL;
+
+ test_ctx = talloc_zero(NULL, struct ipa_dn_test_ctx);
+ assert_non_null(test_ctx);
+ *state = test_ctx;
+
+ /* initialize domain */
+ test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB,
+ TEST_DOM_NAME,
+ TEST_ID_PROVIDER, NULL);
+ assert_non_null(test_ctx->tctx);
+
+ test_ctx->sysdb = test_ctx->tctx->sysdb;
+
+ return 0;
+}
+
+static int ipa_dn_test_teardown(void **state)
+{
+ talloc_zfree(*state);
+ return 0;
+}
+
+static void ipa_check_rdn_test(void **state)
+{
+ struct ipa_dn_test_ctx *test_ctx = NULL;
+ errno_t ret;
+
+ test_ctx = talloc_get_type_abort(*state, struct ipa_dn_test_ctx);
+
+ ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,dc=example,dc=com", "cn");
+ assert_int_equal(ret, EOK);
+
+ ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "attr1", "value1");
+ assert_int_equal(ret, EOK);
+
+ ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", "cn", "attr1", "value1", "attr2", "value2");
+ assert_int_equal(ret, EOK);
+
+ ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,dc=example,dc=com", "nope");
+ assert_int_equal(ret, ENOENT);
+
+ ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "nope", "value1");
+ assert_int_equal(ret, ENOENT);
+
+ ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", "cn", "attr1", "nope");
+ assert_int_equal(ret, ENOENT);
+
+ ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "attr1");
+ assert_int_equal(ret, ENOENT);
+
+ ret = ipa_check_rdn(test_ctx->sysdb, "cn=rdn,attr1=value1", "cn", "attr1", "value1");
+ assert_int_equal(ret, ENOENT);
+}
+
+static void ipa_check_rdn_bool_test(void **state)
+{
+ struct ipa_dn_test_ctx *test_ctx = NULL;
+ bool bret;
+
+ test_ctx = talloc_get_type_abort(*state, struct ipa_dn_test_ctx);
+
+ bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,dc=example,dc=com", "cn");
+ assert_true(bret);
+
+ bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "attr1", "value1");
+ assert_true(bret);
+
+ bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", "cn", "attr1", "value1", "attr2", "value2");
+ assert_true(bret);
+
+ bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,dc=example,dc=com", "nope");
+ assert_false(bret);
+
+ bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "nope", "value1");
+ assert_false(bret);
+
+ bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", "cn", "attr1", "nope");
+ assert_false(bret);
+
+ bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", "cn", "attr1");
+ assert_false(bret);
+
+ bret = ipa_check_rdn_bool(test_ctx->sysdb, "cn=rdn,attr1=value1", "cn", "attr1", "value1");
+ assert_false(bret);
+}
+
+static void ipa_get_rdn_test(void **state)
+{
+ struct ipa_dn_test_ctx *test_ctx = NULL;
+ const char *exprdn = "rdn";
+ char *rdn = NULL;
+ errno_t ret;
+
+ test_ctx = talloc_get_type_abort(*state, struct ipa_dn_test_ctx);
+
+ ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,dc=example,dc=com", &rdn, "cn");
+ assert_int_equal(ret, EOK);
+ assert_non_null(rdn);
+ assert_string_equal(exprdn, rdn);
+
+ ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", &rdn, "cn", "attr1", "value1");
+ assert_int_equal(ret, EOK);
+ assert_non_null(rdn);
+ assert_string_equal(exprdn, rdn);
+
+ ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", &rdn, "cn", "attr1", "value1", "attr2", "value2");
+ assert_int_equal(ret, EOK);
+ assert_non_null(rdn);
+ assert_string_equal(exprdn, rdn);
+
+ rdn = NULL;
+
+ ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,dc=example,dc=com", &rdn, "nope");
+ assert_int_equal(ret, ENOENT);
+ assert_null(rdn);
+
+ ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", &rdn, "cn", "nope", "value1");
+ assert_int_equal(ret, ENOENT);
+ assert_null(rdn);
+
+ ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1,attr2=value2,dc=example,dc=com", &rdn, "cn", "attr1", "nope");
+ assert_int_equal(ret, ENOENT);
+ assert_null(rdn);
+
+ ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1,dc=example,dc=com", &rdn, "cn", "attr1");
+ assert_int_equal(ret, ENOENT);
+ assert_null(rdn);
+
+ ret = ipa_get_rdn(test_ctx, test_ctx->sysdb, "cn=rdn,attr1=value1", &rdn, "cn", "attr1", "value1");
+ assert_int_equal(ret, ENOENT);
+ assert_null(rdn);
+}
+
+int main(int argc, const char *argv[])
+{
+ int rv;
+ int no_cleanup = 0;
+ poptContext pc;
+ int opt;
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ SSSD_DEBUG_OPTS
+ {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0,
+ _("Do not delete the test database after a test run"), NULL },
+ POPT_TABLEEND
+ };
+
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(ipa_check_rdn_test,
+ ipa_dn_test_setup,
+ ipa_dn_test_teardown),
+ cmocka_unit_test_setup_teardown(ipa_check_rdn_bool_test,
+ ipa_dn_test_setup,
+ ipa_dn_test_teardown),
+ cmocka_unit_test_setup_teardown(ipa_get_rdn_test,
+ ipa_dn_test_setup,
+ ipa_dn_test_teardown)
+ };
+
+ /* Set debug level to invalid value so we can deside 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);
+
+ /* Even though normally the tests should clean up after themselves
+ * they might not after a failed run. Remove the old db to be sure */
+ tests_set_cwd();
+ test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
+ test_dom_suite_setup(TESTS_PATH);
+
+ rv = cmocka_run_group_tests(tests, NULL, NULL);
+ if (rv == 0 && !no_cleanup) {
+ test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
+ }
+ return rv;
+}
--
2.5.0

View File

@ -1,152 +0,0 @@
From 0e69b0fca08a1e35eb50232bfaa10094101ea801 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 10 Dec 2015 15:10:37 +0100
Subject: [PATCH 21/49] SDAP: use ipa_get_rdn() in nested groups
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit a6dd4a6c55773e81490dcafd61d4b9782705e9bf)
---
Makefile.am | 2 +
src/providers/ldap/sdap_async_nested_groups.c | 80 +++------------------------
2 files changed, 11 insertions(+), 71 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 6efb5ea7f81642292b39a44e7e2029a2757e47ea..59632f59f26f6d113de3398856e2ef0015d4ad16 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2092,6 +2092,7 @@ nestedgroups_tests_SOURCES = \
src/tests/cmocka/common_mock_be.c \
src/providers/ldap/sdap_async_nested_groups.c \
src/providers/ldap/sdap_ad_groups.c \
+ src/providers/ipa/ipa_dn.c \
$(NULL)
nestedgroups_tests_CFLAGS = \
$(AM_CFLAGS) \
@@ -2860,6 +2861,7 @@ libsss_ldap_common_la_SOURCES = \
src/providers/ldap/sdap_domain.c \
src/providers/ldap/sdap_ops.c \
src/providers/ldap/sdap.c \
+ src/providers/ipa/ipa_dn.c \
src/util/user_info_msg.c \
src/util/sss_ldap.c \
$(NULL)
diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c
index af25430eacd4de7ea2e2872b0d9e34c8515c22db..9d715225243d8672850563473bd3938d4cc5db6b 100644
--- a/src/providers/ldap/sdap_async_nested_groups.c
+++ b/src/providers/ldap/sdap_async_nested_groups.c
@@ -35,6 +35,7 @@
#include "providers/ldap/sdap_async.h"
#include "providers/ldap/sdap_async_private.h"
#include "providers/ldap/sdap_idmap.h"
+#include "providers/ipa/ipa_dn.h"
#define sdap_nested_group_sysdb_search_users(domain, filter) \
sdap_nested_group_sysdb_search((domain), (filter), true)
@@ -1417,96 +1418,33 @@ static errno_t sdap_nested_group_single_recv(struct tevent_req *req)
return EOK;
}
-/* This should be a function pointer set from the IPA provider */
static errno_t sdap_nested_group_get_ipa_user(TALLOC_CTX *mem_ctx,
const char *user_dn,
struct sysdb_ctx *sysdb,
struct sysdb_attrs **_user)
{
- errno_t ret;
- struct sysdb_attrs *user = NULL;
- char *name;
- struct ldb_dn *dn = NULL;
- const char *rdn_name;
- const char *users_comp_name;
- const char *acct_comp_name;
- const struct ldb_val *rdn_val;
- const struct ldb_val *users_comp_val;
- const struct ldb_val *acct_comp_val;
TALLOC_CTX *tmp_ctx;
+ struct sysdb_attrs *user;
+ char *name;
+ errno_t ret;
tmp_ctx = talloc_new(NULL);
- if (!tmp_ctx) return ENOMEM;
-
- /* return username if dn is in form:
- * uid=username,cn=users,cn=accounts,dc=example,dc=com */
-
- dn = ldb_dn_new(tmp_ctx, sysdb_ctx_get_ldb(sysdb), user_dn);
- if (dn == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
- /* rdn, users, accounts and least one domain component */
- if (ldb_dn_get_comp_num(dn) < 4) {
- ret = ENOENT;
- goto done;
- }
-
- rdn_name = ldb_dn_get_rdn_name(dn);
- if (rdn_name == NULL) {
- ret = EINVAL;
- goto done;
- }
-
- /* rdn must be 'uid' */
- if (strcasecmp("uid", rdn_name) != 0) {
- ret = ENOENT;
- goto done;
- }
-
- /* second component must be 'cn=users' */
- users_comp_name = ldb_dn_get_component_name(dn, 1);
- if (strcasecmp("cn", users_comp_name) != 0) {
- ret = ENOENT;
- goto done;
- }
-
- users_comp_val = ldb_dn_get_component_val(dn, 1);
- if (strncasecmp("users", (const char *) users_comp_val->data,
- users_comp_val->length) != 0) {
- ret = ENOENT;
- goto done;
- }
-
- /* third component must be 'cn=accounts' */
- acct_comp_name = ldb_dn_get_component_name(dn, 2);
- if (strcasecmp("cn", acct_comp_name) != 0) {
- ret = ENOENT;
- goto done;
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
}
- acct_comp_val = ldb_dn_get_component_val(dn, 2);
- if (strncasecmp("accounts", (const char *) acct_comp_val->data,
- acct_comp_val->length) != 0) {
- ret = ENOENT;
+ ret = ipa_get_rdn(tmp_ctx, sysdb, user_dn, &name, "uid",
+ "cn", "users", "cn", "accounts");
+ if (ret != EOK) {
goto done;
}
- /* value of rdn is username */
user = sysdb_new_attrs(tmp_ctx);
if (user == NULL) {
ret = ENOMEM;
goto done;
}
- rdn_val = ldb_dn_get_rdn_val(dn);
- name = talloc_strndup(user, (const char *)rdn_val->data, rdn_val->length);
- if (name == NULL) {
- ret = ENOMEM;
- goto done;
- }
-
ret = sysdb_attrs_add_string(user, SYSDB_NAME, name);
if (ret != EOK) {
goto done;
--
2.5.0

View File

@ -1,208 +0,0 @@
From 420700d4afe7ca56a8cb707cc81d0494e9296a34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 25 Nov 2015 12:32:25 +0100
Subject: [PATCH 22/49] IPA SUDO: choose between IPA and LDAP schema
This patch implement logic to choose between IPA and LDAP schema. From
this point the sudo support in IPA is removed if sudo search base is
not set specifically, it will be brought back in furter patches.
Resolves:
https://fedorahosted.org/sssd/ticket/1108
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 0f04241fc90f134af0272eb0999e75fb6749b595)
---
src/providers/ipa/ipa_common.c | 38 ---------------
src/providers/ipa/ipa_sudo.c | 108 +++++++++++++++++++++++++++++++++--------
2 files changed, 88 insertions(+), 58 deletions(-)
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index 2940a42cc8d1eeb0dc18289bbe14d0effcc2be91..90be427518b55a22e307249fbd628017ae4600a3 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -311,44 +311,6 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
if (ret != EOK) goto done;
if (NULL == dp_opt_get_string(ipa_opts->id->basic,
- SDAP_SUDO_SEARCH_BASE)) {
-#if 0
- ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_SUDO_SEARCH_BASE,
- dp_opt_get_string(ipa_opts->id->basic,
- SDAP_SEARCH_BASE));
- if (ret != EOK) {
- goto done;
- }
-#else
- /* We don't yet have support for the representation
- * of sudo in IPA. For now, we need to point at the
- * compat tree
- */
- value = talloc_asprintf(tmpctx, "ou=SUDOers,%s", basedn);
- if (!value) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = dp_opt_set_string(ipa_opts->id->basic,
- SDAP_SUDO_SEARCH_BASE,
- value);
- if (ret != EOK) {
- goto done;
- }
-#endif
-
- DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n",
- ipa_opts->id->basic[SDAP_SUDO_SEARCH_BASE].opt_name,
- dp_opt_get_string(ipa_opts->id->basic,
- SDAP_SUDO_SEARCH_BASE));
- }
- ret = sdap_parse_search_base(ipa_opts->id, ipa_opts->id->basic,
- SDAP_SUDO_SEARCH_BASE,
- &ipa_opts->id->sdom->sudo_search_bases);
- if (ret != EOK) goto done;
-
- if (NULL == dp_opt_get_string(ipa_opts->id->basic,
SDAP_NETGROUP_SEARCH_BASE)) {
value = talloc_asprintf(tmpctx, "cn=ng,cn=alt,%s", basedn);
if (!value) {
diff --git a/src/providers/ipa/ipa_sudo.c b/src/providers/ipa/ipa_sudo.c
index 4863aa55904c47ff7d19e3fdb364c06bad5f5678..3d159b3ac0f4ce8f423454506f66f23009eb463f 100644
--- a/src/providers/ipa/ipa_sudo.c
+++ b/src/providers/ipa/ipa_sudo.c
@@ -1,12 +1,8 @@
/*
- SSSD
-
- IPA Provider Initialization functions
-
Authors:
- Lukas Slebodnik <lslebodn@redhat.com>
+ Pavel Březina <pbrezina@redhat.com>
- Copyright (C) 2013 Red Hat
+ Copyright (C) 2015 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
@@ -25,31 +21,103 @@
#include "providers/ipa/ipa_common.h"
#include "providers/ldap/sdap_sudo.h"
+enum sudo_schema {
+ SUDO_SCHEMA_IPA,
+ SUDO_SCHEMA_LDAP
+};
+
+static errno_t
+ipa_sudo_choose_schema(struct dp_option *ipa_opts,
+ struct dp_option *sdap_opts,
+ enum sudo_schema *_schema)
+{
+ TALLOC_CTX *tmp_ctx;
+ char *ipa_search_base;
+ char *search_base;
+ char *basedn;
+ errno_t ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+ return ENOMEM;
+ }
+
+ ret = domain_to_basedn(tmp_ctx, dp_opt_get_string(ipa_opts,
+ IPA_KRB5_REALM), &basedn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to obtain basedn\n");
+ goto done;
+ }
+
+ ipa_search_base = talloc_asprintf(tmp_ctx, "cn=sudo,%s", basedn);
+ if (ipa_search_base == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ search_base = dp_opt_get_string(sdap_opts, SDAP_SUDO_SEARCH_BASE);
+ if (search_base == NULL) {
+ ret = dp_opt_set_string(sdap_opts, SDAP_SUDO_SEARCH_BASE,
+ ipa_search_base);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, "Option %s set to %s\n",
+ sdap_opts[SDAP_SUDO_SEARCH_BASE].opt_name, ipa_search_base);
+
+ search_base = ipa_search_base;
+ }
+
+ /* Use IPA schema only if search base is cn=sudo,$dc. */
+ if (strcmp(ipa_search_base, search_base) == 0) {
+ *_schema = SUDO_SCHEMA_IPA;
+ } else {
+ *_schema = SUDO_SCHEMA_LDAP;
+ }
+
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
int ipa_sudo_init(struct be_ctx *be_ctx,
struct ipa_id_ctx *id_ctx,
struct bet_ops **ops,
void **pvt_data)
{
- int ret;
- struct ipa_options *ipa_options;
- struct sdap_options *ldap_options;
+ enum sudo_schema schema;
+ errno_t ret;
- DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing sudo IPA back end\n");
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Initializing IPA sudo back end\n");
- /*
- * SDAP_SUDO_SEARCH_BASE has already been initialized in
- * function ipa_get_id_options
- */
- ret = sdap_sudo_init(be_ctx, id_ctx->sdap_id_ctx, ops, pvt_data);
+ ret = ipa_sudo_choose_schema(id_ctx->ipa_options->basic,
+ id_ctx->ipa_options->id->basic,
+ &schema);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "Cannot initialize LDAP SUDO [%d]: %s\n",
- ret, strerror(ret));
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to choose sudo schema [%d]: %s\n",
+ ret, sss_strerror(ret));
return ret;
}
- ipa_options = id_ctx->ipa_options;
- ldap_options = id_ctx->sdap_id_ctx->opts;
+ switch (schema) {
+ case SUDO_SCHEMA_IPA:
+ DEBUG(SSSDBG_TRACE_FUNC, "Using IPA schema for sudo\n");
+ break;
+ case SUDO_SCHEMA_LDAP:
+ DEBUG(SSSDBG_TRACE_FUNC, "Using LDAP schema for sudo\n");
+ ret = sdap_sudo_init(be_ctx, id_ctx->sdap_id_ctx, ops, pvt_data);
+ break;
+ }
+
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize sudo provider"
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ return ret;
+ }
- ipa_options->id->sudorule_map = ldap_options->sudorule_map;
return EOK;
}
--
2.5.0

View File

@ -1,169 +0,0 @@
From 3ab86013f8041070c866135b8b2c61ad8f3da40c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 1 Dec 2015 13:10:16 +0100
Subject: [PATCH 23/49] IPA SUDO: Add ipasudorule mapping
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit a2057618f30a3c64bdffb35a2ef3c2ba148c8a03)
---
src/config/etc/sssd.api.d/sssd-ipa.conf | 20 ++++++++++++++++++++
src/db/sysdb_sudo.h | 20 ++++++++++++++++++++
src/providers/ipa/ipa_common.h | 25 +++++++++++++++++++++++++
src/providers/ipa/ipa_opts.c | 24 ++++++++++++++++++++++++
src/providers/ipa/ipa_opts.h | 2 ++
src/providers/ipa/ipa_sudo.c | 1 +
6 files changed, 92 insertions(+)
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index ab712fe55cdac6d247a085aeca5cc82d65966623..0e4e8c00b0fb1fcf9ee9ee82790c28f6c14d26d0 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -234,3 +234,23 @@ ldap_sudorule_runasgroup = str, None, false
ldap_sudorule_notbefore = str, None, false
ldap_sudorule_notafter = str, None, false
ldap_sudorule_order = str, None, false
+ipa_sudorule_object_class = str, None, false
+ipa_sudorule_name = str, None, false
+ipa_sudorule_uuid = str, None, false
+ipa_sudorule_enabled_flag = str, None, false
+ipa_sudorule_option = str, None, false
+ipa_sudorule_runasgroup = str, None, false
+ipa_sudorule_runasgroup = str, None, false
+ipa_sudorule_allowcmd = str, None, false
+ipa_sudorule_denycmd = str, None, false
+ipa_sudorule_host = str, None, false
+ipa_sudorule_user = str, None, false
+ipa_sudorule_notafter = str, None, false
+ipa_sudorule_notbefore = str, None, false
+ipa_sudorule_sudoorder = str, None, false
+ipa_sudorule_cmdcategory = str, None, false
+ipa_sudorule_hostcategory = str, None, false
+ipa_sudorule_usercategory = str, None, false
+ipa_sudorule_runasusercategory = str, None, false
+ipa_sudorule_runasgroupcategory = str, None, false
+ipa_sudorule_entry_usn = str, None, false
diff --git a/src/db/sysdb_sudo.h b/src/db/sysdb_sudo.h
index 6dd9ea7bb8ec947f5beceb89fd27bde156c27c36..cb4bcc236933d60adaba1c6ffcc52fc73f5df064 100644
--- a/src/db/sysdb_sudo.h
+++ b/src/db/sysdb_sudo.h
@@ -46,6 +46,26 @@
#define SYSDB_SUDO_CACHE_AT_NOTAFTER "sudoNotAfter"
#define SYSDB_SUDO_CACHE_AT_ORDER "sudoOrder"
+/* sysdb ipa attributes */
+#define SYSDB_IPA_SUDORULE_OC "ipasudorule"
+#define SYSDB_IPA_SUDORULE_ENABLED "ipaEnabledFlag"
+#define SYSDB_IPA_SUDORULE_OPTION "ipaSudoOpt"
+#define SYSDB_IPA_SUDORULE_RUNASUSER "ipaSudoRunAs"
+#define SYSDB_IPA_SUDORULE_RUNASGROUP "ipaSudoRunAsGroup"
+#define SYSDB_IPA_SUDORULE_ORIGCMD "originalMemberCommand"
+#define SYSDB_IPA_SUDORULE_ALLOWCMD "memberAllowCmd"
+#define SYSDB_IPA_SUDORULE_DENYCMD "memberDenyCmd"
+#define SYSDB_IPA_SUDORULE_HOST "memberHost"
+#define SYSDB_IPA_SUDORULE_USER "memberUser"
+#define SYSDB_IPA_SUDORULE_NOTAFTER "sudoNotAfter"
+#define SYSDB_IPA_SUDORULE_NOTBEFORE "sudoNotBefore"
+#define SYSDB_IPA_SUDORULE_SUDOORDER "sudoOrder"
+#define SYSDB_IPA_SUDORULE_CMDCATEGORY "cmdCategory"
+#define SYSDB_IPA_SUDORULE_HOSTCATEGORY "hostCategory"
+#define SYSDB_IPA_SUDORULE_USERCATEGORY "userCategory"
+#define SYSDB_IPA_SUDORULE_RUNASUSERCATEGORY "ipaSudoRunAsUserCategory"
+#define SYSDB_IPA_SUDORULE_RUNASGROUPCATEGORY "ipaSudoRunAsGroupCategory"
+
/* When constructing a sysdb filter, OR these values to include.. */
#define SYSDB_SUDO_FILTER_NONE 0x00 /* no additional filter */
#define SYSDB_SUDO_FILTER_USERNAME 0x01 /* username */
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index fb36c702bee2e21860d64e2030f6a0c2b85f564e..d5527aeeda27a4684bc51e2d5bc420f9c3165a86 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -133,6 +133,31 @@ enum ipa_override_attrs {
IPA_OPTS_OVERRIDE
};
+enum ipa_sudorule_attrs {
+ IPA_OC_SUDORULE = 0,
+ IPA_AT_SUDORULE_NAME,
+ IPA_AT_SUDORULE_UUID,
+ IPA_AT_SUDORULE_ENABLED,
+ IPA_AT_SUDORULE_OPTION,
+ IPA_AT_SUDORULE_RUNASUSER,
+ IPA_AT_SUDORULE_RUNASGROUP,
+ IPA_AT_SUDORULE_ALLOWCMD,
+ IPA_AT_SUDORULE_DENYCMD,
+ IPA_AT_SUDORULE_HOST,
+ IPA_AT_SUDORULE_USER,
+ IPA_AT_SUDORULE_NOTAFTER,
+ IPA_AT_SUDORULE_NOTBEFORE,
+ IPA_AT_SUDORULE_SUDOORDER,
+ IPA_AT_SUDORULE_CMDCATEGORY,
+ IPA_AT_SUDORULE_HOSTCATEGORY,
+ IPA_AT_SUDORULE_USERCATEGORY,
+ IPA_AT_SUDORULE_RUNASUSERCATEGORY,
+ IPA_AT_SUDORULE_RUNASGROUPCATEGORY,
+ IPA_AT_SUDORULE_ENTRYUSN,
+
+ IPA_OPTS_SUDORULE
+};
+
struct ipa_auth_ctx {
struct krb5_ctx *krb5_auth_ctx;
struct sdap_id_ctx *sdap_id_ctx;
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
index bc983ec32d63c37b6fdf06d6009df9084f82d4bf..25e9a009a142580e40e3bc2034d7b310ff8ae9c5 100644
--- a/src/providers/ipa/ipa_opts.c
+++ b/src/providers/ipa/ipa_opts.c
@@ -335,3 +335,27 @@ struct sdap_attr_map ipa_autofs_entry_map[] = {
{ "ldap_autofs_entry_value", "automountInformation", SYSDB_AUTOFS_ENTRY_VALUE, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
+
+struct sdap_attr_map ipa_sudorule_map[] = {
+ { "ipa_sudorule_object_class", "ipasudorule", SYSDB_IPA_SUDORULE_OC, NULL },
+ { "ipa_sudorule_name", "cn", SYSDB_NAME, NULL },
+ { "ipa_sudorule_uuid", "ipaUniqueID", SYSDB_UUID, NULL },
+ { "ipa_sudorule_enabled_flag", "ipaEnabledFlag", SYSDB_IPA_SUDORULE_ENABLED, NULL },
+ { "ipa_sudorule_option", "ipaSudoOpt", SYSDB_IPA_SUDORULE_OPTION, NULL },
+ { "ipa_sudorule_runasuser", "ipaSudoRunAs", SYSDB_IPA_SUDORULE_RUNASUSER, NULL },
+ { "ipa_sudorule_runasgroup", "ipaSudoRunAsGroup", SYSDB_IPA_SUDORULE_RUNASGROUP, NULL },
+ { "ipa_sudorule_allowcmd", "memberAllowCmd", SYSDB_IPA_SUDORULE_ALLOWCMD, NULL },
+ { "ipa_sudorule_denycmd", "memberDenyCmd", SYSDB_IPA_SUDORULE_DENYCMD, NULL },
+ { "ipa_sudorule_host", "memberHost", SYSDB_IPA_SUDORULE_HOST, NULL },
+ { "ipa_sudorule_user", "memberUser", SYSDB_IPA_SUDORULE_USER, NULL },
+ { "ipa_sudorule_notafter", "sudoNotAfter", SYSDB_IPA_SUDORULE_NOTAFTER, NULL },
+ { "ipa_sudorule_notbefore", "sudoNotBefore", SYSDB_IPA_SUDORULE_NOTBEFORE, NULL },
+ { "ipa_sudorule_sudoorder", "sudoOrder", SYSDB_IPA_SUDORULE_SUDOORDER, NULL },
+ { "ipa_sudorule_cmdcategory", "cmdCategory", SYSDB_IPA_SUDORULE_CMDCATEGORY, NULL },
+ { "ipa_sudorule_hostcategory", "hostCategory", SYSDB_IPA_SUDORULE_HOSTCATEGORY, NULL },
+ { "ipa_sudorule_usercategory", "userCategory", SYSDB_IPA_SUDORULE_USERCATEGORY, NULL },
+ { "ipa_sudorule_runasusercategory", "ipaSudoRunAsUserCategory", SYSDB_IPA_SUDORULE_RUNASUSERCATEGORY, NULL },
+ { "ipa_sudorule_runasgroupcategory", "ipaSudoRunAsGroupCategory", SYSDB_IPA_SUDORULE_RUNASGROUPCATEGORY, NULL },
+ { "ipa_sudorule_entry_usn", "entryUSN", SYSDB_USN, NULL },
+ SDAP_ATTR_MAP_TERMINATOR
+};
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index af12e63d80696d8341a963368e7d3a3694f16812..6d9e52f73ae1b5625c31d73adc67a76f018c3898 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -58,4 +58,6 @@ extern struct sdap_attr_map ipa_autofs_mobject_map[];
extern struct sdap_attr_map ipa_autofs_entry_map[];
+extern struct sdap_attr_map ipa_sudorule_map[];
+
#endif /* IPA_OPTS_H_ */
diff --git a/src/providers/ipa/ipa_sudo.c b/src/providers/ipa/ipa_sudo.c
index 3d159b3ac0f4ce8f423454506f66f23009eb463f..529fb5f0736a883654b60d43d9dcf248af5c8c21 100644
--- a/src/providers/ipa/ipa_sudo.c
+++ b/src/providers/ipa/ipa_sudo.c
@@ -20,6 +20,7 @@
#include "providers/ipa/ipa_common.h"
#include "providers/ldap/sdap_sudo.h"
+#include "db/sysdb_sudo.h"
enum sudo_schema {
SUDO_SCHEMA_IPA,
--
2.5.0

View File

@ -1,93 +0,0 @@
From 71f41c651bd5a0ff966cfef662abefb8588948ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 2 Dec 2015 14:48:18 +0100
Subject: [PATCH 24/49] IPA SUDO: Add ipasudocmdgrp mapping
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit ed8650be18af26b7bf389e1246f7e8cdb363f829)
---
src/config/etc/sssd.api.d/sssd-ipa.conf | 5 +++++
src/db/sysdb_sudo.h | 2 ++
src/providers/ipa/ipa_common.h | 10 ++++++++++
src/providers/ipa/ipa_opts.c | 9 +++++++++
src/providers/ipa/ipa_opts.h | 2 ++
5 files changed, 28 insertions(+)
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 0e4e8c00b0fb1fcf9ee9ee82790c28f6c14d26d0..f46545491439824f2ac3d65d4bbbad7d0b70a42b 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -254,3 +254,8 @@ ipa_sudorule_usercategory = str, None, false
ipa_sudorule_runasusercategory = str, None, false
ipa_sudorule_runasgroupcategory = str, None, false
ipa_sudorule_entry_usn = str, None, false
+ipa_sudocmdgroup_object_class = str, None, false
+ipa_sudocmdgroup_uuid = str, None, false
+ipa_sudocmdgroup_name = str, None, false
+ipa_sudocmdgroup_member = str, None, false
+ipa_sudocmdgroup_entry_usn = str, None, false
diff --git a/src/db/sysdb_sudo.h b/src/db/sysdb_sudo.h
index cb4bcc236933d60adaba1c6ffcc52fc73f5df064..658d0237a16b5d1687bd0bf2ac60d24c91e1b03b 100644
--- a/src/db/sysdb_sudo.h
+++ b/src/db/sysdb_sudo.h
@@ -66,6 +66,8 @@
#define SYSDB_IPA_SUDORULE_RUNASUSERCATEGORY "ipaSudoRunAsUserCategory"
#define SYSDB_IPA_SUDORULE_RUNASGROUPCATEGORY "ipaSudoRunAsGroupCategory"
+#define SYSDB_IPA_SUDOCMDGROUP_OC "ipasudocmdgrp"
+
/* When constructing a sysdb filter, OR these values to include.. */
#define SYSDB_SUDO_FILTER_NONE 0x00 /* no additional filter */
#define SYSDB_SUDO_FILTER_USERNAME 0x01 /* username */
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index d5527aeeda27a4684bc51e2d5bc420f9c3165a86..57d93dd643e27d08802009dbcb8056c05edf76ab 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -158,6 +158,16 @@ enum ipa_sudorule_attrs {
IPA_OPTS_SUDORULE
};
+enum ipa_sudocmdgroup_attrs {
+ IPA_OC_SUDOCMDGROUP = 0,
+ IPA_AT_SUDOCMDGROUP_UUID,
+ IPA_AT_SUDOCMDGROUP_NAME,
+ IPA_AT_SUDOCMDGROUP_MEMBER,
+ IPA_AT_SUDOCMDGROUP_ENTRYUSN,
+
+ IPA_OPTS_SUDOCMDGROUP
+};
+
struct ipa_auth_ctx {
struct krb5_ctx *krb5_auth_ctx;
struct sdap_id_ctx *sdap_id_ctx;
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
index 25e9a009a142580e40e3bc2034d7b310ff8ae9c5..3493984f5db5b0d3ae474858510af61478e4561f 100644
--- a/src/providers/ipa/ipa_opts.c
+++ b/src/providers/ipa/ipa_opts.c
@@ -359,3 +359,12 @@ struct sdap_attr_map ipa_sudorule_map[] = {
{ "ipa_sudorule_entry_usn", "entryUSN", SYSDB_USN, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
+
+struct sdap_attr_map ipa_sudocmdgroup_map[] = {
+ { "ipa_sudocmdgroup_object_class", "ipasudocmdgrp", SYSDB_IPA_SUDOCMDGROUP_OC, NULL },
+ { "ipa_sudocmdgroup_uuid", "ipaUniqueID", SYSDB_UUID, NULL },
+ { "ipa_sudocmdgroup_name", "cn", SYSDB_NAME, NULL },
+ { "ipa_sudocmdgroup_member", "member", SYSDB_MEMBER, NULL },
+ { "ipa_sudocmdgroup_entry_usn", "entryUSN", SYSDB_USN, NULL },
+ SDAP_ATTR_MAP_TERMINATOR
+};
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 6d9e52f73ae1b5625c31d73adc67a76f018c3898..89acea1608743a65c85b1b1c955e4215576fc48b 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -60,4 +60,6 @@ extern struct sdap_attr_map ipa_autofs_entry_map[];
extern struct sdap_attr_map ipa_sudorule_map[];
+extern struct sdap_attr_map ipa_sudocmdgroup_map[];
+
#endif /* IPA_OPTS_H_ */
--
2.5.0

View File

@ -1,91 +0,0 @@
From 0afa6acd1ff34c749f4442233f8e2c6cd8337678 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 2 Dec 2015 15:02:39 +0100
Subject: [PATCH 25/49] IPA SUDO: Add ipasudocmd mapping
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit cc7766c8456653ab5d7dedbf432cb1711a905804)
---
src/config/etc/sssd.api.d/sssd-ipa.conf | 4 ++++
src/db/sysdb_sudo.h | 3 +++
src/providers/ipa/ipa_common.h | 9 +++++++++
src/providers/ipa/ipa_opts.c | 8 ++++++++
src/providers/ipa/ipa_opts.h | 2 ++
5 files changed, 26 insertions(+)
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index f46545491439824f2ac3d65d4bbbad7d0b70a42b..2784a01e7a012f642377ae9c89d1ed03be88c7ae 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -259,3 +259,7 @@ ipa_sudocmdgroup_uuid = str, None, false
ipa_sudocmdgroup_name = str, None, false
ipa_sudocmdgroup_member = str, None, false
ipa_sudocmdgroup_entry_usn = str, None, false
+ipa_sudocmd_object_class = str, None, false
+ipa_sudocmd_uuid = str, None, false
+ipa_sudocmd_sudoCmd = str, None, false
+ipa_sudocmd_memberof = str, None, false
diff --git a/src/db/sysdb_sudo.h b/src/db/sysdb_sudo.h
index 658d0237a16b5d1687bd0bf2ac60d24c91e1b03b..8635e78041687f386ec15d45e5d1d3f1f0551e3d 100644
--- a/src/db/sysdb_sudo.h
+++ b/src/db/sysdb_sudo.h
@@ -68,6 +68,9 @@
#define SYSDB_IPA_SUDOCMDGROUP_OC "ipasudocmdgrp"
+#define SYSDB_IPA_SUDOCMD_OC "ipasudocmd"
+#define SYSDB_IPA_SUDOCMD_SUDOCMD "sudoCmd"
+
/* When constructing a sysdb filter, OR these values to include.. */
#define SYSDB_SUDO_FILTER_NONE 0x00 /* no additional filter */
#define SYSDB_SUDO_FILTER_USERNAME 0x01 /* username */
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index 57d93dd643e27d08802009dbcb8056c05edf76ab..8cb2058fef98fc8eef0d769a6f62882d1da7ae53 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -168,6 +168,15 @@ enum ipa_sudocmdgroup_attrs {
IPA_OPTS_SUDOCMDGROUP
};
+enum ipa_sudocmd_attrs {
+ IPA_OC_SUDOCMD = 0,
+ IPA_AT_SUDOCMD_UUID,
+ IPA_AT_SUDOCMD_CMD,
+ IPA_AT_SUDOCMD_MEMBEROF,
+
+ IPA_OPTS_SUDOCMD
+};
+
struct ipa_auth_ctx {
struct krb5_ctx *krb5_auth_ctx;
struct sdap_id_ctx *sdap_id_ctx;
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
index 3493984f5db5b0d3ae474858510af61478e4561f..725e512352ff40cb4de6daba88efa3b8dfefdc62 100644
--- a/src/providers/ipa/ipa_opts.c
+++ b/src/providers/ipa/ipa_opts.c
@@ -368,3 +368,11 @@ struct sdap_attr_map ipa_sudocmdgroup_map[] = {
{ "ipa_sudocmdgroup_entry_usn", "entryUSN", SYSDB_USN, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
+
+struct sdap_attr_map ipa_sudocmd_map[] = {
+ { "ipa_sudocmd_object_class", "ipasudocmd", SYSDB_IPA_SUDOCMD_OC, NULL },
+ { "ipa_sudocmd_uuid", "ipaUniqueID", SYSDB_UUID, NULL },
+ { "ipa_sudocmd_sudoCmd", "sudoCmd", SYSDB_IPA_SUDOCMD_SUDOCMD, NULL },
+ { "ipa_sudocmd_memberof", "memberOf", SYSDB_MEMBEROF, NULL },
+ SDAP_ATTR_MAP_TERMINATOR
+};
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 89acea1608743a65c85b1b1c955e4215576fc48b..68326b8649a268232394a8fe970d932feb01d46e 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -62,4 +62,6 @@ extern struct sdap_attr_map ipa_sudorule_map[];
extern struct sdap_attr_map ipa_sudocmdgroup_map[];
+extern struct sdap_attr_map ipa_sudocmd_map[];
+
#endif /* IPA_OPTS_H_ */
--
2.5.0

View File

@ -1,191 +0,0 @@
From 17f35039230235f94c58a01ebd037a2634769b0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 25 Nov 2015 13:14:57 +0100
Subject: [PATCH 26/49] IPA SUDO: Implement sudo handler
Resolves:
https://fedorahosted.org/sssd/ticket/XXXX
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 4ddd5591c50e27dffa55f03fbce0dcc85cd50a8b)
---
Makefile.am | 1 +
src/providers/ipa/ipa_sudo.c | 82 ++++++++++++++++++++++++++++++++++++++++++++
src/providers/ipa/ipa_sudo.h | 38 ++++++++++++++++++++
3 files changed, 121 insertions(+)
create mode 100644 src/providers/ipa/ipa_sudo.h
diff --git a/Makefile.am b/Makefile.am
index 59632f59f26f6d113de3398856e2ef0015d4ad16..69905a9112114932e918adff94d0c285c09ed231 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -644,6 +644,7 @@ dist_noinst_HEADERS = \
src/providers/ipa/ipa_opts.h \
src/providers/ipa/ipa_srv.h \
src/providers/ipa/ipa_dn.h \
+ src/providers/ipa/ipa_sudo.h \
src/providers/ad/ad_srv.h \
src/providers/proxy/proxy.h \
src/tools/tools_util.h \
diff --git a/src/providers/ipa/ipa_sudo.c b/src/providers/ipa/ipa_sudo.c
index 529fb5f0736a883654b60d43d9dcf248af5c8c21..e1b0c828806104336f3df9724484a4411b7fef30 100644
--- a/src/providers/ipa/ipa_sudo.c
+++ b/src/providers/ipa/ipa_sudo.c
@@ -18,10 +18,19 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "providers/ipa/ipa_opts.h"
#include "providers/ipa/ipa_common.h"
#include "providers/ldap/sdap_sudo.h"
+#include "providers/ipa/ipa_sudo.h"
#include "db/sysdb_sudo.h"
+static void ipa_sudo_handler(struct be_req *breq);
+
+struct bet_ops ipa_sudo_ops = {
+ .handler = ipa_sudo_handler,
+ .finalize = NULL,
+};
+
enum sudo_schema {
SUDO_SCHEMA_IPA,
SUDO_SCHEMA_LDAP
@@ -85,6 +94,72 @@ done:
return ret;
}
+static int
+ipa_sudo_init_ipa_schema(struct be_ctx *be_ctx,
+ struct ipa_id_ctx *id_ctx,
+ struct bet_ops **ops,
+ void **pvt_data)
+{
+ struct ipa_sudo_ctx *sudo_ctx;
+ errno_t ret;
+
+ sudo_ctx = talloc_zero(be_ctx, struct ipa_sudo_ctx);
+ if (sudo_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ sudo_ctx->id_ctx = id_ctx->sdap_id_ctx;
+ sudo_ctx->ipa_opts = id_ctx->ipa_options;
+ sudo_ctx->sdap_opts = id_ctx->sdap_id_ctx->opts;
+
+ ret = sdap_get_map(sudo_ctx, be_ctx->cdb, be_ctx->conf_path,
+ ipa_sudorule_map, IPA_OPTS_SUDORULE,
+ &sudo_ctx->sudorule_map);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse attribute map "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = sdap_get_map(sudo_ctx, be_ctx->cdb, be_ctx->conf_path,
+ ipa_sudocmdgroup_map, IPA_OPTS_SUDOCMDGROUP,
+ &sudo_ctx->sudocmdgroup_map);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse attribute map "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = sdap_get_map(sudo_ctx, be_ctx->cdb, be_ctx->conf_path,
+ ipa_sudocmd_map, IPA_OPTS_SUDOCMD,
+ &sudo_ctx->sudocmd_map);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse attribute map "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = sdap_parse_search_base(sudo_ctx, sudo_ctx->sdap_opts->basic,
+ SDAP_SUDO_SEARCH_BASE,
+ &sudo_ctx->sudo_sb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Could not parse sudo search base\n");
+ return ret;
+ }
+
+ *ops = &ipa_sudo_ops;
+ *pvt_data = sudo_ctx;
+
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ talloc_free(sudo_ctx);
+ }
+
+ return ret;
+}
+
int ipa_sudo_init(struct be_ctx *be_ctx,
struct ipa_id_ctx *id_ctx,
struct bet_ops **ops,
@@ -107,6 +182,7 @@ int ipa_sudo_init(struct be_ctx *be_ctx,
switch (schema) {
case SUDO_SCHEMA_IPA:
DEBUG(SSSDBG_TRACE_FUNC, "Using IPA schema for sudo\n");
+ ret = ipa_sudo_init_ipa_schema(be_ctx, id_ctx, ops, pvt_data);
break;
case SUDO_SCHEMA_LDAP:
DEBUG(SSSDBG_TRACE_FUNC, "Using LDAP schema for sudo\n");
@@ -122,3 +198,9 @@ int ipa_sudo_init(struct be_ctx *be_ctx,
return EOK;
}
+
+static void
+ipa_sudo_handler(struct be_req *be_req)
+{
+ sdap_handler_done(be_req, DP_ERR_FATAL, ERR_INTERNAL, "Not implemented yet.");
+}
diff --git a/src/providers/ipa/ipa_sudo.h b/src/providers/ipa/ipa_sudo.h
new file mode 100644
index 0000000000000000000000000000000000000000..21251ed3dabfaebdc324c8d06ba8f1a0b82951b1
--- /dev/null
+++ b/src/providers/ipa/ipa_sudo.h
@@ -0,0 +1,38 @@
+/*
+ Authors:
+ Pavel Březina <pbrezina@redhat.com>
+
+ Copyright (C) 2015 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/>.
+*/
+
+#ifndef _IPA_SUDO_H_
+#define _IPA_SUDO_H_
+
+#include "providers/ipa/ipa_common.h"
+
+struct ipa_sudo_ctx {
+ struct sdap_id_ctx *id_ctx;
+ struct ipa_options *ipa_opts;
+ struct sdap_options *sdap_opts;
+
+ /* sudo */
+ struct sdap_attr_map *sudocmdgroup_map;
+ struct sdap_attr_map *sudorule_map;
+ struct sdap_attr_map *sudocmd_map;
+ struct sdap_search_base **sudo_sb;
+};
+
+#endif /* _IPA_SUDO_H_ */
--
2.5.0

File diff suppressed because it is too large Load Diff

View File

@ -1,315 +0,0 @@
From 1f278025259661dbbec6d9d9cca4f4b8ba6decca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 17 Dec 2015 14:00:21 +0100
Subject: [PATCH 28/49] IPA SUDO: Implement rules refresh
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 9630a4614ba4d5f68e967d4e108893550a996f30)
---
src/providers/ipa/ipa_sudo.c | 11 +++
src/providers/ipa/ipa_sudo.h | 11 +++
src/providers/ipa/ipa_sudo_async.c | 12 ++-
src/providers/ipa/ipa_sudo_conversion.c | 2 +-
src/providers/ipa/ipa_sudo_refresh.c | 155 ++++++++++++++++++++++++++++++++
5 files changed, 186 insertions(+), 5 deletions(-)
diff --git a/src/providers/ipa/ipa_sudo.c b/src/providers/ipa/ipa_sudo.c
index 3e73bd30fa86f394b3ef822d59c7b0e539c92ca2..b4633858f8b1eda870dd1014f998bd7215d0bdbf 100644
--- a/src/providers/ipa/ipa_sudo.c
+++ b/src/providers/ipa/ipa_sudo.c
@@ -211,6 +211,7 @@ ipa_sudo_reply(struct tevent_req *req)
{
struct be_sudo_req *sudo_req;
struct be_req *be_req;
+ bool deleted;
int dp_error;
int ret;
@@ -221,6 +222,12 @@ ipa_sudo_reply(struct tevent_req *req)
case BE_REQ_SUDO_FULL:
ret = ipa_sudo_full_refresh_recv(req, &dp_error);
break;
+ case BE_REQ_SUDO_RULES:
+ ret = ipa_sudo_rules_refresh_recv(req, &dp_error, &deleted);
+ if (ret == EOK && deleted == true) {
+ ret = ENOENT;
+ }
+ break;
default:
DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n",
sudo_req->type);
@@ -256,6 +263,10 @@ ipa_sudo_handler(struct be_req *be_req)
case BE_REQ_SUDO_FULL:
req = ipa_sudo_full_refresh_send(be_req, be_ctx->ev, sudo_ctx);
break;
+ case BE_REQ_SUDO_RULES:
+ req = ipa_sudo_rules_refresh_send(be_req, be_ctx->ev, sudo_ctx,
+ sudo_req->rules);
+ break;
default:
DEBUG(SSSDBG_CRIT_FAILURE, "Invalid request type: %d\n",
sudo_req->type);
diff --git a/src/providers/ipa/ipa_sudo.h b/src/providers/ipa/ipa_sudo.h
index 1ef50a7f352182bdc6607b2fd8ee3d72ccab391d..9dd72948732f4b6e19f4a6546128c5319cd97bda 100644
--- a/src/providers/ipa/ipa_sudo.h
+++ b/src/providers/ipa/ipa_sudo.h
@@ -50,6 +50,11 @@ int
ipa_sudo_full_refresh_recv(struct tevent_req *req,
int *dp_error);
+int
+ipa_sudo_rules_refresh_recv(struct tevent_req *req,
+ int *dp_error,
+ bool *deleted);
+
struct tevent_req *
ipa_sudo_refresh_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
@@ -57,6 +62,12 @@ ipa_sudo_refresh_send(TALLOC_CTX *mem_ctx,
const char *search_filter,
const char *delete_filter);
+struct tevent_req *
+ipa_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct ipa_sudo_ctx *sudo_ctx,
+ char **rules);
+
errno_t
ipa_sudo_refresh_recv(struct tevent_req *req,
int *dp_error,
diff --git a/src/providers/ipa/ipa_sudo_async.c b/src/providers/ipa/ipa_sudo_async.c
index 9ddda1b41a0b3c6ceb33e6d665749948ae835a97..cea85cdbfc21598164557b70a7055fd4b786ba8a 100644
--- a/src/providers/ipa/ipa_sudo_async.c
+++ b/src/providers/ipa/ipa_sudo_async.c
@@ -140,6 +140,7 @@ struct ipa_sudo_fetch_state {
struct sdap_options *sdap_opts;
struct ipa_hostinfo *host;
struct sdap_handle *sh;
+ const char *search_filter;
struct sdap_attr_map *map_cmdgroup;
struct sdap_attr_map *map_rule;
@@ -169,7 +170,8 @@ ipa_sudo_fetch_send(TALLOC_CTX *mem_ctx,
struct sdap_attr_map *map_group,
struct sdap_attr_map *map_host,
struct sdap_attr_map *map_hostgroup,
- struct sdap_handle *sh)
+ struct sdap_handle *sh,
+ const char *search_filter)
{
struct ipa_sudo_fetch_state *state = NULL;
struct tevent_req *req = NULL;
@@ -188,6 +190,7 @@ ipa_sudo_fetch_send(TALLOC_CTX *mem_ctx,
state->sdap_opts = sudo_ctx->sdap_opts;
state->host = host;
state->sh = sh;
+ state->search_filter = search_filter == NULL ? "" : search_filter;
state->map_cmdgroup = sudo_ctx->sudocmdgroup_map;
state->map_rule = sudo_ctx->sudorule_map;
@@ -241,10 +244,10 @@ ipa_sudo_fetch_rules(struct tevent_req *req)
return ENOMEM;
}
- filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=TRUE)%s)",
+ filter = talloc_asprintf(state, "(&(objectClass=%s)(%s=TRUE)%s%s)",
map[IPA_OC_SUDORULE].name,
map[IPA_AT_SUDORULE_ENABLED].name,
- host_filter);
+ host_filter, state->search_filter);
talloc_zfree(host_filter);
if (filter == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n");
@@ -678,7 +681,8 @@ ipa_sudo_refresh_host_done(struct tevent_req *subreq)
state->sdap_opts->user_map,
state->sdap_opts->group_map,
state->ipa_opts->host_map,
- state->ipa_opts->hostgroup_map, state->sh);
+ state->ipa_opts->hostgroup_map, state->sh,
+ state->search_filter);
if (subreq == NULL) {
state->dp_error = DP_ERR_FATAL;
tevent_req_error(req, ENOMEM);
diff --git a/src/providers/ipa/ipa_sudo_conversion.c b/src/providers/ipa/ipa_sudo_conversion.c
index 2f28f837e62b42406ddda25b3f63832c1abb950d..195e40f248e15756a224335208276f6f7a646cd0 100644
--- a/src/providers/ipa/ipa_sudo_conversion.c
+++ b/src/providers/ipa/ipa_sudo_conversion.c
@@ -1124,7 +1124,7 @@ ipa_sudo_conv_result(TALLOC_CTX *mem_ctx,
}
if (ctx.ret != EOK) {
- DEBUG(SSSDBG_CRIT_FAILURE, "Unable to expand command grousp "
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to expand command groups "
"[%d]: %s\n", ctx.ret, sss_strerror(ctx.ret));
return ctx.ret;
}
diff --git a/src/providers/ipa/ipa_sudo_refresh.c b/src/providers/ipa/ipa_sudo_refresh.c
index 6fb8f66af607440ddcbb266c0b049ed99bf235b9..f1b99c0de96dd2226eb3181ce44e54c019139c6e 100644
--- a/src/providers/ipa/ipa_sudo_refresh.c
+++ b/src/providers/ipa/ipa_sudo_refresh.c
@@ -141,6 +141,161 @@ ipa_sudo_full_refresh_recv(struct tevent_req *req,
return EOK;
}
+struct ipa_sudo_rules_refresh_state {
+ size_t num_rules;
+ int dp_error;
+ bool deleted;
+};
+
+static void ipa_sudo_rules_refresh_done(struct tevent_req *subreq);
+
+struct tevent_req *
+ipa_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct ipa_sudo_ctx *sudo_ctx,
+ char **rules)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct ipa_sudo_rules_refresh_state *state;
+ struct tevent_req *subreq;
+ struct tevent_req *req;
+ char *search_filter;
+ char *delete_filter;
+ char *safe_rule;
+ errno_t ret;
+ int i;
+
+ req = tevent_req_create(mem_ctx, &state, struct ipa_sudo_rules_refresh_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
+ return NULL;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ if (rules == NULL || rules[0] == NULL) {
+ state->dp_error = DP_ERR_OK;
+ state->num_rules = 0;
+ state->deleted = false;
+ ret = EOK;
+ goto immediately;
+ }
+
+ search_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */
+ delete_filter = talloc_zero(tmp_ctx, char); /* assign to tmp_ctx */
+
+ /* Download only selected rules from LDAP. */
+ /* Remove all selected rules from cache. */
+ for (i = 0; rules[i] != NULL; i++) {
+ ret = sss_filter_sanitize(tmp_ctx, rules[i], &safe_rule);
+ if (ret != EOK) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ search_filter = talloc_asprintf_append_buffer(search_filter, "(%s=%s)",
+ sudo_ctx->sudorule_map[IPA_AT_SUDORULE_NAME].name,
+ safe_rule);
+ if (search_filter == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ delete_filter = talloc_asprintf_append_buffer(delete_filter, "(%s=%s)",
+ SYSDB_NAME, safe_rule);
+ if (delete_filter == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+ }
+
+ state->num_rules = i;
+
+ search_filter = talloc_asprintf(tmp_ctx, "(|%s)", search_filter);
+ if (search_filter == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ delete_filter = talloc_asprintf(tmp_ctx, "(&(%s=%s)(|%s))",
+ SYSDB_OBJECTCLASS, SYSDB_SUDO_CACHE_OC,
+ delete_filter);
+ if (delete_filter == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ subreq = ipa_sudo_refresh_send(req, ev, sudo_ctx, search_filter,
+ delete_filter);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ tevent_req_set_callback(subreq, ipa_sudo_rules_refresh_done, req);
+
+ ret = EOK;
+
+immediately:
+ talloc_free(tmp_ctx);
+
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ tevent_req_post(req, ev);
+ }
+
+ return req;
+}
+
+static void
+ipa_sudo_rules_refresh_done(struct tevent_req *subreq)
+{
+ struct ipa_sudo_rules_refresh_state *state;
+ struct tevent_req *req = NULL;
+ size_t downloaded_rules_num;
+ int ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct ipa_sudo_rules_refresh_state);
+
+ ret = ipa_sudo_refresh_recv(subreq, &state->dp_error, &downloaded_rules_num);
+ talloc_zfree(subreq);
+ if (ret != EOK || state->dp_error != DP_ERR_OK) {
+ goto done;
+ }
+
+ state->deleted = downloaded_rules_num != state->num_rules ? true : false;
+
+done:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+int
+ipa_sudo_rules_refresh_recv(struct tevent_req *req,
+ int *dp_error,
+ bool *deleted)
+{
+ struct ipa_sudo_rules_refresh_state *state;
+ state = tevent_req_data(req, struct ipa_sudo_rules_refresh_state);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ *dp_error = state->dp_error;
+ *deleted = state->deleted;
+
+ return EOK;
+}
+
static struct tevent_req *
ipa_sudo_ptask_full_refresh_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
--
2.5.0

View File

@ -1,138 +0,0 @@
From 318bdcab400cbe714115e945d016c81037eef18c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 18 Dec 2015 12:34:21 +0100
Subject: [PATCH 29/49] IPA SUDO: Remember USN
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit d06cc0974e59cd6cf1da45cc8c60d6e822b731c2)
---
src/providers/ipa/ipa_sudo_async.c | 50 ++++++++++++++++++++++++++++++++++++--
1 file changed, 48 insertions(+), 2 deletions(-)
diff --git a/src/providers/ipa/ipa_sudo_async.c b/src/providers/ipa/ipa_sudo_async.c
index cea85cdbfc21598164557b70a7055fd4b786ba8a..d52b97da17337b224c4be4b4fb65b0a99000e4b6 100644
--- a/src/providers/ipa/ipa_sudo_async.c
+++ b/src/providers/ipa/ipa_sudo_async.c
@@ -23,6 +23,7 @@
#include <dhash.h>
#include "providers/ldap/sdap_ops.h"
+#include "providers/ldap/sdap_sudo_shared.h"
#include "providers/ipa/ipa_common.h"
#include "providers/ipa/ipa_hosts.h"
#include "providers/ipa/ipa_sudo.h"
@@ -133,6 +134,32 @@ fail:
return NULL;
}
+static errno_t
+ipa_sudo_highest_usn(TALLOC_CTX *mem_ctx,
+ struct sysdb_attrs **attrs,
+ size_t num_attrs,
+ char **current_usn)
+{
+ errno_t ret;
+ char *usn;
+
+ ret = sysdb_get_highest_usn(mem_ctx, attrs, num_attrs, &usn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get highest USN [%d]: %s\n",
+ ret, sss_strerror(ret));
+ return ret;
+ }
+
+ if (sysdb_compare_usn(usn, *current_usn) > 0) {
+ talloc_free(*current_usn);
+ *current_usn = usn;
+ return EOK;
+ }
+
+ talloc_free(usn);
+ return EOK;
+}
+
struct ipa_sudo_fetch_state {
struct tevent_context *ev;
struct sysdb_ctx *sysdb;
@@ -150,6 +177,7 @@ struct ipa_sudo_fetch_state {
struct ipa_sudo_conv *conv;
struct sysdb_attrs **rules;
size_t num_rules;
+ char *usn;
};
static errno_t ipa_sudo_fetch_rules(struct tevent_req *req);
@@ -292,6 +320,11 @@ ipa_sudo_fetch_rules_done(struct tevent_req *subreq)
goto done;
}
+ ret = ipa_sudo_highest_usn(state, attrs, num_attrs, &state->usn);
+ if (ret != EOK) {
+ goto done;
+ }
+
ret = ipa_sudo_fetch_cmdgroups(req);
done:
@@ -366,6 +399,11 @@ ipa_sudo_fetch_cmdgroups_done(struct tevent_req *subreq)
goto done;
}
+ ret = ipa_sudo_highest_usn(state, attrs, num_attrs, &state->usn);
+ if (ret != EOK) {
+ goto done;
+ }
+
ret = ipa_sudo_fetch_cmds(req);
done:
@@ -482,7 +520,8 @@ static errno_t
ipa_sudo_fetch_recv(TALLOC_CTX *mem_ctx,
struct tevent_req *req,
struct sysdb_attrs ***_rules,
- size_t *_num_rules)
+ size_t *_num_rules,
+ char **_usn)
{
struct ipa_sudo_fetch_state *state = NULL;
state = tevent_req_data(req, struct ipa_sudo_fetch_state);
@@ -491,6 +530,7 @@ ipa_sudo_fetch_recv(TALLOC_CTX *mem_ctx,
*_rules = talloc_steal(mem_ctx, state->rules);
*_num_rules = state->num_rules;
+ *_usn = talloc_steal(mem_ctx, state->usn);
return EOK;
}
@@ -697,6 +737,7 @@ ipa_sudo_refresh_done(struct tevent_req *subreq)
{
struct ipa_sudo_refresh_state *state;
struct tevent_req *req;
+ char *usn = NULL;
bool in_transaction = false;
errno_t sret;
int ret;
@@ -704,7 +745,8 @@ ipa_sudo_refresh_done(struct tevent_req *subreq)
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct ipa_sudo_refresh_state);
- ret = ipa_sudo_fetch_recv(state, subreq, &state->rules, &state->num_rules);
+ ret = ipa_sudo_fetch_recv(state, subreq, &state->rules,
+ &state->num_rules, &usn);
talloc_zfree(subreq);
ret = sdap_id_op_done(state->sdap_op, ret, &state->dp_error);
@@ -745,6 +787,10 @@ ipa_sudo_refresh_done(struct tevent_req *subreq)
}
in_transaction = false;
+ if (usn != NULL) {
+ sdap_sudo_set_usn(state->sudo_ctx->id_ctx->srv_opts, usn);
+ }
+
DEBUG(SSSDBG_TRACE_FUNC, "Sudo rules are successfully stored in cache\n");
done:
--
2.5.0

View File

@ -1,80 +0,0 @@
From da594641c3bb8718808205c20f0a4e8f96e80d71 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 5 Jan 2016 11:17:38 +0100
Subject: [PATCH 30/49] SDAP: Add sdap_or_filters
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit ad5a48c4947183fda49308259e3411d17a8b0a13)
---
src/providers/ldap/ldap_common.h | 4 ++++
src/providers/ldap/sdap_utils.c | 30 +++++++++++++++++++++++-------
2 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index e5fee51e742a69d8876f2829f75b2af5f020ef6f..bdd02d8221850b8baef746cc1f28a7c8f8569924 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -264,6 +264,10 @@ errno_t list_missing_attrs(TALLOC_CTX *mem_ctx,
bool sdap_is_secure_uri(const char *uri);
+char *sdap_or_filters(TALLOC_CTX *mem_ctx,
+ const char *base_filter,
+ const char *extra_filter);
+
char *sdap_combine_filters(TALLOC_CTX *mem_ctx,
const char *base_filter,
const char *extra_filter);
diff --git a/src/providers/ldap/sdap_utils.c b/src/providers/ldap/sdap_utils.c
index 47921b8768b9c4c4b2d40a5eb28e28bf48238210..347206c21286ea1a491a7b9447a179694ded9b9b 100644
--- a/src/providers/ldap/sdap_utils.c
+++ b/src/providers/ldap/sdap_utils.c
@@ -149,9 +149,11 @@ errno_t deref_string_to_val(const char *str, int *val)
return EOK;
}
-char *sdap_combine_filters(TALLOC_CTX *mem_ctx,
- const char *base_filter,
- const char *extra_filter)
+static char *
+sdap_combine_filters_ex(TALLOC_CTX *mem_ctx,
+ char operator,
+ const char *base_filter,
+ const char *extra_filter)
{
char *filter = NULL;
@@ -162,12 +164,26 @@ char *sdap_combine_filters(TALLOC_CTX *mem_ctx,
}
if (extra_filter[0] == '(') {
- filter = talloc_asprintf(mem_ctx, "(&%s%s)",
- base_filter, extra_filter);
+ filter = talloc_asprintf(mem_ctx, "(%c%s%s)",
+ operator, base_filter, extra_filter);
} else {
- filter = talloc_asprintf(mem_ctx, "(&%s(%s))",
- base_filter, extra_filter);
+ filter = talloc_asprintf(mem_ctx, "(%c%s(%s))",
+ operator, base_filter, extra_filter);
}
return filter; /* NULL or not */
}
+
+char *sdap_or_filters(TALLOC_CTX *mem_ctx,
+ const char *base_filter,
+ const char *extra_filter)
+{
+ return sdap_combine_filters_ex(mem_ctx, '|', base_filter, extra_filter);
+}
+
+char *sdap_combine_filters(TALLOC_CTX *mem_ctx,
+ const char *base_filter,
+ const char *extra_filter)
+{
+ return sdap_combine_filters_ex(mem_ctx, '&', base_filter, extra_filter);
+}
--
2.5.0

View File

@ -1,610 +0,0 @@
From 5edf5c55bb259ac29454493d06097c5fab8a2199 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Fri, 18 Dec 2015 13:05:41 +0100
Subject: [PATCH 31/49] IPA SUDO: Implement smart refresh
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit cc7f9b639144183eb4f8bd86e5bed077da7d4e35)
---
src/providers/ipa/ipa_sudo.h | 1 +
src/providers/ipa/ipa_sudo_async.c | 312 ++++++++++++++++++++++++++++++++++-
src/providers/ipa/ipa_sudo_refresh.c | 132 ++++++++++++++-
3 files changed, 438 insertions(+), 7 deletions(-)
diff --git a/src/providers/ipa/ipa_sudo.h b/src/providers/ipa/ipa_sudo.h
index 9dd72948732f4b6e19f4a6546128c5319cd97bda..81ada14e46550fab815a7df262abd0b5fa11afd7 100644
--- a/src/providers/ipa/ipa_sudo.h
+++ b/src/providers/ipa/ipa_sudo.h
@@ -59,6 +59,7 @@ struct tevent_req *
ipa_sudo_refresh_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct ipa_sudo_ctx *sudo_ctx,
+ const char *cmdgroups_filter,
const char *search_filter,
const char *delete_filter);
diff --git a/src/providers/ipa/ipa_sudo_async.c b/src/providers/ipa/ipa_sudo_async.c
index d52b97da17337b224c4be4b4fb65b0a99000e4b6..79e69ce962fd5cc2df0e9aac10a5469ffd73c6be 100644
--- a/src/providers/ipa/ipa_sudo_async.c
+++ b/src/providers/ipa/ipa_sudo_async.c
@@ -160,14 +160,217 @@ ipa_sudo_highest_usn(TALLOC_CTX *mem_ctx,
return EOK;
}
+static errno_t
+ipa_sudo_assoc_rules_filter(TALLOC_CTX *mem_ctx,
+ struct sysdb_attrs **cmdgroups,
+ size_t num_cmdgroups,
+ char **_filter)
+{
+ TALLOC_CTX *tmp_ctx;
+ const char *origdn;
+ char *sanitized;
+ char *filter;
+ errno_t ret;
+ size_t i;
+
+ if (num_cmdgroups == 0) {
+ return ENOENT;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ filter = talloc_strdup(tmp_ctx, "");
+ if (filter == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (i = 0; i < num_cmdgroups; i++) {
+ ret = sysdb_attrs_get_string(cmdgroups[i], SYSDB_ORIG_DN, &origdn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get original dn [%d]: %s\n",
+ ret, sss_strerror(ret));
+ ret = ERR_INTERNAL;
+ goto done;
+ }
+
+ ret = sss_filter_sanitize(tmp_ctx, origdn, &sanitized);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ filter = talloc_asprintf_append(filter, "(%s=%s)",
+ SYSDB_IPA_SUDORULE_ORIGCMD, sanitized);
+ if (filter == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ filter = talloc_asprintf(tmp_ctx, "(&(objectClass=%s)(|%s)))",
+ SYSDB_SUDO_CACHE_OC, filter);
+ if (filter == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ *_filter = talloc_steal(mem_ctx, filter);
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+static errno_t
+ipa_sudo_assoc_rules(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ struct sysdb_attrs **cmdgroups,
+ size_t num_cmdgroups,
+ struct sysdb_attrs ***_rules,
+ size_t *_num_rules)
+{
+ TALLOC_CTX *tmp_ctx;
+ const char *attrs[] = {SYSDB_NAME, NULL};
+ struct sysdb_attrs **rules;
+ struct ldb_message **msgs;
+ size_t num_rules;
+ char *filter;
+ errno_t ret;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = ipa_sudo_assoc_rules_filter(tmp_ctx, cmdgroups,
+ num_cmdgroups, &filter);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sysdb_search_custom(tmp_ctx, domain, filter,
+ SUDORULE_SUBDIR, attrs,
+ &num_rules, &msgs);
+ if (ret == ENOENT) {
+ *_rules = NULL;
+ *_num_rules = 0;
+ ret = EOK;
+ goto done;
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Error looking up sudo rules [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = sysdb_msg2attrs(tmp_ctx, num_rules, msgs, &rules);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Could not convert ldb message to "
+ "sysdb_attrs [%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ *_rules = talloc_steal(mem_ctx, rules);
+ *_num_rules = num_rules;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+static errno_t
+ipa_sudo_filter_rules_bycmdgroups(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ struct sysdb_attrs **cmdgroups,
+ size_t num_cmdgroups,
+ struct sdap_attr_map *map_rule,
+ char **_filter)
+{
+ TALLOC_CTX *tmp_ctx;
+ struct sysdb_attrs **rules;
+ size_t num_rules;
+ const char *name;
+ char *sanitized;
+ char *filter;
+ errno_t ret;
+ size_t i;
+
+ if (num_cmdgroups == 0) {
+ *_filter = NULL;
+ return EOK;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = ipa_sudo_assoc_rules(tmp_ctx, domain, cmdgroups, num_cmdgroups,
+ &rules, &num_rules);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (num_rules == 0) {
+ *_filter = NULL;
+ ret = EOK;
+ goto done;
+ }
+
+ filter = talloc_strdup(tmp_ctx, "");
+ if (filter == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (i = 0; i < num_rules; i++) {
+ ret = sysdb_attrs_get_string(rules[i], SYSDB_NAME, &name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get name [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = sss_filter_sanitize(tmp_ctx, name, &sanitized);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ filter = talloc_asprintf_append(filter, "(%s=%s)",
+ map_rule[IPA_AT_SUDORULE_NAME].name, sanitized);
+ if (filter == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ filter = talloc_asprintf(tmp_ctx, "(|%s)", filter);
+ if (filter == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ *_filter = talloc_steal(mem_ctx, filter);
+ ret = EOK;
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
struct ipa_sudo_fetch_state {
struct tevent_context *ev;
struct sysdb_ctx *sysdb;
+ struct sss_domain_info *domain;
struct ipa_sudo_ctx *sudo_ctx;
struct sdap_options *sdap_opts;
struct ipa_hostinfo *host;
struct sdap_handle *sh;
const char *search_filter;
+ const char *cmdgroups_filter;
struct sdap_attr_map *map_cmdgroup;
struct sdap_attr_map *map_rule;
@@ -180,6 +383,8 @@ struct ipa_sudo_fetch_state {
char *usn;
};
+static errno_t ipa_sudo_fetch_addtl_cmdgroups(struct tevent_req *req);
+static void ipa_sudo_fetch_addtl_cmdgroups_done(struct tevent_req *subreq);
static errno_t ipa_sudo_fetch_rules(struct tevent_req *req);
static void ipa_sudo_fetch_rules_done(struct tevent_req *subreq);
static errno_t ipa_sudo_fetch_cmdgroups(struct tevent_req *req);
@@ -191,6 +396,7 @@ static void ipa_sudo_fetch_done(struct tevent_req *req);
static struct tevent_req *
ipa_sudo_fetch_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
+ struct sss_domain_info *domain,
struct sysdb_ctx *sysdb,
struct ipa_sudo_ctx *sudo_ctx,
struct ipa_hostinfo *host,
@@ -199,6 +405,7 @@ ipa_sudo_fetch_send(TALLOC_CTX *mem_ctx,
struct sdap_attr_map *map_host,
struct sdap_attr_map *map_hostgroup,
struct sdap_handle *sh,
+ const char *cmdgroups_filter,
const char *search_filter)
{
struct ipa_sudo_fetch_state *state = NULL;
@@ -214,11 +421,13 @@ ipa_sudo_fetch_send(TALLOC_CTX *mem_ctx,
state->ev = ev;
state->sysdb = sysdb;
+ state->domain = domain;
state->sudo_ctx = sudo_ctx;
state->sdap_opts = sudo_ctx->sdap_opts;
state->host = host;
state->sh = sh;
state->search_filter = search_filter == NULL ? "" : search_filter;
+ state->cmdgroups_filter = cmdgroups_filter;
state->map_cmdgroup = sudo_ctx->sudocmdgroup_map;
state->map_rule = sudo_ctx->sudorule_map;
@@ -234,7 +443,15 @@ ipa_sudo_fetch_send(TALLOC_CTX *mem_ctx,
goto immediately;
}
- ret = ipa_sudo_fetch_rules(req);
+ if (state->cmdgroups_filter != NULL) {
+ /* We need to fetch additional cmdgroups that may not be revealed
+ * during normal search. Such as when using entryUSN filter in smart
+ * refresh, some command groups may have change but none rule was
+ * modified but we need to fetch associated rules anyway. */
+ ret = ipa_sudo_fetch_addtl_cmdgroups(req);
+ } else {
+ ret = ipa_sudo_fetch_rules(req);
+ }
if (ret != EAGAIN) {
goto immediately;
}
@@ -253,6 +470,87 @@ immediately:
}
static errno_t
+ipa_sudo_fetch_addtl_cmdgroups(struct tevent_req *req)
+{
+ struct ipa_sudo_fetch_state *state;
+ struct tevent_req *subreq;
+ struct sdap_attr_map *map;
+ char *filter;
+
+ DEBUG(SSSDBG_TRACE_FUNC, "About to fetch additional command groups\n");
+
+ state = tevent_req_data(req, struct ipa_sudo_fetch_state);
+ map = state->map_cmdgroup;
+
+ filter = talloc_asprintf(state, "(&(objectClass=%s)%s)",
+ map[IPA_OC_SUDOCMDGROUP].name,
+ state->cmdgroups_filter);
+ if (filter == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build filter\n");
+ return ENOMEM;
+ }
+
+ subreq = sdap_search_bases_send(state, state->ev, state->sdap_opts,
+ state->sh, state->sudo_sb, map, true, 0,
+ filter, NULL);
+ if (subreq == NULL) {
+ return ENOMEM;
+ }
+
+ tevent_req_set_callback(subreq, ipa_sudo_fetch_addtl_cmdgroups_done, req);
+ return EAGAIN;
+}
+
+static void
+ipa_sudo_fetch_addtl_cmdgroups_done(struct tevent_req *subreq)
+{
+ struct ipa_sudo_fetch_state *state = NULL;
+ struct tevent_req *req = NULL;
+ struct sysdb_attrs **attrs;
+ size_t num_attrs;
+ char *filter;
+ errno_t ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct ipa_sudo_fetch_state);
+
+ ret = sdap_search_bases_recv(subreq, state, &num_attrs, &attrs);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ DEBUG(SSSDBG_IMPORTANT_INFO, "Received %zu additional command groups\n",
+ num_attrs);
+
+ ret = ipa_sudo_filter_rules_bycmdgroups(state, state->domain, attrs,
+ num_attrs, state->map_rule,
+ &filter);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to construct rules filter "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ state->search_filter = sdap_or_filters(state, state->search_filter, filter);
+ if (state->search_filter == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = ipa_sudo_fetch_rules(req);
+
+done:
+ if (ret == EOK) {
+ ipa_sudo_fetch_done(req);
+ } else if (ret != EAGAIN) {
+ tevent_req_error(req, ret);
+ }
+
+ return;
+}
+
+static errno_t
ipa_sudo_fetch_rules(struct tevent_req *req)
{
struct ipa_sudo_fetch_state *state;
@@ -543,6 +841,7 @@ struct ipa_sudo_refresh_state {
struct ipa_sudo_ctx *sudo_ctx;
struct ipa_options *ipa_opts;
struct sdap_options *sdap_opts;
+ const char *cmdgroups_filter;
const char *search_filter;
const char *delete_filter;
@@ -563,6 +862,7 @@ struct tevent_req *
ipa_sudo_refresh_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct ipa_sudo_ctx *sudo_ctx,
+ const char *cmdgroups_filter,
const char *search_filter,
const char *delete_filter)
{
@@ -592,6 +892,12 @@ ipa_sudo_refresh_send(TALLOC_CTX *mem_ctx,
goto immediately;
}
+ state->cmdgroups_filter = talloc_strdup(state, cmdgroups_filter);
+ if (cmdgroups_filter != NULL && state->cmdgroups_filter == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
state->search_filter = talloc_strdup(state, search_filter);
if (search_filter != NULL && state->search_filter == NULL) {
ret = ENOMEM;
@@ -716,13 +1022,13 @@ ipa_sudo_refresh_host_done(struct tevent_req *subreq)
return;
}
- subreq = ipa_sudo_fetch_send(state, state->ev, state->sysdb,
+ subreq = ipa_sudo_fetch_send(state, state->ev, state->domain, state->sysdb,
state->sudo_ctx, host,
state->sdap_opts->user_map,
state->sdap_opts->group_map,
state->ipa_opts->host_map,
state->ipa_opts->hostgroup_map, state->sh,
- state->search_filter);
+ state->cmdgroups_filter, state->search_filter);
if (subreq == NULL) {
state->dp_error = DP_ERR_FATAL;
tevent_req_error(req, ENOMEM);
diff --git a/src/providers/ipa/ipa_sudo_refresh.c b/src/providers/ipa/ipa_sudo_refresh.c
index f1b99c0de96dd2226eb3181ce44e54c019139c6e..bdde4a0026f224898a4987476f49122ea92a6052 100644
--- a/src/providers/ipa/ipa_sudo_refresh.c
+++ b/src/providers/ipa/ipa_sudo_refresh.c
@@ -69,7 +69,8 @@ ipa_sudo_full_refresh_send(TALLOC_CTX *mem_ctx,
DEBUG(SSSDBG_TRACE_FUNC, "Issuing a full refresh of sudo rules\n");
- subreq = ipa_sudo_refresh_send(state, ev, sudo_ctx, NULL, delete_filter);
+ subreq = ipa_sudo_refresh_send(state, ev, sudo_ctx,
+ NULL, NULL, delete_filter);
if (subreq == NULL) {
ret = ENOMEM;
goto immediately;
@@ -141,6 +142,129 @@ ipa_sudo_full_refresh_recv(struct tevent_req *req,
return EOK;
}
+struct ipa_sudo_smart_refresh_state {
+ int dp_error;
+};
+
+static void ipa_sudo_smart_refresh_done(struct tevent_req *subreq);
+
+static struct tevent_req *
+ipa_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct ipa_sudo_ctx *sudo_ctx)
+{
+ struct sdap_server_opts *srv_opts = sudo_ctx->id_ctx->srv_opts;
+ struct ipa_sudo_smart_refresh_state *state;
+ struct tevent_req *subreq;
+ struct tevent_req *req;
+ char *cmdgroups_filter;
+ char *search_filter;
+ const char *usn;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct ipa_sudo_smart_refresh_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
+ return NULL;
+ }
+
+ if (!sudo_ctx->full_refresh_done
+ || srv_opts == NULL || srv_opts->max_sudo_value == NULL) {
+ /* Perform full refresh first */
+ DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, "
+ "waiting for full refresh!\n");
+ ret = EINVAL;
+ goto immediately;
+ }
+
+ /* Download all rules from LDAP that are newer than usn */
+ usn = srv_opts->max_sudo_value;
+
+ cmdgroups_filter = talloc_asprintf(state,
+ "(&(%s>=%s)(!(%s=%s)))",
+ sudo_ctx->sudocmdgroup_map[IPA_AT_SUDOCMDGROUP_ENTRYUSN].name, usn,
+ sudo_ctx->sudocmdgroup_map[IPA_AT_SUDOCMDGROUP_ENTRYUSN].name, usn);
+ if (cmdgroups_filter == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ search_filter = talloc_asprintf(state,
+ "(&(%s>=%s)(!(%s=%s)))",
+ sudo_ctx->sudorule_map[IPA_AT_SUDORULE_ENTRYUSN].name, usn,
+ sudo_ctx->sudorule_map[IPA_AT_SUDORULE_ENTRYUSN].name, usn);
+ if (search_filter == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ /* Do not remove any rules that are already in the sysdb. */
+
+ DEBUG(SSSDBG_TRACE_FUNC, "Issuing a smart refresh of sudo rules "
+ "(USN > %s)\n", usn);
+
+ subreq = ipa_sudo_refresh_send(state, ev, sudo_ctx, cmdgroups_filter,
+ search_filter, NULL);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ tevent_req_set_callback(subreq, ipa_sudo_smart_refresh_done, req);
+
+ return req;
+
+immediately:
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
+ tevent_req_post(req, ev);
+
+ return req;
+}
+
+static void ipa_sudo_smart_refresh_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = NULL;
+ struct ipa_sudo_smart_refresh_state *state = NULL;
+ int ret;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req, struct ipa_sudo_smart_refresh_state);
+
+ ret = ipa_sudo_refresh_recv(subreq, &state->dp_error, NULL);
+ talloc_zfree(subreq);
+ if (ret != EOK || state->dp_error != DP_ERR_OK) {
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, "Successful smart refresh of sudo rules\n");
+
+done:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+}
+
+int ipa_sudo_smart_refresh_recv(struct tevent_req *req,
+ int *dp_error)
+{
+ struct ipa_sudo_smart_refresh_state *state = NULL;
+ state = tevent_req_data(req, struct ipa_sudo_smart_refresh_state);
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ *dp_error = state->dp_error;
+
+ return EOK;
+}
+
struct ipa_sudo_rules_refresh_state {
size_t num_rules;
int dp_error;
@@ -230,7 +354,7 @@ ipa_sudo_rules_refresh_send(TALLOC_CTX *mem_ctx,
goto immediately;
}
- subreq = ipa_sudo_refresh_send(req, ev, sudo_ctx, search_filter,
+ subreq = ipa_sudo_refresh_send(req, ev, sudo_ctx, NULL, search_filter,
delete_filter);
if (subreq == NULL) {
ret = ENOMEM;
@@ -327,7 +451,7 @@ ipa_sudo_ptask_smart_refresh_send(TALLOC_CTX *mem_ctx,
struct ipa_sudo_ctx *sudo_ctx;
sudo_ctx = talloc_get_type(pvt, struct ipa_sudo_ctx);
- return ipa_sudo_full_refresh_send(mem_ctx, be_ctx->ev, sudo_ctx);
+ return ipa_sudo_smart_refresh_send(mem_ctx, be_ctx->ev, sudo_ctx);
}
static errno_t
@@ -335,7 +459,7 @@ ipa_sudo_ptask_smart_refresh_recv(struct tevent_req *req)
{
int dp_error;
- return ipa_sudo_full_refresh_recv(req, &dp_error);
+ return ipa_sudo_smart_refresh_recv(req, &dp_error);
}
errno_t
--
2.5.0

View File

@ -1,62 +0,0 @@
From effe11c0b2a5e77e1b6085d695339fc449e2481f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 12 Jan 2016 12:02:40 +0100
Subject: [PATCH 32/49] SUDO: sdap_sudo_set_usn() do not steal usn
This is less error prone.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 3ff3bb43ae6509905bbf7fa6540c44cdbbd0f738)
---
src/providers/ldap/sdap_sudo_shared.c | 11 +++++++++--
src/providers/ldap/sdap_sudo_shared.h | 2 +-
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c
index b31d5d27f61b73e71ab8ad0341415ee00e2295cf..0885054e4d0e886671f7057e44d0e66e3f5ccaad 100644
--- a/src/providers/ldap/sdap_sudo_shared.c
+++ b/src/providers/ldap/sdap_sudo_shared.c
@@ -122,10 +122,11 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
void
sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
- char *usn)
+ const char *usn)
{
unsigned int usn_number;
char *endptr = NULL;
+ char *newusn;
if (srv_opts == NULL) {
DEBUG(SSSDBG_TRACE_FUNC, "Bug: srv_opts is NULL\n");
@@ -138,8 +139,14 @@ sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
}
if (sysdb_compare_usn(usn, srv_opts->max_sudo_value) > 0) {
+ newusn = talloc_strdup(srv_opts, usn);
+ if (newusn == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n");
+ return;
+ }
+
talloc_zfree(srv_opts->max_sudo_value);
- srv_opts->max_sudo_value = talloc_steal(srv_opts, usn);
+ srv_opts->max_sudo_value = newusn;
}
usn_number = strtoul(usn, &endptr, 10);
diff --git a/src/providers/ldap/sdap_sudo_shared.h b/src/providers/ldap/sdap_sudo_shared.h
index bbc6927250cf8a9b4a92eb15bad6c718c76e2f70..76858d431d0a8f2513f71321d39822da921bf9f8 100644
--- a/src/providers/ldap/sdap_sudo_shared.h
+++ b/src/providers/ldap/sdap_sudo_shared.h
@@ -35,6 +35,6 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
void
sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
- char *usn);
+ const char *usn);
#endif /* _SDAP_SUDO_SHARED_H_ */
--
2.5.0

View File

@ -1,87 +0,0 @@
From df870fbd4c2d9fa573338714ff1511475e74e785 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 12 Jan 2016 12:12:17 +0100
Subject: [PATCH 33/49] SUDO: remove full_refresh_in_progress
When we switched to be_ptask this variable has become obsolete.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 43bbf5b158ec3152806791ca49ae224ee978de24)
---
src/providers/ipa/ipa_sudo.h | 1 -
src/providers/ipa/ipa_sudo_refresh.c | 4 ----
src/providers/ldap/sdap_sudo.h | 1 -
src/providers/ldap/sdap_sudo_refresh.c | 4 ----
4 files changed, 10 deletions(-)
diff --git a/src/providers/ipa/ipa_sudo.h b/src/providers/ipa/ipa_sudo.h
index 81ada14e46550fab815a7df262abd0b5fa11afd7..3c346c837be6ee4848d4786ac01f36bc80698d3f 100644
--- a/src/providers/ipa/ipa_sudo.h
+++ b/src/providers/ipa/ipa_sudo.h
@@ -29,7 +29,6 @@ struct ipa_sudo_ctx {
struct sdap_options *sdap_opts;
bool full_refresh_done;
- bool full_refresh_in_progress;
/* sudo */
struct sdap_attr_map *sudocmdgroup_map;
diff --git a/src/providers/ipa/ipa_sudo_refresh.c b/src/providers/ipa/ipa_sudo_refresh.c
index bdde4a0026f224898a4987476f49122ea92a6052..c8fb7d9216edc0568ee906c368fcff5ff1596022 100644
--- a/src/providers/ipa/ipa_sudo_refresh.c
+++ b/src/providers/ipa/ipa_sudo_refresh.c
@@ -54,8 +54,6 @@ ipa_sudo_full_refresh_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- sudo_ctx->full_refresh_in_progress = true;
-
state->domain = sudo_ctx->id_ctx->be->domain;
state->sudo_ctx = sudo_ctx;
@@ -118,8 +116,6 @@ ipa_sudo_full_refresh_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, "Successful full refresh of sudo rules\n");
done:
- state->sudo_ctx->full_refresh_in_progress = false;
-
if (ret != EOK) {
tevent_req_error(req, ret);
return;
diff --git a/src/providers/ldap/sdap_sudo.h b/src/providers/ldap/sdap_sudo.h
index d2fa9bec41a07bbae2aaf1739df67a20ea6a578a..060f9fe36d3f6fda6d041e2f1c9a0781d914265d 100644
--- a/src/providers/ldap/sdap_sudo.h
+++ b/src/providers/ldap/sdap_sudo.h
@@ -34,7 +34,6 @@ struct sdap_sudo_ctx {
bool use_host_filter;
bool full_refresh_done;
- bool full_refresh_in_progress;
bool run_hostinfo;
};
diff --git a/src/providers/ldap/sdap_sudo_refresh.c b/src/providers/ldap/sdap_sudo_refresh.c
index 5697818ce71240468d2bcaa8af7994ca6b8ea3ef..f1fb6a924c93ec5c71a890d4e03aaac3e9709d73 100644
--- a/src/providers/ldap/sdap_sudo_refresh.c
+++ b/src/providers/ldap/sdap_sudo_refresh.c
@@ -55,8 +55,6 @@ struct tevent_req *sdap_sudo_full_refresh_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- sudo_ctx->full_refresh_in_progress = true;
-
state->sudo_ctx = sudo_ctx;
state->id_ctx = id_ctx;
state->sysdb = id_ctx->be->domain->sysdb;
@@ -132,8 +130,6 @@ static void sdap_sudo_full_refresh_done(struct tevent_req *subreq)
DEBUG(SSSDBG_TRACE_FUNC, "Successful full refresh of sudo rules\n");
done:
- state->sudo_ctx->full_refresh_in_progress = false;
-
if (ret != EOK) {
tevent_req_error(req, ret);
return;
--
2.5.0

View File

@ -1,127 +0,0 @@
From bd0561dd88307853b1901d2ba4036ec0c862f6d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 12 Jan 2016 12:15:03 +0100
Subject: [PATCH 34/49] SUDO: assume zero if usn is unknown
When we switched to be_ptaks full_refresh_done has become obsolete since
timing is handled in a better way. In case of unknown USN we assume zero
which allows us to disable full refresh completely in configuration.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 8bd44a13de231d025882810c720dd07ca4ee564d)
---
src/providers/ipa/ipa_sudo.h | 2 --
src/providers/ipa/ipa_sudo_refresh.c | 18 ++++++------------
src/providers/ldap/sdap_sudo.c | 4 ----
src/providers/ldap/sdap_sudo_refresh.c | 19 +++++++------------
4 files changed, 13 insertions(+), 30 deletions(-)
diff --git a/src/providers/ipa/ipa_sudo.h b/src/providers/ipa/ipa_sudo.h
index 3c346c837be6ee4848d4786ac01f36bc80698d3f..8b866001931ff0550157861dfbc4a99d7bb8319f 100644
--- a/src/providers/ipa/ipa_sudo.h
+++ b/src/providers/ipa/ipa_sudo.h
@@ -28,8 +28,6 @@ struct ipa_sudo_ctx {
struct ipa_options *ipa_opts;
struct sdap_options *sdap_opts;
- bool full_refresh_done;
-
/* sudo */
struct sdap_attr_map *sudocmdgroup_map;
struct sdap_attr_map *sudorule_map;
diff --git a/src/providers/ipa/ipa_sudo_refresh.c b/src/providers/ipa/ipa_sudo_refresh.c
index c8fb7d9216edc0568ee906c368fcff5ff1596022..5934a8f1181250890ca57ac8d83e47ffdc445ea4 100644
--- a/src/providers/ipa/ipa_sudo_refresh.c
+++ b/src/providers/ipa/ipa_sudo_refresh.c
@@ -105,8 +105,6 @@ ipa_sudo_full_refresh_done(struct tevent_req *subreq)
goto done;
}
- state->sudo_ctx->full_refresh_done = true;
-
ret = sysdb_sudo_set_last_full_refresh(state->domain, time(NULL));
if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, "Unable to save time of "
@@ -165,17 +163,13 @@ ipa_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- if (!sudo_ctx->full_refresh_done
- || srv_opts == NULL || srv_opts->max_sudo_value == NULL) {
- /* Perform full refresh first */
- DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, "
- "waiting for full refresh!\n");
- ret = EINVAL;
- goto immediately;
- }
-
/* Download all rules from LDAP that are newer than usn */
- usn = srv_opts->max_sudo_value;
+ if (srv_opts == NULL || srv_opts->max_sudo_value == NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, ssuming zero.\n");
+ usn = "0";
+ } else {
+ usn = srv_opts->max_sudo_value;
+ }
cmdgroups_filter = talloc_asprintf(state,
"(&(%s>=%s)(!(%s=%s)))",
diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c
index 10067e9ba779b5224bf21dd7a705c45e7f4e0f99..e653c46363253789e60146fbfc067cb93d4ab7f1 100644
--- a/src/providers/ldap/sdap_sudo.c
+++ b/src/providers/ldap/sdap_sudo.c
@@ -71,10 +71,6 @@ int sdap_sudo_init(struct be_ctx *be_ctx,
*ops = &sdap_sudo_ops;
*pvt_data = sudo_ctx;
- /* we didn't do any full refresh now,
- * so we don't have current usn values available */
- sudo_ctx->full_refresh_done = false;
-
ret = ldap_get_sudo_options(be_ctx->cdb,
be_ctx->conf_path, id_ctx->opts,
&sudo_ctx->use_host_filter,
diff --git a/src/providers/ldap/sdap_sudo_refresh.c b/src/providers/ldap/sdap_sudo_refresh.c
index f1fb6a924c93ec5c71a890d4e03aaac3e9709d73..61f24efa11da05d75bc31ea4ea3b150b2f9857f8 100644
--- a/src/providers/ldap/sdap_sudo_refresh.c
+++ b/src/providers/ldap/sdap_sudo_refresh.c
@@ -115,8 +115,6 @@ static void sdap_sudo_full_refresh_done(struct tevent_req *subreq)
goto done;
}
- state->sudo_ctx->full_refresh_done = true;
-
/* save the time in the sysdb */
ret = sysdb_sudo_set_last_full_refresh(state->domain, time(NULL));
if (ret != EOK) {
@@ -178,20 +176,17 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
return NULL;
}
- if (!sudo_ctx->full_refresh_done
- || srv_opts == NULL || srv_opts->max_sudo_value == NULL) {
- /* Perform full refresh first */
- DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, "
- "waiting for full refresh!\n");
- ret = EINVAL;
- goto immediately;
- }
-
state->id_ctx = id_ctx;
state->sysdb = id_ctx->be->domain->sysdb;
/* Download all rules from LDAP that are newer than usn */
- usn = srv_opts->max_sudo_value;
+ if (srv_opts == NULL || srv_opts->max_sudo_value == NULL) {
+ DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, ssuming zero.\n");
+ usn = "0";
+ } else {
+ usn = srv_opts->max_sudo_value;
+ }
+
search_filter = talloc_asprintf(state,
"(&(objectclass=%s)(%s>=%s)(!(%s=%s)))",
map[SDAP_OC_SUDORULE].name,
--
2.5.0

View File

@ -1,31 +0,0 @@
From 83f57d9810a34780949ac9f0c4dc9c6f8a069127 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 12 Jan 2016 11:45:22 +0100
Subject: [PATCH 35/49] SUDO: allow disabling full refresh
This condition always disabled smart refresh when full refresh
interval was set to zero and thus disabling periodic refresh
functionality completelely.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 8da71a9d5eebe7690b66fde8bfad195d5e3cc629)
---
src/providers/ldap/sdap_sudo_shared.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c
index 0885054e4d0e886671f7057e44d0e66e3f5ccaad..9e9574b7c641f52bd54989172ad7b6ccfd04b13f 100644
--- a/src/providers/ldap/sdap_sudo_shared.c
+++ b/src/providers/ldap/sdap_sudo_shared.c
@@ -55,7 +55,7 @@ sdap_sudo_ptask_setup_generic(struct be_ctx *be_ctx,
DEBUG(SSSDBG_CONF_SETTINGS, "At least smart refresh needs to be "
"enabled. Setting smart refresh interval to default value "
"(%ld) seconds.\n", smart);
- } else if (full <= smart) {
+ } else if (full > 0 && full <= smart) {
/* In this case it does not make any sense to run smart refresh. */
smart = 0;
--
2.5.0

View File

@ -1,178 +0,0 @@
From 0d13927fc7b2daec06cdff379715318e1dc2e05b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 14 Jan 2016 12:23:37 +0100
Subject: [PATCH 36/49] SUDO: remember usn as number instead of string
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit f58ffb26aeaae0642a149643672fa59ec01a3a36)
---
src/providers/ipa/ipa_sudo_refresh.c | 14 +++++++-------
src/providers/ldap/sdap.h | 2 +-
src/providers/ldap/sdap_sudo_refresh.c | 12 ++++++------
src/providers/ldap/sdap_sudo_shared.c | 35 ++++++++++++++++++----------------
4 files changed, 33 insertions(+), 30 deletions(-)
diff --git a/src/providers/ipa/ipa_sudo_refresh.c b/src/providers/ipa/ipa_sudo_refresh.c
index 5934a8f1181250890ca57ac8d83e47ffdc445ea4..42137679c4bd2209b98d1d5223fd3ac71dc16b16 100644
--- a/src/providers/ipa/ipa_sudo_refresh.c
+++ b/src/providers/ipa/ipa_sudo_refresh.c
@@ -153,7 +153,7 @@ ipa_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
struct tevent_req *req;
char *cmdgroups_filter;
char *search_filter;
- const char *usn;
+ unsigned long usn;
errno_t ret;
req = tevent_req_create(mem_ctx, &state,
@@ -164,15 +164,15 @@ ipa_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
}
/* Download all rules from LDAP that are newer than usn */
- if (srv_opts == NULL || srv_opts->max_sudo_value == NULL) {
- DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, ssuming zero.\n");
- usn = "0";
+ if (srv_opts == NULL || srv_opts->max_sudo_value == 0) {
+ DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero.\n");
+ usn = 0;
} else {
usn = srv_opts->max_sudo_value;
}
cmdgroups_filter = talloc_asprintf(state,
- "(&(%s>=%s)(!(%s=%s)))",
+ "(&(%s>=%lu)(!(%s=%lu)))",
sudo_ctx->sudocmdgroup_map[IPA_AT_SUDOCMDGROUP_ENTRYUSN].name, usn,
sudo_ctx->sudocmdgroup_map[IPA_AT_SUDOCMDGROUP_ENTRYUSN].name, usn);
if (cmdgroups_filter == NULL) {
@@ -181,7 +181,7 @@ ipa_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
}
search_filter = talloc_asprintf(state,
- "(&(%s>=%s)(!(%s=%s)))",
+ "(&(%s>=%lu)(!(%s=%lu)))",
sudo_ctx->sudorule_map[IPA_AT_SUDORULE_ENTRYUSN].name, usn,
sudo_ctx->sudorule_map[IPA_AT_SUDORULE_ENTRYUSN].name, usn);
if (search_filter == NULL) {
@@ -192,7 +192,7 @@ ipa_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
/* Do not remove any rules that are already in the sysdb. */
DEBUG(SSSDBG_TRACE_FUNC, "Issuing a smart refresh of sudo rules "
- "(USN > %s)\n", usn);
+ "(USN > %lu)\n", usn);
subreq = ipa_sudo_refresh_send(state, ev, sudo_ctx, cmdgroups_filter,
search_filter, NULL);
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index edfbf229b4c4396592020de931eba5f83a8f06ed..d7a299220414f2cf9d80de9921b6a5ec49e5793b 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -460,7 +460,7 @@ struct sdap_server_opts {
char *max_user_value;
char *max_group_value;
char *max_service_value;
- char *max_sudo_value;
+ unsigned long max_sudo_value;
bool posix_checked;
};
diff --git a/src/providers/ldap/sdap_sudo_refresh.c b/src/providers/ldap/sdap_sudo_refresh.c
index 61f24efa11da05d75bc31ea4ea3b150b2f9857f8..ff00fd037430f9a7ce62624184faa53288e581e4 100644
--- a/src/providers/ldap/sdap_sudo_refresh.c
+++ b/src/providers/ldap/sdap_sudo_refresh.c
@@ -167,7 +167,7 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
struct sdap_server_opts *srv_opts = id_ctx->srv_opts;
struct sdap_sudo_smart_refresh_state *state = NULL;
char *search_filter = NULL;
- const char *usn;
+ unsigned long usn;
int ret;
req = tevent_req_create(mem_ctx, &state, struct sdap_sudo_smart_refresh_state);
@@ -180,15 +180,15 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
state->sysdb = id_ctx->be->domain->sysdb;
/* Download all rules from LDAP that are newer than usn */
- if (srv_opts == NULL || srv_opts->max_sudo_value == NULL) {
- DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, ssuming zero.\n");
- usn = "0";
+ if (srv_opts == NULL || srv_opts->max_sudo_value == 0) {
+ DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero.\n");
+ usn = 0;
} else {
usn = srv_opts->max_sudo_value;
}
search_filter = talloc_asprintf(state,
- "(&(objectclass=%s)(%s>=%s)(!(%s=%s)))",
+ "(&(objectclass=%s)(%s>=%lu)(!(%s=%lu)))",
map[SDAP_OC_SUDORULE].name,
map[SDAP_AT_SUDO_USN].name, usn,
map[SDAP_AT_SUDO_USN].name, usn);
@@ -201,7 +201,7 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
* sysdb_filter = NULL; */
DEBUG(SSSDBG_TRACE_FUNC, "Issuing a smart refresh of sudo rules "
- "(USN > %s)\n", usn);
+ "(USN > %lu)\n", usn);
subreq = sdap_sudo_refresh_send(state, sudo_ctx, search_filter, NULL);
if (subreq == NULL) {
diff --git a/src/providers/ldap/sdap_sudo_shared.c b/src/providers/ldap/sdap_sudo_shared.c
index 9e9574b7c641f52bd54989172ad7b6ccfd04b13f..72f55e14baa8f8cf896205fb20f14d5f446cfb0a 100644
--- a/src/providers/ldap/sdap_sudo_shared.c
+++ b/src/providers/ldap/sdap_sudo_shared.c
@@ -126,7 +126,7 @@ sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
{
unsigned int usn_number;
char *endptr = NULL;
- char *newusn;
+ errno_t ret;
if (srv_opts == NULL) {
DEBUG(SSSDBG_TRACE_FUNC, "Bug: srv_opts is NULL\n");
@@ -138,23 +138,26 @@ sdap_sudo_set_usn(struct sdap_server_opts *srv_opts,
return;
}
- if (sysdb_compare_usn(usn, srv_opts->max_sudo_value) > 0) {
- newusn = talloc_strdup(srv_opts, usn);
- if (newusn == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup() failed\n");
- return;
- }
-
- talloc_zfree(srv_opts->max_sudo_value);
- srv_opts->max_sudo_value = newusn;
- }
-
+ errno = 0;
usn_number = strtoul(usn, &endptr, 10);
- if ((endptr == NULL || (*endptr == '\0' && endptr != usn))
- && (usn_number > srv_opts->last_usn)) {
- srv_opts->last_usn = usn_number;
+ if (endptr != NULL && *endptr != '\0') {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to convert USN %s\n", usn);
+ return;
+ } else if (errno != 0) {
+ ret = errno;
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to convert USN %s [%d]: %s\n",
+ usn, ret, sss_strerror(ret));
+ return;
}
- DEBUG(SSSDBG_FUNC_DATA, "SUDO higher USN value: [%s]\n",
+ if (usn_number > srv_opts->max_sudo_value) {
+ srv_opts->max_sudo_value = usn_number;
+ }
+
+ if (usn_number > srv_opts->last_usn) {
+ srv_opts->last_usn = usn_number;
+ }
+
+ DEBUG(SSSDBG_FUNC_DATA, "SUDO higher USN value: [%lu]\n",
srv_opts->max_sudo_value);
}
--
2.5.0

View File

@ -1,66 +0,0 @@
From 7971fa6c5b1b2c12b3e42aad158429665189a300 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Thu, 14 Jan 2016 13:12:14 +0100
Subject: [PATCH 37/49] SUDO: simplify usn filter
usn >= current && usn != currect is equivalent to usn >= current + 1
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 1476d5348fcf387e7481d833becbd993d91f8019)
---
src/providers/ipa/ipa_sudo_refresh.c | 10 +++-------
src/providers/ldap/sdap_sudo_refresh.c | 6 ++----
2 files changed, 5 insertions(+), 11 deletions(-)
diff --git a/src/providers/ipa/ipa_sudo_refresh.c b/src/providers/ipa/ipa_sudo_refresh.c
index 42137679c4bd2209b98d1d5223fd3ac71dc16b16..7871802ef7462ce98f6ff43bc33da57ff123ff6f 100644
--- a/src/providers/ipa/ipa_sudo_refresh.c
+++ b/src/providers/ipa/ipa_sudo_refresh.c
@@ -168,21 +168,17 @@ ipa_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero.\n");
usn = 0;
} else {
- usn = srv_opts->max_sudo_value;
+ usn = srv_opts->max_sudo_value + 1;
}
- cmdgroups_filter = talloc_asprintf(state,
- "(&(%s>=%lu)(!(%s=%lu)))",
- sudo_ctx->sudocmdgroup_map[IPA_AT_SUDOCMDGROUP_ENTRYUSN].name, usn,
+ cmdgroups_filter = talloc_asprintf(state, "(%s>=%lu)",
sudo_ctx->sudocmdgroup_map[IPA_AT_SUDOCMDGROUP_ENTRYUSN].name, usn);
if (cmdgroups_filter == NULL) {
ret = ENOMEM;
goto immediately;
}
- search_filter = talloc_asprintf(state,
- "(&(%s>=%lu)(!(%s=%lu)))",
- sudo_ctx->sudorule_map[IPA_AT_SUDORULE_ENTRYUSN].name, usn,
+ search_filter = talloc_asprintf(state, "(%s>=%lu)",
sudo_ctx->sudorule_map[IPA_AT_SUDORULE_ENTRYUSN].name, usn);
if (search_filter == NULL) {
ret = ENOMEM;
diff --git a/src/providers/ldap/sdap_sudo_refresh.c b/src/providers/ldap/sdap_sudo_refresh.c
index ff00fd037430f9a7ce62624184faa53288e581e4..5ba858019e0bda91a9e0919ed2b0345d9faf085e 100644
--- a/src/providers/ldap/sdap_sudo_refresh.c
+++ b/src/providers/ldap/sdap_sudo_refresh.c
@@ -184,13 +184,11 @@ struct tevent_req *sdap_sudo_smart_refresh_send(TALLOC_CTX *mem_ctx,
DEBUG(SSSDBG_TRACE_FUNC, "USN value is unknown, assuming zero.\n");
usn = 0;
} else {
- usn = srv_opts->max_sudo_value;
+ usn = srv_opts->max_sudo_value + 1;
}
- search_filter = talloc_asprintf(state,
- "(&(objectclass=%s)(%s>=%lu)(!(%s=%lu)))",
+ search_filter = talloc_asprintf(state, "(&(objectclass=%s)(%s>=%lu))",
map[SDAP_OC_SUDORULE].name,
- map[SDAP_AT_SUDO_USN].name, usn,
map[SDAP_AT_SUDO_USN].name, usn);
if (search_filter == NULL) {
ret = ENOMEM;
--
2.5.0

View File

@ -1,103 +0,0 @@
From d652bd9483243485ce86617fc070773f684c113b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Mon, 18 Jan 2016 12:15:47 +0100
Subject: [PATCH 38/49] IPA SUDO: Add support for ipaSudoRunAsExt* attributes
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit a7d2b4f157194c14bc4a40c74f6416b82befa460)
---
src/config/etc/sssd.api.d/sssd-ipa.conf | 3 +++
src/db/sysdb_sudo.h | 3 +++
src/providers/ipa/ipa_common.h | 3 +++
src/providers/ipa/ipa_opts.c | 3 +++
src/providers/ipa/ipa_sudo_conversion.c | 11 +++++++++++
5 files changed, 23 insertions(+)
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 2784a01e7a012f642377ae9c89d1ed03be88c7ae..13715ec34666f2dbc66df037565b495b9df42511 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -253,6 +253,9 @@ ipa_sudorule_hostcategory = str, None, false
ipa_sudorule_usercategory = str, None, false
ipa_sudorule_runasusercategory = str, None, false
ipa_sudorule_runasgroupcategory = str, None, false
+ipa_sudorule_runasextuser = str, None, false
+ipa_sudorule_runasextgroup = str, None, false
+ipa_sudorule_runasextusergroup = str, None, false
ipa_sudorule_entry_usn = str, None, false
ipa_sudocmdgroup_object_class = str, None, false
ipa_sudocmdgroup_uuid = str, None, false
diff --git a/src/db/sysdb_sudo.h b/src/db/sysdb_sudo.h
index 8635e78041687f386ec15d45e5d1d3f1f0551e3d..ba90a68512c6c29134ab2f746220db9533a93dda 100644
--- a/src/db/sysdb_sudo.h
+++ b/src/db/sysdb_sudo.h
@@ -65,6 +65,9 @@
#define SYSDB_IPA_SUDORULE_USERCATEGORY "userCategory"
#define SYSDB_IPA_SUDORULE_RUNASUSERCATEGORY "ipaSudoRunAsUserCategory"
#define SYSDB_IPA_SUDORULE_RUNASGROUPCATEGORY "ipaSudoRunAsGroupCategory"
+#define SYSDB_IPA_SUDORULE_RUNASEXTUSER "ipaSudoRunAsExtUser"
+#define SYSDB_IPA_SUDORULE_RUNASEXTGROUP "ipaSudoRunAsExtGroup"
+#define SYSDB_IPA_SUDORULE_RUNASEXTUSERGROUP "ipaSudoRunAsExtUserGroup"
#define SYSDB_IPA_SUDOCMDGROUP_OC "ipasudocmdgrp"
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index 8cb2058fef98fc8eef0d769a6f62882d1da7ae53..24898ee3809b0bcb682321ba4cfa500acd7c795b 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -153,6 +153,9 @@ enum ipa_sudorule_attrs {
IPA_AT_SUDORULE_USERCATEGORY,
IPA_AT_SUDORULE_RUNASUSERCATEGORY,
IPA_AT_SUDORULE_RUNASGROUPCATEGORY,
+ IPA_AT_SUDORULE_RUNASEXTUSER,
+ IPA_AT_SUDORULE_RUNASEXTGROUP,
+ IPA_AT_SUDORULE_RUNASEXTUSERGROUP,
IPA_AT_SUDORULE_ENTRYUSN,
IPA_OPTS_SUDORULE
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
index 725e512352ff40cb4de6daba88efa3b8dfefdc62..cda10f89a60264ffd998da73ebadd09dff35ed79 100644
--- a/src/providers/ipa/ipa_opts.c
+++ b/src/providers/ipa/ipa_opts.c
@@ -356,6 +356,9 @@ struct sdap_attr_map ipa_sudorule_map[] = {
{ "ipa_sudorule_usercategory", "userCategory", SYSDB_IPA_SUDORULE_USERCATEGORY, NULL },
{ "ipa_sudorule_runasusercategory", "ipaSudoRunAsUserCategory", SYSDB_IPA_SUDORULE_RUNASUSERCATEGORY, NULL },
{ "ipa_sudorule_runasgroupcategory", "ipaSudoRunAsGroupCategory", SYSDB_IPA_SUDORULE_RUNASGROUPCATEGORY, NULL },
+ { "ipa_sudorule_runasextuser", "ipaSudoRunAsExtUser", SYSDB_IPA_SUDORULE_RUNASEXTUSER, NULL },
+ { "ipa_sudorule_runasextgroup", "ipaSudoRunAsExtGroup", SYSDB_IPA_SUDORULE_RUNASEXTGROUP, NULL },
+ { "ipa_sudorule_runasextusergroup", "ipaSudoRunAsExtUserGroup", SYSDB_IPA_SUDORULE_RUNASEXTUSERGROUP, NULL },
{ "ipa_sudorule_entry_usn", "entryUSN", SYSDB_USN, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ipa/ipa_sudo_conversion.c b/src/providers/ipa/ipa_sudo_conversion.c
index 195e40f248e15756a224335208276f6f7a646cd0..02d7ebd5dd819f54b6d97b2251eca294d95a224b 100644
--- a/src/providers/ipa/ipa_sudo_conversion.c
+++ b/src/providers/ipa/ipa_sudo_conversion.c
@@ -757,6 +757,14 @@ convert_group(TALLOC_CTX *mem_ctx,
}
static const char *
+convert_runasextusergroup(TALLOC_CTX *mem_ctx,
+ struct ipa_sudo_conv *conv,
+ const char *value)
+{
+ return talloc_asprintf(mem_ctx, "%%%s", value);
+}
+
+static const char *
convert_cat(TALLOC_CTX *mem_ctx,
struct ipa_sudo_conv *conv,
const char *value)
@@ -798,6 +806,9 @@ convert_attributes(struct ipa_sudo_conv *conv,
{SYSDB_IPA_SUDORULE_USERCATEGORY, SYSDB_SUDO_CACHE_AT_USER , convert_cat},
{SYSDB_IPA_SUDORULE_RUNASUSERCATEGORY, SYSDB_SUDO_CACHE_AT_RUNASUSER , convert_cat},
{SYSDB_IPA_SUDORULE_RUNASGROUPCATEGORY, SYSDB_SUDO_CACHE_AT_RUNASGROUP , convert_cat},
+ {SYSDB_IPA_SUDORULE_RUNASEXTUSER, SYSDB_SUDO_CACHE_AT_RUNASUSER , NULL},
+ {SYSDB_IPA_SUDORULE_RUNASEXTGROUP, SYSDB_SUDO_CACHE_AT_RUNASGROUP , NULL},
+ {SYSDB_IPA_SUDORULE_RUNASEXTUSERGROUP, SYSDB_SUDO_CACHE_AT_RUNASUSER , convert_runasextusergroup},
{SYSDB_IPA_SUDORULE_ALLOWCMD, SYSDB_IPA_SUDORULE_ORIGCMD , NULL},
{SYSDB_IPA_SUDORULE_DENYCMD, SYSDB_IPA_SUDORULE_ORIGCMD , NULL},
{NULL, NULL, NULL}};
--
2.5.0

View File

@ -1,240 +0,0 @@
From d0daca3614cd739cda955d8fdbd75b5718420276 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 14 Jan 2016 13:33:53 +0100
Subject: [PATCH 39/49] UTIL: allow to skip default options for child processes
Currently the SSSD default options like e.g. --debug-level are added
unconditionally to the command line options of a child process when
started with the child helper functions.
If a binary from a different source should be started as a child by SSSD
those options might not be known or used differently. This patch adds an
option to exec_child_ex() which allows to skip the default options and
only add specific options.
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 9dcc7dbf04466cd8cd90aa0bb8acbebef9aca832)
---
src/providers/ad/ad_gpo.c | 2 +-
src/providers/krb5/krb5_child_handler.c | 2 +-
src/responder/pam/pamsrv_p11.c | 2 +-
src/tests/cmocka/test_child_common.c | 4 +-
src/util/child_common.c | 73 ++++++++++++++++++---------------
src/util/child_common.h | 2 +-
6 files changed, 47 insertions(+), 38 deletions(-)
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index d63e52e2798753262b13361788d40b8743640c84..00f4457ddfa35b8917d7babc6666fdc129fb63ae 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -4139,7 +4139,7 @@ gpo_fork_child(struct tevent_req *req)
if (pid == 0) { /* child */
err = exec_child_ex(state,
pipefd_to_child, pipefd_from_child,
- GPO_CHILD, gpo_child_debug_fd, NULL,
+ GPO_CHILD, gpo_child_debug_fd, NULL, false,
STDIN_FILENO, AD_GPO_CHILD_OUT_FILENO);
DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec gpo_child: [%d][%s].\n",
err, strerror(err));
diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c
index fa1055eb7fc7e9aa6fabef1c1759c272b217a395..167a2b2ad09b67908cdce8051d8a37e557c91545 100644
--- a/src/providers/krb5/krb5_child_handler.c
+++ b/src/providers/krb5/krb5_child_handler.c
@@ -312,7 +312,7 @@ static errno_t fork_child(struct tevent_req *req)
err = exec_child_ex(state,
pipefd_to_child, pipefd_from_child,
KRB5_CHILD, state->kr->krb5_ctx->child_debug_fd,
- k5c_extra_args, STDIN_FILENO, STDOUT_FILENO);
+ k5c_extra_args, false, STDIN_FILENO, STDOUT_FILENO);
if (err != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec KRB5 child: [%d][%s].\n",
err, strerror(err));
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index 58310a2530287fc6d08a7195c8e879f96dcc5403..ea428a6a3dd41b1770b69ff0301ed98c1c08c01d 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -322,7 +322,7 @@ struct tevent_req *pam_check_cert_send(TALLOC_CTX *mem_ctx,
child_pid = fork();
if (child_pid == 0) { /* child */
ret = exec_child_ex(state, pipefd_to_child, pipefd_from_child,
- P11_CHILD_PATH, child_debug_fd, extra_args,
+ P11_CHILD_PATH, child_debug_fd, extra_args, false,
STDIN_FILENO, STDOUT_FILENO);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec p11 child: [%d][%s].\n",
diff --git a/src/tests/cmocka/test_child_common.c b/src/tests/cmocka/test_child_common.c
index bf500fa5a1f2b2fe79833e23a53cdf0b06b81260..9ed9c1ae42dd93cef833b738c29259a18e791339 100644
--- a/src/tests/cmocka/test_child_common.c
+++ b/src/tests/cmocka/test_child_common.c
@@ -139,7 +139,7 @@ void test_exec_child_extra_args(void **state)
ret = exec_child_ex(child_tctx,
child_tctx->pipefd_to_child,
child_tctx->pipefd_from_child,
- CHILD_DIR"/"TEST_BIN, 2, extra_args,
+ CHILD_DIR"/"TEST_BIN, 2, extra_args, false,
STDIN_FILENO, STDOUT_FILENO);
assert_int_equal(ret, EOK);
} else {
@@ -287,7 +287,7 @@ void test_exec_child_echo(void **state)
ret = exec_child_ex(child_tctx,
child_tctx->pipefd_to_child,
child_tctx->pipefd_from_child,
- CHILD_DIR"/"TEST_BIN, 2, NULL,
+ CHILD_DIR"/"TEST_BIN, 2, NULL, false,
STDIN_FILENO, 3);
assert_int_equal(ret, EOK);
}
diff --git a/src/util/child_common.c b/src/util/child_common.c
index a6131cd20e7cfff5e5d58806aa2c178327eb9baa..60466c146b5bd9147e9425736072f1ea6ed73663 100644
--- a/src/util/child_common.c
+++ b/src/util/child_common.c
@@ -612,6 +612,7 @@ static errno_t prepare_child_argv(TALLOC_CTX *mem_ctx,
int child_debug_fd,
const char *binary,
const char *extra_argv[],
+ bool extra_args_only,
char ***_argv)
{
/*
@@ -619,18 +620,24 @@ static errno_t prepare_child_argv(TALLOC_CTX *mem_ctx,
* debug_microseconds and NULL
*/
uint_t argc = 5;
- char ** argv;
+ char ** argv = NULL;
errno_t ret = EINVAL;
size_t i;
+ if (extra_args_only) {
+ argc = 2; /* program name and NULL */
+ }
+
/* Save the current state in case an interrupt changes it */
bool child_debug_to_file = debug_to_file;
bool child_debug_timestamps = debug_timestamps;
bool child_debug_microseconds = debug_microseconds;
bool child_debug_stderr = debug_to_stderr;
- if (child_debug_to_file) argc++;
- if (child_debug_stderr) argc++;
+ if (!extra_args_only) {
+ if (child_debug_to_file) argc++;
+ if (child_debug_stderr) argc++;
+ }
if (extra_argv) {
for (i = 0; extra_argv[i]; i++) argc++;
@@ -659,42 +666,44 @@ static errno_t prepare_child_argv(TALLOC_CTX *mem_ctx,
}
}
- argv[--argc] = talloc_asprintf(argv, "--debug-level=%#.4x",
- debug_level);
- if (argv[argc] == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- if (child_debug_stderr) {
- argv[--argc] = talloc_strdup(argv, "--debug-to-stderr");
+ if (!extra_args_only) {
+ argv[--argc] = talloc_asprintf(argv, "--debug-level=%#.4x",
+ debug_level);
if (argv[argc] == NULL) {
ret = ENOMEM;
goto fail;
}
- }
- if (child_debug_to_file) {
- argv[--argc] = talloc_asprintf(argv, "--debug-fd=%d",
- child_debug_fd);
+ if (child_debug_stderr) {
+ argv[--argc] = talloc_strdup(argv, "--debug-to-stderr");
+ if (argv[argc] == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ }
+
+ if (child_debug_to_file) {
+ argv[--argc] = talloc_asprintf(argv, "--debug-fd=%d",
+ child_debug_fd);
+ if (argv[argc] == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ }
+
+ argv[--argc] = talloc_asprintf(argv, "--debug-timestamps=%d",
+ child_debug_timestamps);
if (argv[argc] == NULL) {
ret = ENOMEM;
goto fail;
}
- }
- argv[--argc] = talloc_asprintf(argv, "--debug-timestamps=%d",
- child_debug_timestamps);
- if (argv[argc] == NULL) {
- ret = ENOMEM;
- goto fail;
- }
-
- argv[--argc] = talloc_asprintf(argv, "--debug-microseconds=%d",
- child_debug_microseconds);
- if (argv[argc] == NULL) {
- ret = ENOMEM;
- goto fail;
+ argv[--argc] = talloc_asprintf(argv, "--debug-microseconds=%d",
+ child_debug_microseconds);
+ if (argv[argc] == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
}
argv[--argc] = talloc_strdup(argv, binary);
@@ -720,7 +729,7 @@ fail:
errno_t exec_child_ex(TALLOC_CTX *mem_ctx,
int *pipefd_to_child, int *pipefd_from_child,
const char *binary, int debug_fd,
- const char *extra_argv[],
+ const char *extra_argv[], bool extra_args_only,
int child_in_fd, int child_out_fd)
{
int ret;
@@ -746,7 +755,7 @@ errno_t exec_child_ex(TALLOC_CTX *mem_ctx,
}
ret = prepare_child_argv(mem_ctx, debug_fd,
- binary, extra_argv,
+ binary, extra_argv, extra_args_only,
&argv);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "prepare_child_argv.\n");
@@ -764,7 +773,7 @@ errno_t exec_child(TALLOC_CTX *mem_ctx,
const char *binary, int debug_fd)
{
return exec_child_ex(mem_ctx, pipefd_to_child, pipefd_from_child,
- binary, debug_fd, NULL,
+ binary, debug_fd, NULL, false,
STDIN_FILENO, STDOUT_FILENO);
}
diff --git a/src/util/child_common.h b/src/util/child_common.h
index b93991832b7389177f9da05e694ab729ef50cdc7..0111f2cdb26af8543d68e6a6661d656d1c9c45ac 100644
--- a/src/util/child_common.h
+++ b/src/util/child_common.h
@@ -104,7 +104,7 @@ void fd_nonblocking(int fd);
errno_t exec_child_ex(TALLOC_CTX *mem_ctx,
int *pipefd_to_child, int *pipefd_from_child,
const char *binary, int debug_fd,
- const char *extra_argv[],
+ const char *extra_argv[], bool extra_args_only,
int child_in_fd, int child_out_fd);
/* Same as exec_child_ex() except child_in_fd is set to STDIN_FILENO and
--
2.5.0

View File

@ -1,90 +0,0 @@
From 6ce7de495012c3b4ec28696466938a784e3a4708 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 18 Jan 2016 13:20:16 +0100
Subject: [PATCH 40/49] DP_TASK: add be_ptask_get_timeout()
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit e89c2cb5ec77d57ed93952dae08df51738834faf)
---
src/providers/dp_ptask.c | 5 +++++
src/providers/dp_ptask.h | 1 +
src/tests/cmocka/test_be_ptask.c | 22 ++++++++++++++++++++++
3 files changed, 28 insertions(+)
diff --git a/src/providers/dp_ptask.c b/src/providers/dp_ptask.c
index 51800ab57b5649380c0603f1d602dfa81d1f5919..3ebb134be4a991498ac5692883dd1a42416efcfe 100644
--- a/src/providers/dp_ptask.c
+++ b/src/providers/dp_ptask.c
@@ -384,6 +384,11 @@ time_t be_ptask_get_period(struct be_ptask *task)
return task->period;
}
+time_t be_ptask_get_timeout(struct be_ptask *task)
+{
+ return task->timeout;
+}
+
struct be_ptask_sync_ctx {
be_ptask_sync_t fn;
void *pvt;
diff --git a/src/providers/dp_ptask.h b/src/providers/dp_ptask.h
index 1b931010bb206285f3ca635f7b0c2399c3050951..3b97553619f5ac2d4292ba61e3de3c7408af812c 100644
--- a/src/providers/dp_ptask.h
+++ b/src/providers/dp_ptask.h
@@ -126,5 +126,6 @@ void be_ptask_disable(struct be_ptask *task);
void be_ptask_destroy(struct be_ptask **task);
time_t be_ptask_get_period(struct be_ptask *task);
+time_t be_ptask_get_timeout(struct be_ptask *task);
#endif /* _DP_PTASK_H_ */
diff --git a/src/tests/cmocka/test_be_ptask.c b/src/tests/cmocka/test_be_ptask.c
index a0daaf967a6f1ea991ff30445488ffadff51f821..cbf61e81dd00d98cb27f87e31a0c4718f6b9a0b4 100644
--- a/src/tests/cmocka/test_be_ptask.c
+++ b/src/tests/cmocka/test_be_ptask.c
@@ -33,6 +33,7 @@
#define DELAY 2
#define PERIOD 1
+#define TIMEOUT 123
#define new_test(test) \
cmocka_unit_test_setup_teardown(test_ ## test, test_setup, test_teardown)
@@ -795,6 +796,26 @@ void test_be_ptask_get_period(void **state)
assert_null(ptask);
}
+void test_be_ptask_get_timeout(void **state)
+{
+ struct test_ctx *test_ctx = (struct test_ctx *)(*state);
+ struct be_ptask *ptask = NULL;
+ time_t out_timeout;
+ errno_t ret;
+
+ ret = be_ptask_create(test_ctx, test_ctx->be_ctx, PERIOD, 0, 0, 0, TIMEOUT,
+ BE_PTASK_OFFLINE_SKIP, 0, test_be_ptask_send,
+ test_be_ptask_recv, test_ctx, "Test ptask", &ptask);
+ assert_int_equal(ret, ERR_OK);
+ assert_non_null(ptask);
+
+ out_timeout = be_ptask_get_timeout(ptask);
+ assert_true(TIMEOUT == out_timeout);
+
+ be_ptask_destroy(&ptask);
+ assert_null(ptask);
+}
+
void test_be_ptask_create_sync(void **state)
{
struct test_ctx *test_ctx = (struct test_ctx *)(*state);
@@ -970,6 +991,7 @@ int main(int argc, const char *argv[])
new_test(be_ptask_reschedule_timeout),
new_test(be_ptask_reschedule_backoff),
new_test(be_ptask_get_period),
+ new_test(be_ptask_get_timeout),
new_test(be_ptask_create_sync),
new_test(be_ptask_sync_reschedule_ok),
new_test(be_ptask_sync_reschedule_error),
--
2.5.0

View File

@ -1,575 +0,0 @@
From 70a669646ed841048346b451741e972a0ada703d Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 12 Jan 2016 11:05:02 +0100
Subject: [PATCH 41/49] AD: add task to renew the machine account password if
needed
AD expects its clients to renew the machine account password on a
regular basis, be default every 30 days. Even if a client does not renew
the password it might not cause issues because AD does not enforce the
renewal. But the password age might be used to identify unused machine
accounts in large environments which might get disabled or deleted
automatically.
With this patch SSSD calls an external program to check the age of the
machine account password and renew it if needed. Currently 'adcli' is
used as external program which is able to renew the password since
version 0.8.0.
Resolves https://fedorahosted.org/sssd/ticket/1041
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 5f7cd30c865046a7ea69944f7e07c85b4c43465a)
---
Makefile.am | 1 +
src/config/SSSDConfig/__init__.py.in | 2 +
src/config/etc/sssd.api.d/sssd-ad.conf | 2 +
src/man/sssd-ad.5.xml | 33 +++
src/providers/ad/ad_common.h | 5 +
src/providers/ad/ad_init.c | 7 +
src/providers/ad/ad_machine_pw_renewal.c | 372 +++++++++++++++++++++++++++++++
src/providers/ad/ad_opts.c | 2 +
src/util/util_errors.c | 1 +
src/util/util_errors.h | 1 +
10 files changed, 426 insertions(+)
create mode 100644 src/providers/ad/ad_machine_pw_renewal.c
diff --git a/Makefile.am b/Makefile.am
index 1c0b1aada9804b2ef35a09cf1b7bf5e9c65ee4e5..a9099c07fcfe54a88bd56129364dde5262e901ed 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3061,6 +3061,7 @@ libsss_ad_la_SOURCES = \
src/providers/ad/ad_common.h \
src/providers/ad/ad_init.c \
src/providers/ad/ad_dyndns.c \
+ src/providers/ad/ad_machine_pw_renewal.c \
src/providers/ad/ad_id.c \
src/providers/ad/ad_id.h \
src/providers/ad/ad_access.c \
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 2cb857013fe4bddfd2e79e589d3ba9721dc3ca4f..b4a6fcb0d37469e1dda85eda95fd80825697902c 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -199,6 +199,8 @@ option_strings = {
'ad_gpo_map_deny' : _('PAM service names for which GPO-based access is always denied'),
'ad_gpo_default_right' : _('Default logon right (or permit/deny) to use for unmapped PAM service names'),
'ad_site' : _('a particular site to be used by the client'),
+ 'ad_maximum_machine_account_password_age' : _('Maximum age in days before the machine account password should be renewed'),
+ 'ad_machine_account_password_renewal_opts' : _('Option for tuing the machine account renewal task'),
# [provider/krb5]
'krb5_kdcip' : _('Kerberos server address'),
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index 5eb546caac913b839112a70bd81dbde2c7ff2d9f..0ea73d14112d1c7cf7a6d4cbda0d2b2e53a3a7be 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -17,6 +17,8 @@ ad_gpo_map_permit = str, None, false
ad_gpo_map_deny = str, None, false
ad_gpo_default_right = str, None, false
ad_site = str, None, false
+ad_maximum_machine_account_password_age = int, None, false
+ad_machine_account_password_renewal_opts = str, None, false
ldap_uri = str, None, false
ldap_backup_uri = str, None, false
ldap_search_base = str, None, false
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index 173fb93009f66c2c83ab87ff5ca900fc10cbf5e8..4280eac5f4594b26d158a0ea58622f9fe7beb53e 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -719,6 +719,39 @@ ad_gpo_map_deny = +my_pam_service
</varlistentry>
<varlistentry>
+ <term>ad_maximum_machine_account_password_age (integer)</term>
+ <listitem>
+ <para>
+ SSSD will check once a day if the machine account
+ password is older than the given age in days and try
+ to renew it. A value of 0 will disable the renewal
+ attempt.
+ </para>
+ <para>
+ Default: 30 days
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>ad_machine_account_password_renewal_opts (string)</term>
+ <listitem>
+ <para>
+ This option should only be used to test the machine
+ account renewal task. The option expect 2 integers
+ seperated by a colon (':'). The first integer
+ defines the interval in seconds how often the task
+ is run. The second specifies the inital timeout in
+ seconds before the task is run for the first time
+ after startup.
+ </para>
+ <para>
+ Default: 86400:750 (24h and 15m)
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>dyndns_update (boolean)</term>
<listitem>
<para>
diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
index 2dd4175487cd36215dad1aaa9111e316a1fc3a0a..5bb2e52d402e4279fdc60d4ab58afd2292358487 100644
--- a/src/providers/ad/ad_common.h
+++ b/src/providers/ad/ad_common.h
@@ -62,6 +62,8 @@ enum ad_basic_opt {
AD_GPO_DEFAULT_RIGHT,
AD_SITE,
AD_KRB5_CONFD_PATH,
+ AD_MAXIMUM_MACHINE_ACCOUNT_PASSWORD_AGE,
+ AD_MACHINE_ACCOUNT_PASSWORD_RENEWAL_OPTS,
AD_OPTS_BASIC /* opts counter */
};
@@ -180,4 +182,7 @@ int ad_autofs_init(struct be_ctx *be_ctx,
struct bet_ops **ops,
void **pvt_data);
+errno_t ad_machine_account_password_renewal_init(struct be_ctx *be_ctx,
+ struct ad_options *ad_opts);
+
#endif /* AD_COMMON_H_ */
diff --git a/src/providers/ad/ad_init.c b/src/providers/ad/ad_init.c
index 72ce5536b0f0f69a530bda0ffc41ae93180c1a94..e40fb6f1d0eabae45581969f1ff73c8cf302fb4c 100644
--- a/src/providers/ad/ad_init.c
+++ b/src/providers/ad/ad_init.c
@@ -308,6 +308,13 @@ sssm_ad_id_init(struct be_ctx *bectx,
"will not work [%d]: %s\n", ret, strerror(ret));
}
+ ret = ad_machine_account_password_renewal_init(bectx, ad_options);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot setup task for machine account "
+ "password renewal.\n");
+ goto done;
+ }
+
*ops = &ad_id_ops;
*pvt_data = ad_ctx;
diff --git a/src/providers/ad/ad_machine_pw_renewal.c b/src/providers/ad/ad_machine_pw_renewal.c
new file mode 100644
index 0000000000000000000000000000000000000000..e42c700e7aa3cf9a45acee025e36899b36642dad
--- /dev/null
+++ b/src/providers/ad/ad_machine_pw_renewal.c
@@ -0,0 +1,372 @@
+/*
+ SSSD
+
+ Authors:
+ Sumit Bose <sbose@redhat.com>
+
+ Copyright (C) 2016 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 "util/util.h"
+#include "util/strtonum.h"
+#include "providers/dp_ptask.h"
+#include "providers/ad/ad_common.h"
+
+#ifndef RENEWAL_PROG_PATH
+#define RENEWAL_PROG_PATH "/usr/sbin/adcli"
+#endif
+
+struct renewal_data {
+ char *prog_path;
+ const char **extra_args;
+};
+
+static errno_t get_adcli_extra_args(const char *ad_domain,
+ const char *ad_hostname,
+ const char *ad_keytab,
+ size_t pw_lifetime_in_days,
+ size_t period,
+ size_t initial_delay,
+ struct renewal_data *renewal_data)
+{
+ const char **args;
+ size_t c = 0;
+
+ if (ad_domain == NULL || ad_hostname == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Missing AD domain or hostname.\n");
+ return EINVAL;
+ }
+
+ renewal_data->prog_path = talloc_strdup(renewal_data, RENEWAL_PROG_PATH);
+ if (renewal_data->prog_path == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
+ return ENOMEM;
+ }
+
+ args = talloc_array(renewal_data, const char *, 7);
+ if (args == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
+ return ENOMEM;
+ }
+
+ /* extra_args are added in revers order */
+ args[c++] = talloc_asprintf(args, "--computer-password-lifetime=%zu",
+ pw_lifetime_in_days);
+ args[c++] = talloc_asprintf(args, "--host-fqdn=%s", ad_hostname);
+ if (ad_keytab != NULL) {
+ args[c++] = talloc_asprintf(args, "--host-keytab=%s", ad_keytab);
+ }
+ args[c++] = talloc_asprintf(args, "--domain=%s", ad_domain);
+ if (DEBUG_IS_SET(SSSDBG_TRACE_LIBS)) {
+ args[c++] = talloc_strdup(args, "--verbose");
+ }
+ args[c++] = talloc_strdup(args, "update");
+ args[c] = NULL;
+
+ do {
+ if (args[--c] == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "talloc failed while copying arguments.\n");
+ talloc_free(args);
+ return ENOMEM;
+ }
+ } while (c != 0);
+
+ renewal_data->extra_args = args;
+
+ return EOK;
+}
+
+struct renewal_state {
+ int child_status;
+ struct sss_child_ctx_old *child_ctx;
+ struct tevent_timer *timeout_handler;
+ struct tevent_context *ev;
+
+ int write_to_child_fd;
+ int read_from_child_fd;
+};
+
+static void ad_machine_account_password_renewal_done(struct tevent_req *subreq);
+static void
+ad_machine_account_password_renewal_timeout(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval tv, void *pvt);
+
+static struct tevent_req *
+ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct be_ctx *be_ctx,
+ struct be_ptask *be_ptask,
+ void *pvt)
+{
+ struct renewal_data *renewal_data;
+ struct renewal_state *state;
+ struct tevent_req *req;
+ struct tevent_req *subreq;
+ pid_t child_pid;
+ struct timeval tv;
+ int pipefd_to_child[2];
+ int pipefd_from_child[2];
+ int ret;
+
+ req = tevent_req_create(mem_ctx, &state, struct renewal_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
+ return NULL;
+ }
+
+ renewal_data = talloc_get_type(pvt, struct renewal_data);
+
+ state->ev = ev;
+ state->child_status = EFAULT;
+ state->read_from_child_fd = -1;
+ state->write_to_child_fd = -1;
+
+ ret = pipe(pipefd_from_child);
+ if (ret == -1) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "pipe failed [%d][%s].\n", ret, strerror(ret));
+ goto done;
+ }
+ ret = pipe(pipefd_to_child);
+ if (ret == -1) {
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "pipe failed [%d][%s].\n", ret, strerror(ret));
+ goto done;
+ }
+
+ child_pid = fork();
+ if (child_pid == 0) { /* child */
+ ret = exec_child_ex(state, pipefd_to_child, pipefd_from_child,
+ renewal_data->prog_path, -1,
+ renewal_data->extra_args, true,
+ STDIN_FILENO, STDERR_FILENO);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec renewal child: [%d][%s].\n",
+ ret, strerror(ret));
+ goto done;
+ }
+ } else if (child_pid > 0) { /* parent */
+
+ state->read_from_child_fd = pipefd_from_child[0];
+ close(pipefd_from_child[1]);
+ sss_fd_nonblocking(state->read_from_child_fd);
+
+ state->write_to_child_fd = pipefd_to_child[1];
+ close(pipefd_to_child[0]);
+ sss_fd_nonblocking(state->write_to_child_fd);
+
+ /* Set up SIGCHLD handler */
+ ret = child_handler_setup(ev, child_pid, NULL, NULL, &state->child_ctx);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "Could not set up child handlers [%d]: %s\n",
+ ret, sss_strerror(ret));
+ ret = ERR_RENEWAL_CHILD;
+ goto done;
+ }
+
+ /* Set up timeout handler */
+ tv = tevent_timeval_current_ofs(be_ptask_get_timeout(be_ptask), 0);
+ state->timeout_handler = tevent_add_timer(ev, req, tv,
+ ad_machine_account_password_renewal_timeout,
+ req);
+ if(state->timeout_handler == NULL) {
+ ret = ERR_RENEWAL_CHILD;
+ goto done;
+ }
+
+ subreq = read_pipe_send(state, ev, state->read_from_child_fd);
+ if (subreq == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "read_pipe_send failed.\n");
+ ret = ERR_RENEWAL_CHILD;
+ goto done;
+ }
+ tevent_req_set_callback(subreq,
+ ad_machine_account_password_renewal_done, req);
+
+ /* Now either wait for the timeout to fire or the child
+ * to finish
+ */
+ } else { /* error */
+ ret = errno;
+ DEBUG(SSSDBG_CRIT_FAILURE, "fork failed [%d][%s].\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ tevent_req_post(req, ev);
+ }
+ return req;
+}
+
+static void ad_machine_account_password_renewal_done(struct tevent_req *subreq)
+{
+ uint8_t *buf;
+ ssize_t buf_len;
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct renewal_state *state = tevent_req_data(req, struct renewal_state);
+ int ret;
+
+ talloc_zfree(state->timeout_handler);
+
+ ret = read_pipe_recv(subreq, state, &buf, &buf_len);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ DEBUG(SSSDBG_TRACE_LIBS, "--- adcli output start---\n"
+ "%.*s"
+ "---adcli output end---\n",
+ (int) buf_len, buf);
+
+ close(state->read_from_child_fd);
+ state->read_from_child_fd = -1;
+
+
+ tevent_req_done(req);
+ return;
+}
+
+static void
+ad_machine_account_password_renewal_timeout(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval tv, void *pvt)
+{
+ struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
+ struct renewal_state *state = tevent_req_data(req, struct renewal_state);
+
+ DEBUG(SSSDBG_CRIT_FAILURE, "Timeout reached for AD renewal child.\n");
+ child_handler_destroy(state->child_ctx);
+ state->child_ctx = NULL;
+ state->child_status = ETIMEDOUT;
+ tevent_req_error(req, ERR_RENEWAL_CHILD);
+}
+
+static errno_t
+ad_machine_account_password_renewal_recv(struct tevent_req *req)
+{
+
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ return EOK;
+}
+
+errno_t ad_machine_account_password_renewal_init(struct be_ctx *be_ctx,
+ struct ad_options *ad_opts)
+{
+ int ret;
+ struct renewal_data *renewal_data;
+ int lifetime;
+ size_t period;
+ size_t initial_delay;
+ const char *dummy;
+ char **opt_list;
+ int opt_list_size;
+ char *endptr;
+
+ lifetime = dp_opt_get_int(ad_opts->basic,
+ AD_MAXIMUM_MACHINE_ACCOUNT_PASSWORD_AGE);
+
+ if (lifetime == 0) {
+ DEBUG(SSSDBG_CONF_SETTINGS, "Automatic machine account renewal disabled.\n");
+ return EOK;
+ }
+
+ if (lifetime < 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Illegal value [%d] for password lifetime.\n", lifetime);
+ return EINVAL;
+ }
+
+ renewal_data = talloc(be_ctx, struct renewal_data);
+ if (renewal_data == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc failed.\n");
+ return ENOMEM;
+ }
+
+ dummy = dp_opt_get_cstring(ad_opts->basic,
+ AD_MACHINE_ACCOUNT_PASSWORD_RENEWAL_OPTS);
+ ret = split_on_separator(renewal_data, dummy, ':', true, false,
+ &opt_list, &opt_list_size);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "split_on_separator failed.\n");
+ goto done;
+ }
+
+ if (opt_list_size != 2) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Wrong number of renewal options.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ errno = 0;
+ period = strtouint32(opt_list[0], &endptr, 10);
+ if (errno != 0 || *endptr != '\0' || opt_list[0] == endptr) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse first renewal option.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ errno = 0;
+ initial_delay = strtouint32(opt_list[1], &endptr, 10);
+ if (errno != 0 || *endptr != '\0' || opt_list[0] == endptr) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to parse second renewal option.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = get_adcli_extra_args(dp_opt_get_cstring(ad_opts->basic, AD_DOMAIN),
+ dp_opt_get_cstring(ad_opts->basic, AD_HOSTNAME),
+ dp_opt_get_cstring(ad_opts->id_ctx->sdap_id_ctx->opts->basic,
+ SDAP_KRB5_KEYTAB),
+ lifetime, period, initial_delay, renewal_data);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "get_adcli_extra_args failed.\n");
+ goto done;
+ }
+
+ ret = be_ptask_create(be_ctx, be_ctx, period, initial_delay, 0, 0, 60,
+ BE_PTASK_OFFLINE_DISABLE, 0,
+ ad_machine_account_password_renewal_send,
+ ad_machine_account_password_renewal_recv,
+ renewal_data,
+ "AD machine account password renewal", NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "be_ptask_create failed.\n");
+ goto done;
+ }
+
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ talloc_free(renewal_data);
+ }
+
+ return ret;
+}
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
index 4ea96637ca7264c76109ed8c2f7b5e8a94f73bfe..8b2841eadc0236b51f8c9c2c02b7c98837fbe416 100644
--- a/src/providers/ad/ad_opts.c
+++ b/src/providers/ad/ad_opts.c
@@ -48,6 +48,8 @@ struct dp_option ad_basic_opts[] = {
{ "ad_gpo_default_right", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "ad_site", DP_OPT_STRING, NULL_STRING, NULL_STRING },
{ "krb5_confd_path", DP_OPT_STRING, { KRB5_MAPPING_DIR }, NULL_STRING },
+ { "ad_maximum_machine_account_password_age", DP_OPT_NUMBER, { .number = 30 }, NULL_NUMBER },
+ { "ad_machine_account_password_renewal_opts", DP_OPT_STRING, { "86400:750" }, NULL_STRING },
DP_OPTION_TERMINATOR
};
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
index ed19346d9b588a711367af4c891b1298cd4f067e..1d684d387b90b8db37609d5bc022e06fcac708f9 100644
--- a/src/util/util_errors.c
+++ b/src/util/util_errors.c
@@ -82,6 +82,7 @@ struct err_string error_to_str[] = {
{ "Address family not supported" }, /* ERR_ADDR_FAMILY_NOT_SUPPORTED */
{ "Message sender is the bus" }, /* ERR_SBUS_SENDER_BUS */
{ "Subdomain is inactive" }, /* ERR_SUBDOM_INACTIVE */
+ { "AD renewal child failed" }, /* ERR_RENEWAL_CHILD */
{ "ERR_LAST" } /* ERR_LAST */
};
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
index c1d081912a382d645c27809a3ac336ff90047cdf..5c02fdd8b4c6e0c59f7fd6f66a3fc8a8e48dc607 100644
--- a/src/util/util_errors.h
+++ b/src/util/util_errors.h
@@ -104,6 +104,7 @@ enum sssd_errors {
ERR_ADDR_FAMILY_NOT_SUPPORTED,
ERR_SBUS_SENDER_BUS,
ERR_SUBDOM_INACTIVE,
+ ERR_RENEWAL_CHILD,
ERR_LAST /* ALWAYS LAST */
};
--
2.5.0

View File

@ -1,95 +0,0 @@
From 7012e1c6d5571eb75015b679dbadcd14c68d4f58 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 19 Jan 2016 15:04:04 +0100
Subject: [PATCH 42/49] FO: add fo_get_active_server()
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 5a7f17aedad34a8618765bc33342c109a6958ab5)
---
src/providers/fail_over.c | 5 +++++
src/providers/fail_over.h | 2 ++
src/tests/fail_over-tests.c | 11 +++++++++++
3 files changed, 18 insertions(+)
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
index b076687ac6e571f7e27402fd11ac60183ea46951..b51a6c99ce031a1566f5d021fcf41843891a2d1c 100644
--- a/src/providers/fail_over.c
+++ b/src/providers/fail_over.c
@@ -1457,6 +1457,11 @@ fo_set_port_status(struct fo_server *server, enum port_status status)
}
}
+struct fo_server *fo_get_active_server(struct fo_service *service)
+{
+ return service->active_server;
+}
+
void fo_try_next_server(struct fo_service *service)
{
struct fo_server *server;
diff --git a/src/providers/fail_over.h b/src/providers/fail_over.h
index e49c6414a14eb6ca2cad333f8efbb58576811345..b8272a0a16015ff6b5d287b775c33a77e23eba67 100644
--- a/src/providers/fail_over.h
+++ b/src/providers/fail_over.h
@@ -200,6 +200,8 @@ void fo_reset_services(struct fo_ctx *fo_ctx);
void fo_reset_servers(struct fo_service *svc);
+struct fo_server *fo_get_active_server(struct fo_service *service);
+
bool fo_svc_has_server(struct fo_service *service, struct fo_server *server);
/*
diff --git a/src/tests/fail_over-tests.c b/src/tests/fail_over-tests.c
index b21ead38229be5d55df2de10bec3dd00a8566d71..c9bac68711cfcf624064b5881f5226d4f8449e39 100644
--- a/src/tests/fail_over-tests.c
+++ b/src/tests/fail_over-tests.c
@@ -50,6 +50,7 @@ struct test_ctx {
struct task {
struct test_ctx *test_ctx;
const char *location;
+ struct fo_service *service;
int recv;
int port;
int new_server_status;
@@ -147,6 +148,7 @@ test_resolve_service_callback(struct tevent_req *req)
int port;
struct task *task;
struct fo_server *server = NULL;
+ struct fo_server *active_server = NULL;
struct resolv_hostent *he;
int i;
@@ -181,6 +183,13 @@ test_resolve_service_callback(struct tevent_req *req)
}
}
+ if (task->new_port_status == PORT_WORKING
+ && task->new_server_status == SERVER_WORKING) {
+ active_server = fo_get_active_server(task->service);
+ fail_if(active_server == NULL, "Missing active server");
+ fail_if(server != active_server, "Current server is not active server");
+ }
+
}
#define get_request(a, b, c, d, e, f) \
@@ -203,6 +212,7 @@ _get_request(struct test_ctx *test_ctx, struct fo_service *service,
task->new_port_status = new_port_status;
task->new_server_status = new_server_status;
task->location = location;
+ task->service = service;
test_ctx->tasks++;
req = fo_resolve_service_send(test_ctx, test_ctx->ev,
@@ -242,6 +252,7 @@ START_TEST(test_fo_resolve_service)
/* Make requests. */
get_request(ctx, service[0], EOK, 20, PORT_WORKING, -1);
+ get_request(ctx, service[0], EOK, 20, PORT_WORKING, SERVER_WORKING);
get_request(ctx, service[0], EOK, 20, -1, SERVER_NOT_WORKING);
get_request(ctx, service[0], EOK, 80, PORT_WORKING, -1);
get_request(ctx, service[0], EOK, 80, PORT_NOT_WORKING, -1);
--
2.5.0

View File

@ -1,57 +0,0 @@
From ba178abc4f4ddeb0faf65cb779b15e6a95f113fc Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 19 Jan 2016 15:05:03 +0100
Subject: [PATCH 43/49] FO: add be_fo_get_active_server_name()
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 7fdec78178440855058be8ca1011e0b1aa45de31)
---
src/providers/data_provider_fo.c | 17 +++++++++++++++++
src/providers/dp_backend.h | 3 +++
2 files changed, 20 insertions(+)
diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c
index cd57340a0ba0ac7e474dc502bf1f1b4de0e1f778..d1d8c4c5c94811ce73b550dc99166d3c913b95aa 100644
--- a/src/providers/data_provider_fo.c
+++ b/src/providers/data_provider_fo.c
@@ -723,6 +723,23 @@ void be_fo_try_next_server(struct be_ctx *ctx, const char *service_name)
}
}
+const char *be_fo_get_active_server_name(struct be_ctx *ctx,
+ const char *service_name)
+{
+ struct be_svc_data *svc;
+ struct fo_server *server;
+
+ svc = be_fo_find_svc_data(ctx, service_name);
+ if (svc != NULL) {
+ server = fo_get_active_server(svc->fo_service);
+ if (server != NULL) {
+ return fo_get_server_name(server);
+ }
+ }
+
+ return NULL;
+}
+
int be_fo_run_callbacks_at_next_request(struct be_ctx *ctx,
const char *service_name)
{
diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
index 0ced851be8468ce21a9d283e26461fc47194557e..ffeeca4a6bad976ae8922bc4964b839242290259 100644
--- a/src/providers/dp_backend.h
+++ b/src/providers/dp_backend.h
@@ -285,6 +285,9 @@ int be_fo_run_callbacks_at_next_request(struct be_ctx *ctx,
void reset_fo(struct be_ctx *be_ctx);
void be_fo_reset_svc(struct be_ctx *be_ctx, const char *svc_name);
+const char *be_fo_get_active_server_name(struct be_ctx *ctx,
+ const char *service_name);
+
errno_t be_res_init(struct be_ctx *ctx);
/* be_req helpers */
--
2.5.0

View File

@ -1,92 +0,0 @@
From 3e1fe540aa11d653dff45c00f2845c5394706c1b Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 19 Jan 2016 15:05:36 +0100
Subject: [PATCH 44/49] AD: try to use current server in the renewal task
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 8167761a1e1d7575d49babcea45937fc9cd45fdc)
---
src/providers/ad/ad_machine_pw_renewal.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/src/providers/ad/ad_machine_pw_renewal.c b/src/providers/ad/ad_machine_pw_renewal.c
index e42c700e7aa3cf9a45acee025e36899b36642dad..7997fbb0cdaa9490cd4e5c794c9d98e3b892673e 100644
--- a/src/providers/ad/ad_machine_pw_renewal.c
+++ b/src/providers/ad/ad_machine_pw_renewal.c
@@ -31,6 +31,7 @@
#endif
struct renewal_data {
+ struct be_ctx *be_ctx;
char *prog_path;
const char **extra_args;
};
@@ -57,13 +58,16 @@ static errno_t get_adcli_extra_args(const char *ad_domain,
return ENOMEM;
}
- args = talloc_array(renewal_data, const char *, 7);
+ args = talloc_array(renewal_data, const char *, 8);
if (args == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
return ENOMEM;
}
/* extra_args are added in revers order */
+ /* first add NULL as a placeholder for the server name which is determined
+ * at runtime */
+ args[c++] = NULL;
args[c++] = talloc_asprintf(args, "--computer-password-lifetime=%zu",
pw_lifetime_in_days);
args[c++] = talloc_asprintf(args, "--host-fqdn=%s", ad_hostname);
@@ -84,7 +88,7 @@ static errno_t get_adcli_extra_args(const char *ad_domain,
talloc_free(args);
return ENOMEM;
}
- } while (c != 0);
+ } while (c != 1); /* is is expected that the first element is NULL */
renewal_data->extra_args = args;
@@ -123,6 +127,8 @@ ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx,
int pipefd_to_child[2];
int pipefd_from_child[2];
int ret;
+ const char **extra_args;
+ const char *server_name;
req = tevent_req_create(mem_ctx, &state, struct renewal_state);
if (req == NULL) {
@@ -137,6 +143,20 @@ ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx,
state->read_from_child_fd = -1;
state->write_to_child_fd = -1;
+ server_name = be_fo_get_active_server_name(be_ctx, AD_SERVICE_NAME);
+ talloc_zfree(renewal_data->extra_args[0]);
+ if (server_name != NULL) {
+ renewal_data->extra_args[0] = talloc_asprintf(renewal_data->extra_args,
+ "--domain-controller=%s",
+ server_name);
+ /* if talloc_asprintf() fails we let adcli try to find a server */
+ }
+
+ extra_args = renewal_data->extra_args;
+ if (extra_args[0] == NULL) {
+ extra_args = &renewal_data->extra_args[1];
+ }
+
ret = pipe(pipefd_from_child);
if (ret == -1) {
ret = errno;
@@ -156,7 +176,7 @@ ad_machine_account_password_renewal_send(TALLOC_CTX *mem_ctx,
if (child_pid == 0) { /* child */
ret = exec_child_ex(state, pipefd_to_child, pipefd_from_child,
renewal_data->prog_path, -1,
- renewal_data->extra_args, true,
+ extra_args, true,
STDIN_FILENO, STDERR_FILENO);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Could not exec renewal child: [%d][%s].\n",
--
2.5.0

View File

@ -1,37 +0,0 @@
From 62ae069bc8c559f4814f64504335475edc522622 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 19 Jan 2016 13:30:58 +0100
Subject: [PATCH 45/55] sdap_connect_send: fail if uri or sockaddr is NULL
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves:
https://fedorahosted.org/sssd/ticket/2904
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit 8bd9ec3a8885b01a34863d22aa784e221fc422fb)
---
src/providers/ldap/sdap_async_connection.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 8f5227d263f995693f6e65bd238171538aa52af7..85b7aaa5bf5acedf3511ffe6f8636be007d5a136 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -75,6 +75,12 @@ struct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
req = tevent_req_create(memctx, &state, struct sdap_connect_state);
if (!req) return NULL;
+ if (uri == NULL || sockaddr == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid uri or sockaddr\n");
+ ret = EINVAL;
+ goto fail;
+ }
+
state->reply = talloc(state, struct sdap_msg);
if (!state->reply) {
talloc_zfree(req);
--
2.5.0

View File

@ -1,136 +0,0 @@
From 199a9d29c3e56c1c341fb331cfe790b35736a1f2 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Tue, 19 Jan 2016 14:54:45 +0100
Subject: [PATCH 46/55] SDAP: Make it possible to silence errors from
dereference
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://fedorahosted.org/sssd/ticket/2791
When a modern IPA client is connected to an old (3.x) IPA server, the
attribute dereferenced during the ID views lookup does not exist, which
triggers an error during the dereference processing and also a confusing
syslog message.
This patch suppresses the syslog message.
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit 95c132e1a8c6bbab4be8b3a340333fadd8076122)
---
src/providers/ipa/ipa_subdomains.c | 6 +++++-
src/providers/ldap/sdap_async.c | 25 +++++++++++++++++--------
src/providers/ldap/sdap_async.h | 7 ++++++-
3 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index cd78506ffc59c392da4e834c764c9ca82dbc89b0..f13847f12a7eae42b13a51e3fe1d09b60878633b 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -792,6 +792,9 @@ static errno_t ipa_get_view_name(struct ipa_subdomains_req_ctx *ctx)
return EOK;
}
+ /* We add SDAP_DEREF_FLG_SILENT because old IPA servers don't have
+ * the attribute we dereference, causing the deref call to fail
+ */
req = sdap_deref_search_with_filter_send(ctx, ctx->sd_ctx->be_ctx->ev,
ctx->sd_ctx->sdap_id_ctx->opts,
sdap_id_op_handle(ctx->sdap_op),
@@ -799,7 +802,8 @@ static errno_t ipa_get_view_name(struct ipa_subdomains_req_ctx *ctx)
ctx->current_filter, IPA_ASSIGNED_ID_VIEW, attrs,
1, maps,
dp_opt_get_int(ctx->sd_ctx->sdap_id_ctx->opts->basic,
- SDAP_SEARCH_TIMEOUT));
+ SDAP_SEARCH_TIMEOUT),
+ SDAP_DEREF_FLG_SILENT);
if (req == NULL) {
DEBUG(SSSDBG_OP_FAILURE, "sdap_get_generic_send failed.\n");
diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
index 5260aafebf7570291876b2433dbcf44ffb5b0011..6cc32323b4a4c43023a50e10a3a003bc4b2b8994 100644
--- a/src/providers/ldap/sdap_async.c
+++ b/src/providers/ldap/sdap_async.c
@@ -2763,6 +2763,7 @@ struct sdap_deref_search_state {
size_t reply_count;
struct sdap_deref_attrs **reply;
enum sdap_deref_type deref_type;
+ unsigned flags;
};
static void sdap_deref_search_done(struct tevent_req *subreq);
@@ -2779,7 +2780,8 @@ sdap_deref_search_with_filter_send(TALLOC_CTX *memctx,
const char **attrs,
int num_maps,
struct sdap_attr_map_info *maps,
- int timeout)
+ int timeout,
+ unsigned flags)
{
struct tevent_req *req = NULL;
struct tevent_req *subreq = NULL;
@@ -2791,6 +2793,7 @@ sdap_deref_search_with_filter_send(TALLOC_CTX *memctx,
state->sh = sh;
state->reply_count = 0;
state->reply = NULL;
+ state->flags = flags;
if (sdap_is_control_supported(sh, LDAP_CONTROL_X_DEREF)) {
DEBUG(SSSDBG_TRACE_INTERNAL, "Server supports OpenLDAP deref\n");
@@ -2917,14 +2920,20 @@ static void sdap_deref_search_done(struct tevent_req *subreq)
DEBUG(SSSDBG_OP_FAILURE,
"dereference processing failed [%d]: %s\n", ret, strerror(ret));
if (ret == ENOTSUP) {
- sss_log(SSS_LOG_WARNING,
- "LDAP server claims to support deref, but deref search failed. "
- "Disabling deref for further requests. You can permanently "
- "disable deref by setting ldap_deref_threshold to 0 in domain "
- "configuration.");
state->sh->disable_deref = true;
- } else {
- sss_log(SSS_LOG_WARNING, "dereference processing failed : %s", strerror(ret));
+ }
+
+ if (!(state->flags & SDAP_DEREF_FLG_SILENT)) {
+ if (ret == ENOTSUP) {
+ sss_log(SSS_LOG_WARNING,
+ "LDAP server claims to support deref, but deref search "
+ "failed. Disabling deref for further requests. You can "
+ "permanently disable deref by setting "
+ "ldap_deref_threshold to 0 in domain configuration.");
+ } else {
+ sss_log(SSS_LOG_WARNING,
+ "dereference processing failed : %s", strerror(ret));
+ }
}
tevent_req_error(req, ret);
return;
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 09bc0d65407253f93514b30877850cc38009c625..f86f1890bc2971ede4fe70f42154d7bc39c43ac6 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -227,6 +227,10 @@ int sdap_get_generic_recv(struct tevent_req *req,
bool sdap_has_deref_support(struct sdap_handle *sh, struct sdap_options *opts);
+enum sdap_deref_flags {
+ SDAP_DEREF_FLG_SILENT = 1 << 0, /* Do not warn if dereference fails */
+};
+
struct tevent_req *
sdap_deref_search_with_filter_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
@@ -238,7 +242,8 @@ sdap_deref_search_with_filter_send(TALLOC_CTX *memctx,
const char **attrs,
int num_maps,
struct sdap_attr_map_info *maps,
- int timeout);
+ int timeout,
+ unsigned flags);
int sdap_deref_search_with_filter_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx,
size_t *reply_count,
--
2.5.0

View File

@ -1,29 +0,0 @@
From 20623658d24b860b2d13ae2da4a22ce7151394d9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 14 Jan 2016 11:42:26 +0100
Subject: [PATCH 47/55] p11: add gnome-screensaver to list of allowed services
Resolves https://fedorahosted.org/sssd/ticket/2925
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit e9c42ec738c213bd5f351567c20d404a280b32d0)
---
src/responder/pam/pamsrv_p11.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index ea428a6a3dd41b1770b69ff0301ed98c1c08c01d..ad1670136dbf8efc41df6950af744ff8b06e6a11 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -45,7 +45,7 @@ bool may_do_cert_auth(struct pam_ctx *pctx, struct pam_data *pd)
size_t c;
const char *sc_services[] = { "login", "su", "su-l", "gdm-smartcard",
"gdm-password", "kdm", "sudo", "sudo-i",
- NULL };
+ "gnome-screensaver", NULL };
if (!pctx->cert_auth) {
return false;
}
--
2.5.0

View File

@ -1,50 +0,0 @@
From 2fe18a1614007d20ffaa74387e162b5af4dcafb0 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Wed, 13 Jan 2016 09:07:39 -0500
Subject: [PATCH 48/55] IDMAP: Fix computing max id for slice range
Max value of id mapping range was 1 unit too high.
Resolves:
https://fedorahosted.org/sssd/ticket/2922
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 7db89d44b5582a0cb0a61a7aa42a2fac7ca9408f)
---
src/lib/idmap/sss_idmap.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c
index 4c453120539a549807e9b6bb4db2dc396c1b3152..b5457f92dbb91ac5109ad17258920549e8808d26 100644
--- a/src/lib/idmap/sss_idmap.c
+++ b/src/lib/idmap/sss_idmap.c
@@ -336,7 +336,7 @@ enum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx,
}
min = (rangesize * new_slice) + idmap_lower;
- max = min + rangesize;
+ max = min + rangesize - 1;
/* Verify that this slice is not already in use */
do {
for (dom = ctx->idmap_domain_info; dom != NULL; dom = dom->next) {
@@ -353,7 +353,7 @@ enum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx,
}
min = (rangesize * new_slice) + idmap_lower;
- max = min + rangesize;
+ max = min + rangesize - 1;
break;
}
}
@@ -371,7 +371,7 @@ enum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx,
}
_range->min = (rangesize * new_slice) + idmap_lower;
- _range->max = _range->min + rangesize;
+ _range->max = _range->min + rangesize - 1;
if (slice_num) {
*slice_num = new_slice;
--
2.5.0

View File

@ -1,238 +0,0 @@
From 3cc105df9f064a4380dc01010f470025217964e7 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Thu, 26 Nov 2015 10:46:34 -0500
Subject: [PATCH 49/55] IDMAP: New structure for domain range params
Create new internal structure idmap_range_params by merging ID mapping
range relevant fields from idmap_domain_info and remove corrsponding
fields.
Resolves:
https://fedorahosted.org/sssd/ticket/2188
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit c3cdd6a644a870531092e4378cbcd1a428ff514c)
---
src/lib/idmap/sss_idmap.c | 117 ++++++++++++++++++++++++----------------------
1 file changed, 60 insertions(+), 57 deletions(-)
diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c
index b5457f92dbb91ac5109ad17258920549e8808d26..23ed46a583547a3f2f0bca5ab62824bd045e56b9 100644
--- a/src/lib/idmap/sss_idmap.c
+++ b/src/lib/idmap/sss_idmap.c
@@ -33,13 +33,21 @@
#define SID_FMT "%s-%d"
#define SID_STR_MAX_LEN 1024
+/* Hold all parameters for unix<->sid mapping relevant for
+ * given slice. */
+struct idmap_range_params {
+ uint32_t min_id;
+ uint32_t max_id;
+ char *range_id;
+
+ uint32_t first_rid;
+};
+
struct idmap_domain_info {
char *name;
char *sid;
- struct sss_idmap_range *range;
+ struct idmap_range_params range_params;
struct idmap_domain_info *next;
- uint32_t first_rid;
- char *range_id;
bool external_mapping;
};
@@ -72,37 +80,17 @@ static char *idmap_strdup(struct sss_idmap_ctx *ctx, const char *str)
return new;
}
-static struct sss_idmap_range *idmap_range_dup(struct sss_idmap_ctx *ctx,
- struct sss_idmap_range *range)
-{
- struct sss_idmap_range *new = NULL;
-
- CHECK_IDMAP_CTX(ctx, NULL);
-
-
- new = ctx->alloc_func(sizeof(struct sss_idmap_range), ctx->alloc_pvt);
- if (new == NULL) {
- return NULL;
- }
-
- memset(new, 0, sizeof(struct sss_idmap_range));
-
- new->min = range->min;
- new->max = range->max;
-
- return new;
-}
-
-static bool id_is_in_range(uint32_t id, struct idmap_domain_info *dom,
+static bool id_is_in_range(uint32_t id,
+ struct idmap_range_params *rp,
uint32_t *rid)
{
- if (id == 0 || dom == NULL || dom->range == NULL) {
+ if (id == 0 || rp == NULL) {
return false;
}
- if (id >= dom->range->min && id <= dom->range->max) {
+ if (id >= rp->min_id && id <= rp->max_id) {
if (rid != NULL) {
- *rid = dom->first_rid + (id - dom->range->min);
+ *rid = rp->first_rid + (id - rp->min_id);
}
return true;
@@ -220,8 +208,7 @@ static void sss_idmap_free_domain(struct sss_idmap_ctx *ctx,
return;
}
- ctx->free_func(dom->range_id, ctx->alloc_pvt);
- ctx->free_func(dom->range, ctx->alloc_pvt);
+ ctx->free_func(dom->range_params.range_id, ctx->alloc_pvt);
ctx->free_func(dom->name, ctx->alloc_pvt);
ctx->free_func(dom->sid, ctx->alloc_pvt);
ctx->free_func(dom, ctx->alloc_pvt);
@@ -340,9 +327,12 @@ enum idmap_error_code sss_idmap_calculate_range(struct sss_idmap_ctx *ctx,
/* Verify that this slice is not already in use */
do {
for (dom = ctx->idmap_domain_info; dom != NULL; dom = dom->next) {
- if ((dom->range->min <= min && dom->range->max >= max) ||
- (dom->range->min >= min && dom->range->min <= max) ||
- (dom->range->max >= min && dom->range->max <= max)) {
+ uint32_t dmin = dom->range_params.min_id;
+ uint32_t dmax = dom->range_params.max_id;
+
+ if ((dmin <= min && dmax >= max) ||
+ (dmin >= min && dmin <= max) ||
+ (dmax >= min && dmax <= max)) {
/* This range overlaps one already registered
* We'll try the next available slot
*/
@@ -445,10 +435,17 @@ enum idmap_error_code sss_idmap_check_collision(struct sss_idmap_ctx *ctx,
{
struct idmap_domain_info *dom;
enum idmap_error_code err;
+ struct sss_idmap_range range;
for (dom = ctx->idmap_domain_info; dom != NULL; dom = dom->next) {
- err = sss_idmap_check_collision_ex(dom->name, dom->sid, dom->range,
- dom->first_rid, dom->range_id,
+
+ range.min = dom->range_params.min_id;
+ range.max = dom->range_params.max_id;
+
+ err = sss_idmap_check_collision_ex(dom->name, dom->sid,
+ &range,
+ dom->range_params.first_rid,
+ dom->range_params.range_id,
dom->external_mapping,
n_name, n_sid, n_range, n_first_rid,
n_range_id, n_external_mapping);
@@ -459,20 +456,29 @@ enum idmap_error_code sss_idmap_check_collision(struct sss_idmap_ctx *ctx,
return IDMAP_SUCCESS;
}
-static enum idmap_error_code dom_check_collision(
- struct idmap_domain_info *dom_list,
- struct idmap_domain_info *new_dom)
+static enum
+idmap_error_code dom_check_collision(struct idmap_domain_info *dom_list,
+ struct idmap_domain_info *new_dom)
{
struct idmap_domain_info *dom;
enum idmap_error_code err;
+ struct sss_idmap_range range;
+ struct sss_idmap_range new_dom_range = { new_dom->range_params.min_id,
+ new_dom->range_params.max_id };
for (dom = dom_list; dom != NULL; dom = dom->next) {
- err = sss_idmap_check_collision_ex(dom->name, dom->sid, dom->range,
- dom->first_rid, dom->range_id,
+ range.min = dom->range_params.min_id;
+ range.max = dom->range_params.max_id;
+
+ err = sss_idmap_check_collision_ex(dom->name, dom->sid,
+ &range,
+ dom->range_params.first_rid,
+ dom->range_params.range_id,
dom->external_mapping,
new_dom->name, new_dom->sid,
- new_dom->range, new_dom->first_rid,
- new_dom->range_id,
+ &new_dom_range,
+ new_dom->range_params.first_rid,
+ new_dom->range_params.range_id,
new_dom->external_mapping);
if (err != IDMAP_SUCCESS) {
return err;
@@ -531,21 +537,18 @@ enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx,
}
}
- dom->range = idmap_range_dup(ctx, range);
- if (dom->range == NULL) {
- err = IDMAP_OUT_OF_MEMORY;
- goto fail;
- }
+ dom->range_params.min_id = range->min;
+ dom->range_params.max_id = range->max;
if (range_id != NULL) {
- dom->range_id = idmap_strdup(ctx, range_id);
- if (dom->range_id == NULL) {
+ dom->range_params.range_id = idmap_strdup(ctx, range_id);
+ if (dom->range_params.range_id == NULL) {
err = IDMAP_OUT_OF_MEMORY;
goto fail;
}
}
- dom->first_rid = rid;
+ dom->range_params.first_rid = rid;
dom->external_mapping = external_mapping;
err = dom_check_collision(ctx->idmap_domain_info, dom);
@@ -621,10 +624,10 @@ enum idmap_error_code sss_idmap_sid_to_unix(struct sss_idmap_ctx *ctx,
return IDMAP_SID_INVALID;
}
- if (rid >= idmap_domain_info->first_rid) {
- id = idmap_domain_info->range->min
- + (rid - idmap_domain_info->first_rid);
- if (id <= idmap_domain_info->range->max) {
+ if (rid >= idmap_domain_info->range_params.first_rid) {
+ id = idmap_domain_info->range_params.min_id
+ + (rid - idmap_domain_info->range_params.first_rid);
+ if (id <= idmap_domain_info->range_params.max_id) {
*_id = id;
return IDMAP_SUCCESS;
}
@@ -670,8 +673,8 @@ enum idmap_error_code sss_idmap_check_sid_unix(struct sss_idmap_ctx *ctx,
if (strlen(sid) > dom_len && sid[dom_len] == '-'
&& strncmp(sid, idmap_domain_info->sid, dom_len) == 0) {
- if (id >= idmap_domain_info->range->min
- && id <= idmap_domain_info->range->max) {
+ if (id >= idmap_domain_info->range_params.min_id
+ && id <= idmap_domain_info->range_params.max_id) {
return IDMAP_SUCCESS;
}
@@ -700,7 +703,7 @@ enum idmap_error_code sss_idmap_unix_to_sid(struct sss_idmap_ctx *ctx,
idmap_domain_info = ctx->idmap_domain_info;
while (idmap_domain_info != NULL) {
- if (id_is_in_range(id, idmap_domain_info, &rid)) {
+ if (id_is_in_range(id, &idmap_domain_info->range_params, &rid)) {
if (idmap_domain_info->external_mapping == true
|| idmap_domain_info->sid == NULL) {
--
2.5.0

File diff suppressed because it is too large Load Diff

View File

@ -1,108 +0,0 @@
From 931a3a8fe35897552da09d6c0ca90b373538c094 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Mon, 18 Jan 2016 22:02:55 +0100
Subject: [PATCH 51/86] NSS: do not skip cache check for netgoups
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When refresh_expired_interval was not zero,
the NSS responder only refreshed netgroup cache
using background periodic task and ignored
SYSDB_CACHE_EXPIRE attribute.
With this behaviour it was impossible to
get new netgroup from remote server even
after sss_cache tool was used to expire
existing entry in the cache.
Resolves:
https://fedorahosted.org/sssd/ticket/2912
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 1b8858b1611db5048592f477059ca5ad66d7ceb1)
(cherry picked from commit 66c6bf86da1241c3253d23aa7e68850d6ec14d15)
---
src/responder/nss/nsssrv_cmd.c | 47 +++++++++++++++++++++---------------------
1 file changed, 23 insertions(+), 24 deletions(-)
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index b8bd6425e2c937ce6008fd6663fe0312ad68f01e..c6f8284571be382dad5dfda651a25e4df6a14cb1 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -579,10 +579,9 @@ static int nss_cmd_getpw_send_reply(struct nss_dom_ctx *dctx, bool filter)
return EOK;
}
-/* Currently only refreshing expired netgroups is supported. */
static bool
is_refreshed_on_bg(enum sss_dp_acct_type req_type,
- enum sss_dp_acct_type refresh_expired_interval)
+ uint32_t refresh_expired_interval)
{
if (refresh_expired_interval == 0) {
return false;
@@ -590,6 +589,8 @@ is_refreshed_on_bg(enum sss_dp_acct_type req_type,
switch (req_type) {
case SSS_DP_NETGR:
+ case SSS_DP_USER:
+ case SSS_DP_GROUP:
return true;
default:
return false;
@@ -753,31 +754,29 @@ errno_t check_cache(struct nss_dom_ctx *dctx,
get_dp_name_and_id(dctx->cmdctx, dctx->domain, req_type, opt_name, opt_id,
&name, &id);
- /* if we have any reply let's check cache validity, but ignore netgroups
- * if refresh_expired_interval is set (which implies that another method
- * is used to refresh netgroups)
- */
+ /* if we have any reply let's check cache validity */
if (res->count > 0) {
- if (is_refreshed_on_bg(req_type,
- dctx->domain->refresh_expired_interval)) {
- ret = EOK;
+ bool refreshed_on_bg;
+ uint32_t bg_refresh_interval = dctx->domain->refresh_expired_interval;
+
+ if (req_type == SSS_DP_INITGROUPS) {
+ cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+ SYSDB_INITGR_EXPIRE,
+ 0);
} else {
- if (req_type == SSS_DP_INITGROUPS) {
- cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
- SYSDB_INITGR_EXPIRE,
- 0);
- } else {
- cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
- SYSDB_CACHE_EXPIRE,
- 0);
- }
-
- /* if we have any reply let's check cache validity */
- ret = sss_cmd_check_cache(res->msgs[0],
- nctx->cache_refresh_percent,
- cacheExpire);
+ cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+ SYSDB_CACHE_EXPIRE,
+ 0);
}
- if (ret == EOK) {
+
+ /* Check if background refresh is enabled for this entry */
+ refreshed_on_bg = is_refreshed_on_bg(req_type, bg_refresh_interval);
+
+ /* if we have any reply let's check cache validity */
+ ret = sss_cmd_check_cache(res->msgs[0],
+ nctx->cache_refresh_percent,
+ cacheExpire);
+ if (ret == EOK || (ret == EAGAIN && refreshed_on_bg)) {
DEBUG(SSSDBG_TRACE_FUNC, "Cached entry is valid, returning..\n");
return EOK;
} else if (ret != EAGAIN && ret != ENOENT) {
--
2.5.0

View File

@ -1,131 +0,0 @@
From 4a3e2e2d6c6197cd40eec986f581e2a1abb9ef04 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 6 Jan 2016 12:08:18 +0100
Subject: [PATCH 52/86] cache_req: simplify cache_req_cache_check()
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 46f34279204c537a53a0fac7e3fd8022359bfa09)
(cherry picked from commit 97e764f55211c209f2f97debe27f65d0185f4f50)
---
src/responder/common/responder_cache_req.c | 79 ++++++++++++++++++------------
1 file changed, 48 insertions(+), 31 deletions(-)
diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c
index 4ab52b8188859f1143ba1ffa3de03d14ecc028c2..3a436d8e560c36f36553ca6b92204cc47d58dc2e 100644
--- a/src/responder/common/responder_cache_req.c
+++ b/src/responder/common/responder_cache_req.c
@@ -568,6 +568,47 @@ static bool cache_req_bypass_cache(struct cache_req_input *input)
return false;
}
+static errno_t cache_req_expiration_status(struct cache_req_input *input,
+ struct ldb_result *result,
+ time_t cache_refresh_percent)
+{
+ time_t expire;
+
+ if (result == NULL || result->count == 0 || cache_req_bypass_cache(input)) {
+ return ENOENT;
+ }
+
+ if (input->type == CACHE_REQ_INITGROUPS) {
+ expire = ldb_msg_find_attr_as_uint64(result->msgs[0],
+ SYSDB_INITGR_EXPIRE, 0);
+ } else {
+ expire = ldb_msg_find_attr_as_uint64(result->msgs[0],
+ SYSDB_CACHE_EXPIRE, 0);
+ }
+
+ return sss_cmd_check_cache(result->msgs[0], cache_refresh_percent, expire);
+}
+
+static void cache_req_dpreq_params(struct cache_req_input *input,
+ const char **_string,
+ uint32_t *_id,
+ const char **_flag)
+{
+ *_id = input->id;
+ *_string = input->dom_objname;
+
+ if (input->type == CACHE_REQ_USER_BY_CERT) {
+ *_string = input->cert;
+ }
+
+ *_flag = NULL;
+ if (DOM_HAS_VIEWS(input->domain)) {
+ *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
+ } else if (cache_req_input_is_upn(input)) {
+ *_flag = EXTRA_NAME_IS_UPN;
+ }
+}
+
struct cache_req_cache_state {
/* input data */
struct tevent_context *ev;
@@ -669,38 +710,16 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
struct cache_req_cache_state *state = NULL;
struct tevent_req *subreq = NULL;
const char *extra_flag = NULL;
- uint64_t cache_expire = 0;
- errno_t ret;
const char *search_str;
+ uint32_t search_id;
+ errno_t ret;
state = tevent_req_data(req, struct cache_req_cache_state);
- if (state->result == NULL || state->result->count == 0 ||
- cache_req_bypass_cache(state->input) == true) {
- ret = ENOENT;
- } else {
- if (state->input->type == CACHE_REQ_INITGROUPS) {
- cache_expire = ldb_msg_find_attr_as_uint64(state->result->msgs[0],
- SYSDB_INITGR_EXPIRE, 0);
- } else {
- cache_expire = ldb_msg_find_attr_as_uint64(state->result->msgs[0],
- SYSDB_CACHE_EXPIRE, 0);
- }
+ cache_req_dpreq_params(state->input, &search_str, &search_id, &extra_flag);
- ret = sss_cmd_check_cache(state->result->msgs[0],
- state->cache_refresh_percent, cache_expire);
- }
-
- search_str = state->input->dom_objname;
- if (state->input->type == CACHE_REQ_USER_BY_CERT) {
- search_str = state->input->cert;
- }
-
- if (DOM_HAS_VIEWS(state->input->domain)) {
- extra_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
- } else if (cache_req_input_is_upn(state->input)) {
- extra_flag = EXTRA_NAME_IS_UPN;
- }
+ ret = cache_req_expiration_status(state->input, state->result,
+ state->cache_refresh_percent);
switch (ret) {
case EOK:
@@ -715,8 +734,7 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
subreq = sss_dp_get_account_send(state, state->rctx,
state->input->domain, true,
state->input->dp_type,
- search_str,
- state->input->id, extra_flag);
+ search_str, search_id, extra_flag);
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band "
"data provider request\n");
@@ -733,8 +751,7 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
subreq = sss_dp_get_account_send(state, state->rctx,
state->input->domain, true,
state->input->dp_type,
- search_str,
- state->input->id, extra_flag);
+ search_str, search_id, extra_flag);
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
"Out of memory sending data provider request\n");
--
2.5.0

View File

@ -1,146 +0,0 @@
From 6d3c0f1d269193c366945dcdaeff45dd139230cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Wed, 6 Jan 2016 12:45:38 +0100
Subject: [PATCH 53/86] cache_req: do not lookup views if possible
This is needed for LOCAL view but also creates a shortcut for
server side overrides.
Resolves:
https://fedorahosted.org/sssd/ticket/2849
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 5f2b1986a16a394ecbecd16f82c7265b5b47b546)
(cherry picked from commit f840cfd6c2ad61045160f301d6ae7276e3e33f54)
---
src/responder/common/responder_cache_req.c | 98 +++++++++++++++++++++++++++---
1 file changed, 88 insertions(+), 10 deletions(-)
diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c
index 3a436d8e560c36f36553ca6b92204cc47d58dc2e..2344b0f09c6c4242ff3f769ae565f21c1d2b3e3b 100644
--- a/src/responder/common/responder_cache_req.c
+++ b/src/responder/common/responder_cache_req.c
@@ -589,24 +589,101 @@ static errno_t cache_req_expiration_status(struct cache_req_input *input,
return sss_cmd_check_cache(result->msgs[0], cache_refresh_percent, expire);
}
-static void cache_req_dpreq_params(struct cache_req_input *input,
+static void cache_req_dpreq_params(TALLOC_CTX *mem_ctx,
+ struct cache_req_input *input,
+ struct ldb_result *result,
const char **_string,
uint32_t *_id,
const char **_flag)
{
+ struct ldb_result *user = NULL;
+ const char *name = NULL;
+ uint32_t id = 0;
+ errno_t ret;
+
*_id = input->id;
*_string = input->dom_objname;
-
- if (input->type == CACHE_REQ_USER_BY_CERT) {
- *_string = input->cert;
- }
-
*_flag = NULL;
- if (DOM_HAS_VIEWS(input->domain)) {
- *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
- } else if (cache_req_input_is_upn(input)) {
+
+ if (cache_req_input_is_upn(input)) {
*_flag = EXTRA_NAME_IS_UPN;
+ return;
}
+
+ if (input->type == CACHE_REQ_USER_BY_CERT) {
+ *_string = input->cert;
+ return;
+ }
+
+ if (!DOM_HAS_VIEWS(input->domain)) {
+ return;
+ }
+
+ /* We must search with views. */
+ if (result == NULL || result->count == 0) {
+ *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
+ return;
+ }
+
+ /* If domain has views we will try to user original values instead of the
+ * overridden ones. This is a must for the LOCAL view since we can't look
+ * it up otherwise. But it is also a shortcut for non-local views where
+ * we will not fail over to the overridden value. */
+
+ switch (input->type) {
+ case CACHE_REQ_USER_BY_NAME:
+ case CACHE_REQ_GROUP_BY_NAME:
+ name = ldb_msg_find_attr_as_string(result->msgs[0], SYSDB_NAME, NULL);
+ if (name == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL\n");
+ }
+ break;
+ case CACHE_REQ_USER_BY_ID:
+ id = ldb_msg_find_attr_as_uint64(result->msgs[0], SYSDB_UIDNUM, 0);
+ if (id == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0\n");
+ }
+ break;
+ case CACHE_REQ_GROUP_BY_ID:
+ id = ldb_msg_find_attr_as_uint64(result->msgs[0], SYSDB_GIDNUM, 0);
+ if (id == 0) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: id cannot be 0\n");
+ }
+ break;
+ case CACHE_REQ_INITGROUPS:
+ ret = sysdb_getpwnam_with_views(NULL, input->domain,
+ input->dom_objname, &user);
+ if (ret != EOK || user == NULL || user->count != 1) {
+ /* Case where the user is not found has been already handled. If
+ * this is not OK, it is an error. */
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to match initgroups user "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ break;
+ }
+
+ name = ldb_msg_find_attr_as_string(user->msgs[0], SYSDB_NAME,
+ NULL);
+ if (name == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: name cannot be NULL\n");
+ break;
+ }
+
+ talloc_steal(mem_ctx, name);
+ talloc_free(user);
+ break;
+ default:
+ return;
+ }
+
+ /* Now we have the original name and id. We don't have to search with
+ * views unless some error occurred. */
+ if (name == NULL && id == 0) {
+ *_flag = EXTRA_INPUT_MAYBE_WITH_VIEW;
+ return;
+ }
+
+ *_string = talloc_steal(mem_ctx, name);
+ *_id = id;
}
struct cache_req_cache_state {
@@ -716,7 +793,8 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
state = tevent_req_data(req, struct cache_req_cache_state);
- cache_req_dpreq_params(state->input, &search_str, &search_id, &extra_flag);
+ cache_req_dpreq_params(state, state->input, state->result,
+ &search_str, &search_id, &extra_flag);
ret = cache_req_expiration_status(state->input, state->result,
state->cache_refresh_percent);
--
2.5.0

View File

@ -1,54 +0,0 @@
From 521ef4f7839216e19ad93420f0464ba969fead8b Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 22 Jan 2016 12:30:23 -0500
Subject: [PATCH 54/86] IDMAP: Fix minor memory leak
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit 5554a2a679f72f19f266d660a5681e3b0c657379)
(cherry picked from commit fe8d58c75da2b9b3704bb2ae19f8014323797757)
---
src/lib/idmap/sss_idmap.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/lib/idmap/sss_idmap.c b/src/lib/idmap/sss_idmap.c
index 269ef0132ff3b9ffbfbe65006361fac6d4f88cf9..e3e9972b802748770a5f7440fa8ddc8ba75d3362 100644
--- a/src/lib/idmap/sss_idmap.c
+++ b/src/lib/idmap/sss_idmap.c
@@ -607,13 +607,13 @@ get_helpers(struct sss_idmap_ctx *ctx,
for (int i = 0; i < ctx->idmap_opts.extra_slice_init; i++) {
secondary_name = generate_sec_slice_name(ctx, domain_sid, first_rid);
if (secondary_name == NULL) {
- return IDMAP_OUT_OF_MEMORY;
+ err = IDMAP_OUT_OF_MEMORY;
+ goto fail;
}
err = generate_slice(ctx, secondary_name, first_rid, &slice);
if (err != IDMAP_SUCCESS) {
- ctx->free_func(secondary_name, ctx->alloc_pvt);
- return err;
+ goto fail;
}
first_rid += ctx->idmap_opts.rangesize;
@@ -631,6 +631,14 @@ get_helpers(struct sss_idmap_ctx *ctx,
*_sec_slices = sec_slices;
return IDMAP_SUCCESS;
+
+fail:
+ ctx->free_func(secondary_name, ctx->alloc_pvt);
+
+ /* Free already generated helpers. */
+ free_helpers(ctx, sec_slices, true);
+
+ return err;
}
enum idmap_error_code sss_idmap_add_domain_ex(struct sss_idmap_ctx *ctx,
--
2.5.0

View File

@ -1,30 +0,0 @@
From 92281a16d6e8988dec661fe40eac6361b7bcfb4a Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 1 Feb 2016 09:34:08 +0100
Subject: [PATCH 55/86] CONFIGURE: Replace obsoleted macro AC_PROG_LIBTOOL
The AC_PROG_LIBTOOL macro is obsoleted since libtool 2.0
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 700d45751e997c634504a4f22facd2edf82edea7)
(cherry picked from commit dba300fe84fe40919a17a82bc4f4b9b672ed195d)
---
configure.ac | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index 1ab64765968e9ffe94da9075496be2491bf33e9a..8ef2493c79a144d348200213f0ce1681d0fa3c1f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,7 +19,7 @@ AM_PROG_CC_C_O
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_DISABLE_STATIC
AC_PROG_INSTALL
-AC_PROG_LIBTOOL
+LT_INIT
m4_ifdef([AC_PROG_MKDIR_P],
[AC_PROG_MKDIR_P],
[AC_SUBST([MKDIR_P], "mkdir -p")])
--
2.5.0

View File

@ -1,146 +0,0 @@
From c53781ec735a14c346fa111749ac02030e550fb5 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 13 Jan 2016 15:06:06 +0100
Subject: [PATCH 56/86] TESTS: Fix race condition in python test
Python tests for pyhbac and pysss_murmur created symbolic
links in shared directory ".libs". It happened that both
tests created symbolic link in the same time and therefore
python2 test could try to import link to python3 module
which caused failures in tests.
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 9e1de5c83371d91e200254cceef70852f5f94fd2)
(cherry picked from commit 94bafaad2401bc647a31a22953ad2d985c88b06e)
---
src/tests/pyhbac-test.py | 33 ++++++++++++++++-----------------
src/tests/pysss_murmur-test.py | 33 ++++++++++++++++-----------------
2 files changed, 32 insertions(+), 34 deletions(-)
diff --git a/src/tests/pyhbac-test.py b/src/tests/pyhbac-test.py
index 9d8fd1a333bf54ecf21d14d3b6293f7294a0d53e..09867311ed42cad1e3b44e10616edb084716ce10 100755
--- a/src/tests/pyhbac-test.py
+++ b/src/tests/pyhbac-test.py
@@ -5,11 +5,12 @@ import unittest
import sys
import os
import copy
-import sys
-import errno
+import tempfile
+
+BUILD_DIR = os.getenv('builddir') or "."
+TEST_DIR = os.getenv('SSS_TEST_DIR') or "."
+MODPATH = tempfile.mkdtemp(prefix="tp_pyhbac_", dir=TEST_DIR)
-srcdir = os.getenv('builddir') or "."
-MODPATH = srcdir + "/.libs" #FIXME - is there a way to get this from libtool?
if sys.version_info[0] > 2:
unicode = str
@@ -40,22 +41,15 @@ class PyHbacImport(unittest.TestCase):
def testImport(self):
" Import the module and assert it comes from tree "
try:
- cwd_backup = os.getcwd()
+ dest_module_path = MODPATH + "/pyhbac.so"
- try:
- os.unlink(MODPATH + "/pyhbac.so")
- except OSError as e:
- if e.errno == errno.ENOENT:
- pass
- else:
- raise e
-
- os.chdir(MODPATH)
if sys.version_info[0] > 2:
- os.symlink("_py3hbac.so", "pyhbac.so")
+ src_module_path = BUILD_DIR + "/.libs/_py3hbac.so"
else:
- os.symlink("_py2hbac.so", "pyhbac.so")
- os.chdir(cwd_backup)
+ src_module_path = BUILD_DIR + "/.libs/_py2hbac.so"
+
+ src_module_path = os.path.abspath(src_module_path)
+ os.symlink(src_module_path, dest_module_path)
import pyhbac
except ImportError as e:
@@ -456,6 +450,11 @@ class PyHbacRequestTest(unittest.TestCase):
self.assertRaises(TypeError, req.evaluate, (allow_rule, None))
class PyHbacModuleTest(unittest.TestCase):
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(MODPATH + "/pyhbac.so")
+ os.rmdir(MODPATH)
+
def testHasResultTypes(self):
assert hasattr(pyhbac, "HBAC_EVAL_ALLOW")
assert hasattr(pyhbac, "HBAC_EVAL_DENY")
diff --git a/src/tests/pysss_murmur-test.py b/src/tests/pysss_murmur-test.py
index faa8bb2d33b9d94d380b8f7045ba45aa06ac4793..1cbbe4d03172804ef16b630d3dd1c3a22e09a20a 100755
--- a/src/tests/pysss_murmur-test.py
+++ b/src/tests/pysss_murmur-test.py
@@ -22,11 +22,12 @@ from __future__ import print_function
import unittest
import sys
import os
-import copy
-import errno
+import tempfile
+
+BUILD_DIR = os.getenv('builddir') or "."
+TEST_DIR = os.getenv('SSS_TEST_DIR') or "."
+MODPATH = tempfile.mkdtemp(prefix="tp_pysss_murmur_", dir=TEST_DIR)
-srcdir = os.getenv('builddir') or "."
-MODPATH = srcdir + "/.libs" #FIXME - is there a way to get this from libtool?
def compat_assertItemsEqual(this, expected_seq, actual_seq, msg=None):
return this.assertEqual(sorted(expected_seq), sorted(actual_seq))
@@ -56,22 +57,15 @@ class PySssMurmurImport(unittest.TestCase):
def testImport(self):
" Import the module and assert it comes from tree "
try:
- cwd_backup = os.getcwd()
+ dest_module_path = MODPATH + "/pysss_murmur.so"
- try:
- os.unlink(MODPATH + "/pysss_murmur.so")
- except OSError as e:
- if e.errno == errno.ENOENT:
- pass
- else:
- raise e
-
- os.chdir(MODPATH)
if sys.version_info[0] > 2:
- os.symlink("_py3sss_murmur.so", "pysss_murmur.so")
+ src_module_path = BUILD_DIR + "/.libs/_py3sss_murmur.so"
else:
- os.symlink("_py2sss_murmur.so", "pysss_murmur.so")
- os.chdir(cwd_backup)
+ src_module_path = BUILD_DIR + "/.libs/_py2sss_murmur.so"
+
+ src_module_path = os.path.abspath(src_module_path)
+ os.symlink(src_module_path, dest_module_path)
import pysss_murmur
except ImportError as e:
@@ -80,6 +74,11 @@ class PySssMurmurImport(unittest.TestCase):
self.assertEqual(pysss_murmur.__file__, MODPATH + "/pysss_murmur.so")
class PySssMurmurTest(unittest.TestCase):
+ @classmethod
+ def tearDownClass(cls):
+ os.unlink(MODPATH + "/pysss_murmur.so")
+ os.rmdir(MODPATH)
+
def testExpectedHash(self):
hash = pysss_murmur.murmurhash3("S-1-5-21-2153326666-2176343378-3404031434", 41, 0xdeadbeef)
self.assertEqual(hash, 93103853)
--
2.5.0

View File

@ -1,100 +0,0 @@
From 8fc61f5bba2f8c06b0d86d177f2e11d5c7f5d874 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 27 Jan 2016 16:02:33 +0100
Subject: [PATCH 57/86] PYTHON: sss_obfuscate should work with python3
Based on patch from: Steven W. Elling <ellingsw+29044@gmail.com>
Resolves:
https://fedorahosted.org/sssd/ticket/2937
Reviewed-by: Martin Basti <mbasti@redhat.com>
(cherry picked from commit 11496692da75a330de01d5f15b7183d2439efd3c)
(cherry picked from commit 683b9d012117016483b99620c333be666a6c888e)
---
src/tools/sss_obfuscate | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/src/tools/sss_obfuscate b/src/tools/sss_obfuscate
index fbea1213d8f7e99ab3b1a6d7d24accf8a6194094..68ef30e386ced95b85afbea87696e3c69bea7b51 100644
--- a/src/tools/sss_obfuscate
+++ b/src/tools/sss_obfuscate
@@ -1,5 +1,7 @@
#!/usr/bin/python
+from __future__ import print_function
+
import sys
from optparse import OptionParser
@@ -33,11 +35,11 @@ def parse_options():
def main():
options, args = parse_options()
if not options:
- print >> sys.stderr, "Cannot parse options"
+ print("Cannot parse options", file=sys.stderr)
return 1
if not options.domain:
- print >> sys.stderr, "No domain specified"
+ print("No domain specified", file=sys.stderr)
return 1
if not options.stdin:
@@ -59,7 +61,8 @@ def main():
password = p1
except EOFError:
- print >> sys.stderr, '\nUnexpected end-of-file. Password change aborted'
+ print('\nUnexpected end-of-file. Password change aborted',
+ file=sys.stderr)
return 1
except KeyboardInterrupt:
return 1
@@ -78,26 +81,26 @@ def main():
try:
sssdconfig = SSSDConfig.SSSDConfig()
except IOError:
- print "Cannot read internal configuration files."
+ print("Cannot read internal configuration files.")
return 1
try:
sssdconfig.import_config(options.filename)
except IOError:
- print "Permissions error reading config file"
+ print("Permissions error reading config file")
return 1
try:
domain = sssdconfig.get_domain(options.domain)
except SSSDConfig.NoDomainError:
- print "No such domain %s" % options.domain
+ print("No such domain %s" % options.domain)
return 1
try:
domain.set_option('ldap_default_authtok_type', 'obfuscated_password')
domain.set_option('ldap_default_authtok', obfpwd)
except SSSDConfig.NoOptionError:
- print "The domain %s does not seem to support the required options" % \
- options.domain
+ print("The domain %s does not seem to support the required options"
+ % options.domain)
return 1
@@ -106,9 +109,8 @@ def main():
sssdconfig.write()
except IOError:
# File could not be written
- print >> sys.stderr, "Could not write to config file. Check that " \
- "you have the appropriate permissions to edit " \
- "this file."
+ print("Could not write to config file. Check that you have the "
+ "appropriate permissions to edit this file.", file=sys.stderr)
return 1
return 0
--
2.5.0

View File

@ -1,82 +0,0 @@
From 1d7742a2b98c1494af2ce1c3eb3d6850ea1e78e9 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 27 Jan 2016 17:49:45 +0100
Subject: [PATCH 58/86] PYTHON: Fix pep8 errors in sss_obfuscate
src/tools/sss_obfuscate:12:1: E302 expected 2 blank lines, found 1
src/tools/sss_obfuscate:29:80: E501 line too long (111 > 79 characters)
src/tools/sss_obfuscate:35:1: E302 expected 2 blank lines, found 1
src/tools/sss_obfuscate:47:80: E501 line too long (107 > 79 characters)
src/tools/sss_obfuscate:50:13: E265 block comment should start with '# '
src/tools/sss_obfuscate:58:17: E265 block comment should start with '# '
src/tools/sss_obfuscate:107:5: E303 too many blank lines (2)
Reviewed-by: Martin Basti <mbasti@redhat.com>
(cherry picked from commit 37ea8e70fa13ff9ba563300fb15de0e5e6185d68)
(cherry picked from commit f61eb0c92251dbe65a2868aa1ded470d1f2739c8)
---
src/tools/sss_obfuscate | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/src/tools/sss_obfuscate b/src/tools/sss_obfuscate
index 68ef30e386ced95b85afbea87696e3c69bea7b51..5981e81410af68fd8123781a5e21a0c7fa3bcb23 100644
--- a/src/tools/sss_obfuscate
+++ b/src/tools/sss_obfuscate
@@ -9,6 +9,7 @@ import pysss
import SSSDConfig
import getpass
+
def parse_options():
parser = OptionParser()
parser.set_description("sss_obfuscate converts a given password into \
@@ -26,12 +27,14 @@ def parse_options():
metavar="DOMNAME")
parser.add_option("-f", "--file",
dest="filename", default=None,
- help="Set input file to FILE (default: Use system default, usually /etc/sssd/sssd.conf)",
+ help="Set input file to FILE (default: Use system "
+ "default, usually /etc/sssd/sssd.conf)",
metavar="FILE")
(options, args) = parser.parse_args()
return options, args
+
def main():
options, args = parse_options()
if not options:
@@ -44,10 +47,11 @@ def main():
if not options.stdin:
try:
- pprompt = lambda: (getpass.getpass("Enter password: "), getpass.getpass("Re-enter password: "))
+ pprompt = lambda: (getpass.getpass("Enter password: "),
+ getpass.getpass("Re-enter password: "))
p1, p2 = pprompt()
- #Work around bug in Python 2.6
+ # Work around bug in Python 2.6
if '\x03' in p1 or '\x03' in p2:
raise KeyboardInterrupt
@@ -55,7 +59,7 @@ def main():
print('Passwords do not match. Try again')
p1, p2 = pprompt()
- #Work around bug in Python 2.6
+ # Work around bug in Python 2.6
if '\x03' in p1 or '\x03' in p2:
raise KeyboardInterrupt
password = p1
@@ -103,7 +107,6 @@ def main():
% options.domain)
return 1
-
sssdconfig.save_domain(domain)
try:
sssdconfig.write()
--
2.5.0

View File

@ -1,37 +0,0 @@
From 33a029f9d2b55887fef08676234bebc4b6b5f7e4 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Thu, 28 Jan 2016 05:03:40 -0500
Subject: [PATCH 59/86] IDMAP: Man change for ldap_idmap_range_size option
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves:
https://fedorahosted.org/sssd/ticket/2922
Reviewed-by: Nathaniel McCallum <npmccallum@redhat.com>
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit d9de4b26f44a344025bbfa23104b7b67935fae35)
(cherry picked from commit c2fa17edf4b9d385302ddd24ce599a1cef7250a6)
---
src/man/include/ldap_id_mapping.xml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/man/include/ldap_id_mapping.xml b/src/man/include/ldap_id_mapping.xml
index a088c4e81d81c5670edea8ae8081abe80927446a..9252b1caa56b086b640ab0b2a79069616cef6443 100644
--- a/src/man/include/ldap_id_mapping.xml
+++ b/src/man/include/ldap_id_mapping.xml
@@ -178,7 +178,9 @@ ldap_schema = ad
<para>
For example, if your most recently-added Active Directory user has
objectSid=S-1-5-21-2153326666-2176343378-3404031434-1107,
- <quote>ldap_idmap_range_size</quote> must be at least 1107.
+ <quote>ldap_idmap_range_size</quote> must be at least 1108 as
+ range size is equal to maximal SID minus minimal SID plus one
+ (e.g. 1108 = 1107 - 0 + 1).
</para>
<para>
It is important to plan ahead for future expansion, as changing this
--
2.5.0

View File

@ -1,107 +0,0 @@
From df9da4a4d83e1ebc235a2b5ead445e0a406c1234 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 27 Nov 2015 07:53:00 -0500
Subject: [PATCH 60/86] NSS: Fix memory leak netgroup
Resolves:
https://fedorahosted.org/sssd/ticket/2865
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 4231a17e66e0809a9c3d42207b45f95429cbb46c)
(cherry picked from commit 3bca87239e3368d61c25f2f6bd2329191eca0dee)
---
src/responder/nss/nsssrv_netgroup.c | 41 ++++++++++++++++++++++++++-----------
1 file changed, 29 insertions(+), 12 deletions(-)
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 9a78c1119c2f4e06e43ebec29ace775adc997e08..383b44a2c9b1fb87d3abfdce071b226a561e22a7 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -435,14 +435,18 @@ static errno_t create_negcache_netgr(struct setent_step_ctx *step_ctx)
errno_t ret;
struct getent_ctx *netgr;
- netgr = talloc_zero(step_ctx->nctx, struct getent_ctx);
- if (netgr == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
- ret = ENOMEM;
- goto done;
- } else {
- netgr->ready = true;
- netgr->found = false;
+ /* Is there already netgroup with such name? */
+ ret = get_netgroup_entry(step_ctx->nctx, step_ctx->name,
+ &netgr);
+ if (ret != EOK || netgr == NULL) {
+
+ netgr = talloc_zero(step_ctx->nctx, struct getent_ctx);
+ if (netgr == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_zero failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
netgr->entries = NULL;
netgr->lookup_table = step_ctx->nctx->netgroups;
netgr->name = talloc_strdup(netgr, step_ctx->name);
@@ -457,13 +461,20 @@ static errno_t create_negcache_netgr(struct setent_step_ctx *step_ctx)
DEBUG(SSSDBG_CRIT_FAILURE, "set_netgroup_entry failed.\n");
goto done;
}
- set_netgr_lifetime(step_ctx->nctx->neg_timeout, step_ctx, netgr);
}
+ netgr->ready = true;
+ netgr->found = false;
+
+ set_netgr_lifetime(step_ctx->nctx->neg_timeout, step_ctx, netgr);
+
+ ret = EOK;
+
done:
if (ret != EOK) {
talloc_free(netgr);
}
+
return ret;
}
@@ -474,6 +485,12 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
struct getent_ctx *netgr;
char *name = NULL;
uint32_t lifetime;
+ TALLOC_CTX *tmp_ctx;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
/* Check each domain for this netgroup name */
while (dom) {
@@ -494,8 +511,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
/* make sure to update the dctx if we changed domain */
step_ctx->dctx->domain = dom;
- talloc_free(name);
- name = sss_get_cased_name(step_ctx, step_ctx->name,
+ name = sss_get_cased_name(tmp_ctx, step_ctx->name,
dom->case_sensitive);
if (!name) {
DEBUG(SSSDBG_CRIT_FAILURE, "sss_get_cased_name failed\n");
@@ -623,10 +639,11 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
"create_negcache_netgr failed with: %d:[%s], ignored.\n",
ret, sss_strerror(ret));
}
+
ret = ENOENT;
done:
- talloc_free(name);
+ talloc_free(tmp_ctx);
return ret;
}
--
2.5.0

View File

@ -1,189 +0,0 @@
From e3e319e537e6def0248351118f3801213b5a2475 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 22 Jan 2016 08:34:14 -0500
Subject: [PATCH 61/86] IDMAP: Add test to validate off by one bug
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves:
https://fedorahosted.org/sssd/ticket/2922
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit 9d17f436795a36b1b1126f444923aa847fd0f93a)
(cherry picked from commit 8c1f3b27d8e20b271dfea0c41fd864e9af5476f5)
---
src/tests/cmocka/test_sss_idmap.c | 113 ++++++++++++++++++++++++++++++++++++--
1 file changed, 109 insertions(+), 4 deletions(-)
diff --git a/src/tests/cmocka/test_sss_idmap.c b/src/tests/cmocka/test_sss_idmap.c
index 00e03ffd9ab1532fb55795b9935b254c8a89ec16..f82e3dc51601850a480cf1daa6d5f6dbd940ddcb 100644
--- a/src/tests/cmocka/test_sss_idmap.c
+++ b/src/tests/cmocka/test_sss_idmap.c
@@ -43,6 +43,9 @@
#define TEST_OFFSET 1000000
#define TEST_OFFSET_STR "1000000"
+const int TEST_2922_MIN_ID = 1842600000;
+const int TEST_2922_MAX_ID = 1842799999;
+
struct test_ctx {
TALLOC_CTX *mem_idmap;
struct sss_idmap_ctx *idmap_ctx;
@@ -128,7 +131,38 @@ static int setup_ranges(struct test_ctx *test_ctx, bool external_mapping,
return 0;
}
-static int test_sss_idmap_setup_with_domains(void **state) {
+static int setup_ranges_2922(struct test_ctx *test_ctx)
+{
+ const int TEST_2922_DFL_SLIDE = 9212;
+ struct sss_idmap_range range;
+ enum idmap_error_code err;
+ const char *name;
+ const char *sid;
+ /* Pick a new slice. */
+ id_t slice_num = -1;
+
+ assert_non_null(test_ctx);
+
+ name = TEST_DOM_NAME;
+ sid = TEST_DOM_SID;
+
+ err = sss_idmap_calculate_range(test_ctx->idmap_ctx, sid, &slice_num,
+ &range);
+ assert_int_equal(err, IDMAP_SUCCESS);
+ /* Range computation should be deterministic. Lets validate that. */
+ assert_int_equal(range.min, TEST_2922_MIN_ID);
+ assert_int_equal(range.max, TEST_2922_MAX_ID);
+ assert_int_equal(slice_num, TEST_2922_DFL_SLIDE);
+
+ err = sss_idmap_add_domain_ex(test_ctx->idmap_ctx, name, sid, &range,
+ NULL, 0, false /* No external mapping */);
+ assert_int_equal(err, IDMAP_SUCCESS);
+
+ return 0;
+}
+
+static int test_sss_idmap_setup_with_domains(void **state)
+{
struct test_ctx *test_ctx;
test_sss_idmap_setup(state);
@@ -140,7 +174,21 @@ static int test_sss_idmap_setup_with_domains(void **state) {
return 0;
}
-static int test_sss_idmap_setup_with_domains_sec_slices(void **state) {
+static int test_sss_idmap_setup_with_domains_2922(void **state)
+{
+ struct test_ctx *test_ctx;
+
+ test_sss_idmap_setup(state);
+
+ test_ctx = talloc_get_type(*state, struct test_ctx);
+ assert_non_null(test_ctx);
+
+ setup_ranges_2922(test_ctx);
+ return 0;
+}
+
+static int test_sss_idmap_setup_with_domains_sec_slices(void **state)
+{
struct test_ctx *test_ctx;
test_sss_idmap_setup(state);
@@ -152,7 +200,8 @@ static int test_sss_idmap_setup_with_domains_sec_slices(void **state) {
return 0;
}
-static int test_sss_idmap_setup_with_external_mappings(void **state) {
+static int test_sss_idmap_setup_with_external_mappings(void **state)
+{
struct test_ctx *test_ctx;
test_sss_idmap_setup(state);
@@ -164,7 +213,8 @@ static int test_sss_idmap_setup_with_external_mappings(void **state) {
return 0;
}
-static int test_sss_idmap_setup_with_both(void **state) {
+static int test_sss_idmap_setup_with_both(void **state)
+{
struct test_ctx *test_ctx;
test_sss_idmap_setup(state);
@@ -298,6 +348,58 @@ void test_map_id(void **state)
sss_idmap_free_sid(test_ctx->idmap_ctx, sid);
}
+/* https://fedorahosted.org/sssd/ticket/2922 */
+/* ID mapping - bug in computing max id for slice range */
+void test_map_id_2922(void **state)
+{
+ const char* TEST_2922_FIRST_SID = TEST_DOM_SID"-0";
+ /* Last SID = first SID + (default) rangesize -1 */
+ const char* TEST_2922_LAST_SID = TEST_DOM_SID"-199999";
+ /* Last SID = first SID + rangesize */
+ const char* TEST_2922_LAST_SID_PLUS_ONE = TEST_DOM_SID"-200000";
+ struct test_ctx *test_ctx;
+ enum idmap_error_code err;
+ uint32_t id;
+ char *sid = NULL;
+
+ test_ctx = talloc_get_type(*state, struct test_ctx);
+
+ assert_non_null(test_ctx);
+
+ /* Min UNIX ID to SID */
+ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_2922_MIN_ID, &sid);
+ assert_int_equal(err, IDMAP_SUCCESS);
+ assert_string_equal(sid, TEST_2922_FIRST_SID);
+ sss_idmap_free_sid(test_ctx->idmap_ctx, sid);
+
+ /* First SID to UNIX ID */
+ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_2922_FIRST_SID, &id);
+ assert_int_equal(err, IDMAP_SUCCESS);
+ assert_int_equal(id, TEST_2922_MIN_ID);
+
+ /* Max UNIX ID to SID */
+ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_2922_MAX_ID, &sid);
+ assert_int_equal(err, IDMAP_SUCCESS);
+ assert_string_equal(sid, TEST_2922_LAST_SID);
+ sss_idmap_free_sid(test_ctx->idmap_ctx, sid);
+
+ /* Last SID to UNIX ID */
+ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx, TEST_2922_LAST_SID, &id);
+ assert_int_equal(err, IDMAP_SUCCESS);
+ assert_int_equal(id, TEST_2922_MAX_ID);
+
+ /* Max UNIX ID + 1 to SID */
+ err = sss_idmap_unix_to_sid(test_ctx->idmap_ctx, TEST_2922_MAX_ID + 1,
+ &sid);
+ assert_int_equal(err, IDMAP_NO_DOMAIN);
+
+ /* Last SID + 1 to UNIX ID */
+ err = sss_idmap_sid_to_unix(test_ctx->idmap_ctx,
+ TEST_2922_LAST_SID_PLUS_ONE, &id);
+ /* Auto adding new ranges is disable in this test. */
+ assert_int_equal(err, IDMAP_NO_RANGE);
+}
+
void test_map_id_sec_slices(void **state)
{
struct test_ctx *test_ctx;
@@ -589,6 +691,9 @@ int main(int argc, const char *argv[])
cmocka_unit_test_setup_teardown(test_map_id,
test_sss_idmap_setup_with_domains,
test_sss_idmap_teardown),
+ cmocka_unit_test_setup_teardown(test_map_id_2922,
+ test_sss_idmap_setup_with_domains_2922,
+ test_sss_idmap_teardown),
cmocka_unit_test_setup_teardown(test_map_id_sec_slices,
test_sss_idmap_setup_with_domains_sec_slices,
test_sss_idmap_teardown),
--
2.5.0

View File

@ -1,119 +0,0 @@
From 4f1dec56127c91c02908f40161cde42313ff93e4 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 5 Feb 2016 07:27:38 -0500
Subject: [PATCH 62/86] SDAP: Add return code ERR_ACCOUNT_LOCKED
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add code to distinquish state when account is locked in Active
Directory server.
Tested against Windows Server 2012
This patch is best effort only as decision whether account is actually
locked is based on parsing error message returned by AD. The format and
content of this error message might be subject of change in future
releases and also can be modified by AD administrators.
If account is locked bind operation is expected to return following
error message:
-----------------------------------------------------------------------
Invalid credentials(49), 80090308: LdapErr: DSID-0C0903C5, comment:
AcceptSecurityContext error, data 775, v23f0
-----------------------------------------------------------------------
Where sub string 'data 775' implies that account is locked
(ERROR_ACCOUNT_LOCKED_OUT) [1]. However the 80090308 (error code
0x80090308, SEC_E_INVALID_TOKEN) is the only guaranteed part of error
string [2].
Error message is described in further detail as [3]:
-----------------------------------------------------------------------
When the server fails an LDAP operation with an error, and the server
has sufficient resources to compute a string value for the errorMessage
field of the LDAPResult, it includes a string in the errorMessage field
of the LDAPResult (see [RFC2251] section 4.1.10). The string contains
further information about the error.
The first eight characters of the errorMessage string are a 32-bit
integer, expressed in hexadecimal. Where protocol specifies the extended
error code "<unrestricted>" there is no restriction on the value of the
32-bit integer. It is recommended that implementations use a Windows
error code for the 32-bit integer in this case in order to improve
usability of the directory for clients. Where protocol specifies an
extended error code which is a Windows error code, the 32-bit integer is
the specified Windows error code. Any data after the eighth character
is strictly informational and used only for debugging. Conformant
implementations need not put any value beyond the eighth character of
the errorMessage field.
-----------------------------------------------------------------------
[1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms681386%28v=vs.85%29.aspx
[2] https://social.msdn.microsoft.com/Forums/en-US/e1d600c8-60b7-4ed0-94cb-20ddd6c1a1c6/msadts-user-locking-password-policies?forum=os_windowsprotocols
[3] MS-ADTS 3.1.1.3.1.9
https://msdn.microsoft.com/en-us/library/cc223253.aspx
Resolves:
https://fedorahosted.org/sssd/ticket/2839
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Reviewed-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit ff275f4c0b8cc1a098dbd0c5f6d52d6a93cda597)
(cherry picked from commit 81cb4057920c6296b7f7e6b7c651fdb601ff0338)
---
src/providers/data_provider.h | 2 ++
src/providers/ldap/ldap_auth.c | 4 ++++
src/providers/ldap/sdap_async_connection.c | 6 ++++++
3 files changed, 12 insertions(+)
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index 39051b90c3aad96f62dcbb86a20bcfd8c954879b..7332b677d19f70f4736e4d0b68d55cdd3c67a4af 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -182,6 +182,8 @@ struct pam_data {
bool offline_auth;
bool last_auth_saved;
int priv;
+ int account_locked;
+
#ifdef USE_KEYRING
key_serial_t key_serial;
#endif
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index 217e80fd07abc41f2594d19397783683d44600cd..2fab92e5d22a4dae870c5e9dde7ef162fc36cbe2 100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -1302,6 +1302,10 @@ static void sdap_pam_auth_done(struct tevent_req *req)
case ERR_PASSWORD_EXPIRED:
state->pd->pam_status = PAM_NEW_AUTHTOK_REQD;
break;
+ case ERR_ACCOUNT_LOCKED:
+ state->pd->account_locked = true;
+ state->pd->pam_status = PAM_PERM_DENIED;
+ break;
default:
state->pd->pam_status = PAM_SYSTEM_ERR;
dp_err = DP_ERR_FATAL;
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 85b7aaa5bf5acedf3511ffe6f8636be007d5a136..40256de99006815c97ee9390dfd2e997cf6fc072 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -754,6 +754,12 @@ static void simple_bind_done(struct sdap_op *op,
if (result == LDAP_SUCCESS) {
ret = EOK;
+ } else if (result == LDAP_INVALID_CREDENTIALS
+ && errmsg != NULL && strstr(errmsg, "data 775,") != NULL) {
+ /* Value 775 is described in
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ms681386%28v=vs.85%29.aspx
+ * for more details please see commit message. */
+ ret = ERR_ACCOUNT_LOCKED;
} else {
ret = ERR_AUTH_FAILED;
}
--
2.5.0

View File

@ -1,198 +0,0 @@
From fdc7e4acad41e7f0dff4926690f14bf94c009e38 Mon Sep 17 00:00:00 2001
From: Pavel Reichl <preichl@redhat.com>
Date: Fri, 5 Feb 2016 07:31:45 -0500
Subject: [PATCH 63/86] PAM: Pass account lockout status and display message
Tested against Windows Server 2012.
Resolves:
https://fedorahosted.org/sssd/ticket/2839
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 4180d485829969d4626cc7d49d2b5f7146512f21)
(cherry picked from commit 1b9f294dab02e6bcd4ce54e3447648d3d664ceaa)
---
src/confdb/confdb.h | 1 +
src/config/SSSDConfig/__init__.py.in | 1 +
src/config/etc/sssd.api.conf | 1 +
src/man/sssd.conf.5.xml | 21 +++++++++++++++++++++
src/providers/dp_auth_util.c | 19 +++++++++++++++++++
src/responder/pam/pamsrv_cmd.c | 31 +++++++++++++++++++++++--------
6 files changed, 66 insertions(+), 8 deletions(-)
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index c6a5e3f61d8bfd045eb2699d0f5e279cb7d89f86..6d8601b31cf4ce1a42f824a8400cef8c4ffadf9a 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -117,6 +117,7 @@
#define CONFDB_PAM_TRUSTED_USERS "pam_trusted_users"
#define CONFDB_PAM_PUBLIC_DOMAINS "pam_public_domains"
#define CONFDB_PAM_ACCOUNT_EXPIRED_MESSAGE "pam_account_expired_message"
+#define CONFDB_PAM_ACCOUNT_LOCKED_MESSAGE "pam_account_locked_message"
#define CONFDB_PAM_CERT_AUTH "pam_cert_auth"
#define CONFDB_PAM_CERT_DB_PATH "pam_cert_db_path"
#define CONFDB_PAM_P11_CHILD_TIMEOUT "p11_child_timeout"
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 6abdbc3a43cd4dbd74208efa8602b889f6e84d2b..09284fdd7c8e630b3745367b33b8ea0424ff466f 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -90,6 +90,7 @@ option_strings = {
'pam_trusted_users' : _('List of trusted uids or user\'s name'),
'pam_public_domains' : _('List of domains accessible even for untrusted users.'),
'pam_account_expired_message' : _('Message printed when user account is expired.'),
+ 'pam_account_locked_message' : _('Message printed when user account is locked.'),
'p11_child_timeout' : _('How many seconds will pam_sss wait for p11_child to finish'),
# [sudo]
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index b6a396a75e564355d0828fa24858337eb06ff4bf..6e00a87918b4c3972c1f05e5d66d0fc8a71a5cf7 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -60,6 +60,7 @@ get_domains_timeout = int, None, false
pam_trusted_users = str, None, false
pam_public_domains = str, None, false
pam_account_expired_message = str, None, false
+pam_account_locked_message = str, None, false
p11_child_timeout = int, None, false
[sudo]
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index 7b1c4f0fff9c042ce9ade2473bfe4582909212c4..cf2301f06d03b580f0bd5cea3567599af45eed02 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1024,6 +1024,27 @@ pam_account_expired_message = Account expired, please call help desk.
</listitem>
</varlistentry>
<varlistentry>
+ <term>pam_account_locked_message (string)</term>
+ <listitem>
+ <para>
+ If user is authenticating and
+ account is locked then by default
+ 'Permission denied' is output. This output will
+ be changed to content of this variable if it is
+ set.
+ </para>
+ <para>
+ example:
+ <programlisting>
+pam_account_locked_message = Account locked, please call help desk.
+ </programlisting>
+ </para>
+ <para>
+ Default: none
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
<term>p11_child_timeout (integer)</term>
<listitem>
<para>
diff --git a/src/providers/dp_auth_util.c b/src/providers/dp_auth_util.c
index f8a30c5d4e6da7ce6ac28723032241e2458ea473..8e261ef5e4af7479ffce087370844caa1cad43d7 100644
--- a/src/providers/dp_auth_util.c
+++ b/src/providers/dp_auth_util.c
@@ -160,6 +160,14 @@ bool dp_pack_pam_response(DBusMessage *msg, struct pam_data *pd)
return false;
}
+ /* Append the lockout of account */
+ dbret = dbus_message_iter_append_basic(&iter,
+ DBUS_TYPE_UINT32,
+ &pd->account_locked);
+ if (!dbret) {
+ return false;
+ }
+
/* Create an array of response structures */
dbret = dbus_message_iter_open_container(&iter,
DBUS_TYPE_ARRAY, "(uay)",
@@ -246,6 +254,17 @@ bool dp_unpack_pam_response(DBusMessage *msg, struct pam_data *pd, DBusError *db
return false;
}
+ if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
+ return false;
+ }
+ dbus_message_iter_get_basic(&iter, &(pd->account_locked));
+
+ if (!dbus_message_iter_next(&iter)) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "pam response has too few arguments.\n");
+ return false;
+ }
+
/* After this point will be an array of pam data */
if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) {
DEBUG(SSSDBG_CRIT_FAILURE, "pam response format error.\n");
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
index 38636088e63ede159df0bc9376c255d05bf7de0b..c4ea9cd3e8970db7d281086453d22f3218b05c47 100644
--- a/src/responder/pam/pamsrv_cmd.c
+++ b/src/responder/pam/pamsrv_cmd.c
@@ -53,10 +53,10 @@ pam_get_last_online_auth_with_curr_token(struct sss_domain_info *domain,
static void pam_reply(struct pam_auth_req *preq);
-static errno_t pack_user_info_account_expired(TALLOC_CTX *mem_ctx,
- const char *user_error_message,
- size_t *resp_len,
- uint8_t **_resp)
+static errno_t pack_user_info_msg(TALLOC_CTX *mem_ctx,
+ const char *user_error_message,
+ size_t *resp_len,
+ uint8_t **_resp)
{
uint32_t resp_type = SSS_PAM_USER_INFO_ACCOUNT_EXPIRED;
size_t err_len;
@@ -83,14 +83,13 @@ static errno_t pack_user_info_account_expired(TALLOC_CTX *mem_ctx,
return EOK;
}
-static void inform_account_expired(struct pam_data* pd,
- const char *pam_message)
+static void inform_user(struct pam_data* pd, const char *pam_message)
{
size_t msg_len;
uint8_t *msg;
errno_t ret;
- ret = pack_user_info_account_expired(pd, pam_message, &msg_len, &msg);
+ ret = pack_user_info_msg(pd, pam_message, &msg_len, &msg);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
"pack_user_info_account_expired failed.\n");
@@ -601,6 +600,7 @@ static void pam_reply(struct pam_auth_req *preq)
time_t exp_date = -1;
time_t delay_until = -1;
char* pam_account_expired_message;
+ char* pam_account_locked_message;
int pam_verbosity;
pd = preq->pd;
@@ -762,7 +762,22 @@ static void pam_reply(struct pam_auth_req *preq)
goto done;
}
- inform_account_expired(pd, pam_account_expired_message);
+ inform_user(pd, pam_account_expired_message);
+ }
+
+ if (pd->account_locked) {
+
+ ret = confdb_get_string(pctx->rctx->cdb, pd, CONFDB_PAM_CONF_ENTRY,
+ CONFDB_PAM_ACCOUNT_LOCKED_MESSAGE, "",
+ &pam_account_locked_message);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Failed to get expiration message: %d:[%s].\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ inform_user(pd, pam_account_locked_message);
}
ret = filter_responses(pctx->rctx->cdb, pd->resp_list);
--
2.5.0

View File

@ -1,65 +0,0 @@
From 03dde14c2cc236e20456f24910dae4308dc96f16 Mon Sep 17 00:00:00 2001
From: Dan Lavu <dlavu@redhat.com>
Date: Fri, 5 Feb 2016 09:28:41 -0500
Subject: [PATCH 64/86] PAM: Fix man for pam_account_{expired,locked}_message
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 09092b6535b711b9b734ed0c047c671de9e6cafd)
(cherry picked from commit ffe3df61d85c2890a31d627c5e6fe8890f1e26d8)
---
src/man/sssd.conf.5.xml | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
index cf2301f06d03b580f0bd5cea3567599af45eed02..d7e324f457a42403133c9d25f34d702d703fc9b8 100644
--- a/src/man/sssd.conf.5.xml
+++ b/src/man/sssd.conf.5.xml
@@ -1006,16 +1006,39 @@ fallback_homedir = /home/%u
<term>pam_account_expired_message (string)</term>
<listitem>
<para>
- If user is authenticating using SSH keys and
- account is expired then by default
- 'Permission denied' is output. This output will
- be changed to content of this variable if it is
- set.
+ Allows a custom expiration message to be set,
+ replacing the default 'Permission denied'
+ message.
+ </para>
+ <para>
+ Note: Please be aware that message is only
+ printed for the SSH service unless pam_verbostiy
+ is set to 3 (show all messages and debug
+ information).
+ </para>
+ <para>
+ example:
+ <programlisting>
+pam_account_expired_message = Account expired, please contact help desk.
+ </programlisting>
+ </para>
+ <para>
+ Default: none
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>pam_account_locked_message (string)</term>
+ <listitem>
+ <para>
+ Allows a custom lockout message to be set,
+ replacing the default 'Permission denied'
+ message.
</para>
<para>
example:
<programlisting>
-pam_account_expired_message = Account expired, please call help desk.
+pam_account_locked_message = Account locked, please contact help desk.
</programlisting>
</para>
<para>
--
2.5.0

View File

@ -1,45 +0,0 @@
From 90933a2aa0bc149fd8a1ca4feef0527ddfcf7258 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 17 Feb 2016 17:58:10 +0100
Subject: [PATCH 65/86] UTIL: Backport error code ERR_ACCOUNT_LOCKED
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Required by:
https://fedorahosted.org/sssd/ticket/2839
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit af717c5b022d5c28141333fc02d5d9e1f322505c)
---
src/util/util_errors.c | 1 +
src/util/util_errors.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
index 1d684d387b90b8db37609d5bc022e06fcac708f9..59ae63ab8d6e834a772349b162bf282f9a4f1c72 100644
--- a/src/util/util_errors.c
+++ b/src/util/util_errors.c
@@ -82,6 +82,7 @@ struct err_string error_to_str[] = {
{ "Address family not supported" }, /* ERR_ADDR_FAMILY_NOT_SUPPORTED */
{ "Message sender is the bus" }, /* ERR_SBUS_SENDER_BUS */
{ "Subdomain is inactive" }, /* ERR_SUBDOM_INACTIVE */
+ { "Account is locked" }, /* ERR_ACCOUNT_LOCKED */
{ "AD renewal child failed" }, /* ERR_RENEWAL_CHILD */
{ "ERR_LAST" } /* ERR_LAST */
};
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
index 5c02fdd8b4c6e0c59f7fd6f66a3fc8a8e48dc607..05791f2f08f107a8b4830b810b8826983763174f 100644
--- a/src/util/util_errors.h
+++ b/src/util/util_errors.h
@@ -104,6 +104,7 @@ enum sssd_errors {
ERR_ADDR_FAMILY_NOT_SUPPORTED,
ERR_SBUS_SENDER_BUS,
ERR_SUBDOM_INACTIVE,
+ ERR_ACCOUNT_LOCKED,
ERR_RENEWAL_CHILD,
ERR_LAST /* ALWAYS LAST */
};
--
2.5.0

View File

@ -1,51 +0,0 @@
From 5897690a889c6f2a11135d1ed33089409ddb8c57 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Wed, 17 Feb 2016 17:23:37 +0100
Subject: [PATCH 66/86] sss_idmap-tests: Fix segmentation fault
I can reproduce it only with clang.
But it's tipical off by one error.
sh$ ./sss_idmap-tests
Running suite(s): IDMAP
Segmentation fault (core dumped)
Running suite(s): IDMAP
==2644== Process terminating with default action of signal 11 (SIGSEGV)
==2644== Access not within mapped region at address 0xA08F430
==2644== at 0x4C2CC53: strcmp (vg_replace_strmem.c:842)
==2644== by 0x4060DA: idmap_test_sid2uid_additional_secondary_slices (sss_idmap-tests.c:451)
==2644== by 0x503C78A: ??? (in /usr/lib64/libcheck.so.0.0.0)
==2644== by 0x503CB7C: srunner_run (in /usr/lib64/libcheck.so.0.0.0)
==2644== by 0x4061EE: main (sss_idmap-tests.c:965)
==2644== If you believe this happened as a result of a stack
==2644== overflow in your program's main thread (unlikely but
==2644== possible), you can try to increase the size of the
==2644== main thread stack using the --main-stacksize= flag.
==2644== The main thread stack size used in this run was 8388608.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 4f3a996561445ba82c854bb2b674f975f596e884)
(cherry picked from commit 999af61d6a55bf816d86dbfc94214383436b18d3)
---
src/tests/sss_idmap-tests.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/tests/sss_idmap-tests.c b/src/tests/sss_idmap-tests.c
index 900b7bff1cd4f3c6f9cdffc4b012864d05e72913..885913645ed286636758f3f48a5a62d87cc9ab75 100644
--- a/src/tests/sss_idmap-tests.c
+++ b/src/tests/sss_idmap-tests.c
@@ -427,8 +427,8 @@ START_TEST(idmap_test_sid2uid_additional_secondary_slices)
struct TALLOC_CTX *tmp_ctx;
const char *dom_prefix = "S-1-5-21-1-2-3";
const int max_rid = 80;
- const char *sids[max_rid];
- unsigned int ids[max_rid];
+ const char *sids[max_rid + 1];
+ unsigned int ids[max_rid + 1];
tmp_ctx = talloc_new(NULL);
fail_unless(tmp_ctx != NULL, "Out of memory.");
--
2.5.0

View File

@ -1,74 +0,0 @@
From 40ccad84a0558eb21ebd351ea837c5042fa38966 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Fri, 29 Jan 2016 13:30:49 +0100
Subject: [PATCH 67/86] krb5_child: Warn if user cannot read krb5.conf
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Attached patch should siplify troubleshoting of
issues with permission of krb5.conf. It's not clear from
krb5_child.log even with full debug level.
[sss_get_ccache_name_for_principal] (0x4000):
Location: [FILE:/tmp/krb5cc_12069_XXXXXX]
[sss_get_ccache_name_for_principal] (0x2000):
krb5_cc_cache_match failed: [-1765328243]
[Can't find client principal user@EXAMPLE.COM in cache collection]
[create_ccache] (0x0020): 735: [13][Permission denied]
Resolves:
https://fedorahosted.org/sssd/ticket/2931
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit 38f251e531b1c68e70eaa98dfecaf78da5f36ccc)
(cherry picked from commit 760d655881e87f52db033a4a56b05fbe91dce146)
---
src/providers/krb5/krb5_child.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index 619e76372f962279ddffadadc607d9bbb20fbffb..6fd88815a5224809c7c448198495ae009f47097e 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -2572,6 +2572,29 @@ static krb5_error_code privileged_krb5_setup(struct krb5_req *kr,
return 0;
}
+static void try_open_krb5_conf(void)
+{
+ int fd;
+ int ret;
+
+ fd = open("/etc/krb5.conf", O_RDONLY);
+ if (fd != -1) {
+ close(fd);
+ } else {
+ ret = errno;
+ if (ret == EACCES || ret == EPERM) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "User with uid:%"SPRIuid" gid:%"SPRIgid" cannot read "
+ "/etc/krb5.conf. It might cause problems\n",
+ geteuid(), getegid());
+ } else {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Cannot open /etc/krb5.conf [%d]: %s\n",
+ ret, strerror(ret));
+ }
+ }
+}
+
int main(int argc, const char *argv[])
{
struct krb5_req *kr = NULL;
@@ -2673,6 +2696,7 @@ int main(int argc, const char *argv[])
DEBUG(SSSDBG_TRACE_INTERNAL,
"Running as [%"SPRIuid"][%"SPRIgid"].\n", geteuid(), getegid());
+ try_open_krb5_conf();
ret = k5c_setup(kr, offline);
if (ret != EOK) {
--
2.5.0

View File

@ -1,197 +0,0 @@
From 7832b422ec442ec2d80cf00bb1189ac2f38a783b Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Fri, 12 Feb 2016 22:05:21 +0100
Subject: [PATCH 68/86] Fix typos reported by lintian
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 42604cc8d11743febf5aa892cb3a7d3c32bfed48)
(cherry picked from commit 7870820e8b188d755fef9fb31ef95b518c0f905b)
---
src/ldb_modules/memberof.c | 10 +++++-----
src/providers/krb5/krb5_utils.c | 2 +-
src/providers/ldap/sdap.c | 2 +-
src/python/pysss.c | 2 +-
src/responder/common/negcache.c | 2 +-
src/responder/nss/nsssrv_mmap_cache.c | 2 +-
src/responder/pam/pamsrv_p11.c | 2 +-
src/tools/tools_util.c | 2 +-
src/util/nscd.c | 6 +++---
9 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/ldb_modules/memberof.c b/src/ldb_modules/memberof.c
index 4d7b23ea1b95bed0ec5c7cc717b95e6da3cd0717..83d93196c34854d75fcd8ac91ad056f64b26b659 100644
--- a/src/ldb_modules/memberof.c
+++ b/src/ldb_modules/memberof.c
@@ -411,7 +411,7 @@ static int mbof_add_fill_ghop_ex(struct mbof_add_ctx *add_ctx,
return LDB_SUCCESS;
default:
- /* an error occured, return */
+ /* an error occurred, return */
return ret;
}
@@ -911,7 +911,7 @@ static int mbof_add_operation(struct mbof_add_operation *addop)
break;
default:
- /* an error occured, return */
+ /* an error occurred, return */
return ret;
}
@@ -2133,7 +2133,7 @@ static int mbof_del_mod_entry(struct mbof_del_operation *delop)
is_user = false;
break;
default:
- /* an error occured, return */
+ /* an error occurred, return */
return ret;
}
@@ -2457,7 +2457,7 @@ static int mbof_del_fill_muop(struct mbof_del_ctx *del_ctx,
return LDB_SUCCESS;
default:
- /* an error occured, return */
+ /* an error occurred, return */
return ret;
}
@@ -2520,7 +2520,7 @@ static int mbof_del_fill_ghop_ex(struct mbof_del_ctx *del_ctx,
return LDB_SUCCESS;
default:
- /* an error occured, return */
+ /* an error occurred, return */
return ret;
}
diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c
index 0b73880eca6015fc9dffa4a850b230afc5dfddfc..7fd490514a52f0bfa3f1ced75f2b6496a77dada6 100644
--- a/src/providers/krb5/krb5_utils.c
+++ b/src/providers/krb5/krb5_utils.c
@@ -386,7 +386,7 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
rerun = true;
continue;
} else if (strncmp(n , S_EXP_EUID, L_EXP_EUID) == 0) {
- /* SSSD does not distinguish betwen uid and euid,
+ /* SSSD does not distinguish between uid and euid,
* so we treat both the same way */
action = 'U';
n += L_EXP_EUID - 1;
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index f9b9ff7e6913c406547f36d341300b936e121693..c0863a6d5bbe4f8f074e25634cb5e236075ce55a 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -1284,7 +1284,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
break;
default:
DEBUG(SSSDBG_CRIT_FAILURE,
- "Unkown error (%d) checking rootdse!\n", ret);
+ "Unknown error (%d) checking rootdse!\n", ret);
}
} else {
if (!entry_usn_name) {
diff --git a/src/python/pysss.c b/src/python/pysss.c
index 50f80421739e579ff94e5b8d1c5b97433b460e06..6bd8f5a9261aefe5b8ca90998e14878dd3896eef 100644
--- a/src/python/pysss.c
+++ b/src/python/pysss.c
@@ -461,7 +461,7 @@ static PyObject *py_sss_usermod(PySssLocalObject *self,
if (lock && lock != DO_LOCK && lock != DO_UNLOCK) {
PyErr_SetString(PyExc_ValueError,
- "Unkown value for lock parameter");
+ "Unknown value for lock parameter");
goto fail;
}
diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index f7af9e0280737f6c89c3034e8b19a6ecd393d355..5b0517ceba85d6e35515a935423412314c218143 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -806,7 +806,7 @@ errno_t sss_ncache_prepopulate(struct sss_nc_ctx *ncache,
if (domainname && strcmp(domainname, dom->name)) {
DEBUG(SSSDBG_CRIT_FAILURE,
- "Mismatch betwen domain name (%s) and name "
+ "Mismatch between domain name (%s) and name "
"set in FQN (%s), skipping group %s\n",
dom->name, domainname, name);
continue;
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index 62f4c543c628712810b6dfbc669c586c39ca609d..f7f62733941cd3ae3b071d6d54c801f9be1ce800 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -1348,7 +1348,7 @@ errno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
if (mc_ctx == NULL || (*mc_ctx) == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
- "Unable to re-init unitialized memory cache.\n");
+ "Unable to re-init uninitialized memory cache.\n");
return EINVAL;
}
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
index ad1670136dbf8efc41df6950af744ff8b06e6a11..7a8002c2828c14e55ef2d827e37398035a0c6726 100644
--- a/src/responder/pam/pamsrv_p11.c
+++ b/src/responder/pam/pamsrv_p11.c
@@ -144,7 +144,7 @@ static errno_t parse_p11_child_response(TALLOC_CTX *mem_ctx, uint8_t *buf,
if (buf_len < 0) {
DEBUG(SSSDBG_CRIT_FAILURE,
- "Error occured while reading data from p11_child.\n");
+ "Error occurred while reading data from p11_child.\n");
return EIO;
}
diff --git a/src/tools/tools_util.c b/src/tools/tools_util.c
index 68f6588ea887da6391159fa59916fdece102472b..3112171a6c06a50b7099f1c1b58ea1ad581c7cb3 100644
--- a/src/tools/tools_util.c
+++ b/src/tools/tools_util.c
@@ -324,7 +324,7 @@ fini:
* Check is path is owned by uid
* returns 0 - owns
* -1 - does not own
- * >0 - an error occured, error code
+ * >0 - an error occurred, error code
*/
static int is_owner(uid_t uid, const char *path)
{
diff --git a/src/util/nscd.c b/src/util/nscd.c
index f58aebcad69924bdd841a4bb51aedb0308237ac4..ab29f3d271970911a0c1467b83147ba4774c1ecb 100644
--- a/src/util/nscd.c
+++ b/src/util/nscd.c
@@ -139,7 +139,7 @@ errno_t sss_nscd_parse_conf(const char *conf_path)
{
FILE *fp;
int ret = EOK;
- unsigned int occured = 0;
+ unsigned int occurred = 0;
char *line, *entry, *service, *enabled, *pad;
size_t linelen = 0;
@@ -195,7 +195,7 @@ errno_t sss_nscd_parse_conf(const char *conf_path)
if (!strcmp(entry, "enable-cache") &&
!strcmp(enabled, "yes")) {
- occured |= sss_nscd_check_service(service);
+ occurred |= sss_nscd_check_service(service);
}
};
@@ -209,7 +209,7 @@ errno_t sss_nscd_parse_conf(const char *conf_path)
}
ret = EOK;
- if (occured != 0) {
+ if (occurred != 0) {
ret = EEXIST;
goto done;
}
--
2.5.0

View File

@ -1,97 +0,0 @@
From f468d11fce4257bf3acc07b7f5a8d45cfbe52a60 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 11 Jan 2016 18:54:40 +0100
Subject: [PATCH 69/86] UTIL: Use prefix for debug function
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 2a44a8c6683cfea218ee5329bcfad953dfeb6746)
(cherry picked from commit 4772bb86902552cb2fc18c3127b74f8cde5252ea)
---
src/util/debug.c | 12 ++++++------
src/util/sss_semanage.c | 2 +-
src/util/util.h | 16 ++++++++--------
3 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/util/debug.c b/src/util/debug.c
index b6ab368db824bbd297dcb410c3e669d911ff0d33..570c80273c0bdda1cc8df0e6af825595cfa339e0 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -206,11 +206,11 @@ journal_done:
}
#endif /* WiTH_JOURNALD */
-void debug_fn(const char *file,
- long line,
- const char *function,
- int level,
- const char *format, ...)
+void sss_debug_fn(const char *file,
+ long line,
+ const char *function,
+ int level,
+ const char *format, ...)
{
va_list ap;
struct timeval tv;
@@ -301,7 +301,7 @@ void ldb_debug_messages(void *context, enum ldb_debug_level level,
}
if (DEBUG_IS_SET(loglevel))
- debug_fn(__FILE__, __LINE__, "ldb", loglevel, "%s\n", message);
+ sss_debug_fn(__FILE__, __LINE__, "ldb", loglevel, "%s\n", message);
free(message);
}
diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c
index d1d03988c05dc011dbd465051d50fe6acca4f845..4fb9df589bbfddcc815ed321b6e3b32655d44a0c 100644
--- a/src/util/sss_semanage.c
+++ b/src/util/sss_semanage.c
@@ -64,7 +64,7 @@ static void sss_semanage_error_callback(void *varg,
}
if (DEBUG_IS_SET(level))
- debug_fn(__FILE__, __LINE__, "libsemanage", level, "%s\n", message);
+ sss_debug_fn(__FILE__, __LINE__, "libsemanage", level, "%s\n", message);
free(message);
}
diff --git a/src/util/util.h b/src/util/util.h
index c0db6779f7f6fae44a5d956ae52a166f0f4eefc6..0b50d5abf6f1651dcf350e2c235702b5a21536d1 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -71,11 +71,11 @@ extern int debug_microseconds;
extern int debug_to_file;
extern int debug_to_stderr;
extern const char *debug_log_file;
-void debug_fn(const char *file,
- long line,
- const char *function,
- int level,
- const char *format, ...) SSS_ATTRIBUTE_PRINTF(5,6);
+void sss_debug_fn(const char *file,
+ long line,
+ const char *function,
+ int level,
+ const char *format, ...) SSS_ATTRIBUTE_PRINTF(5, 6);
int debug_convert_old_level(int old_level);
errno_t set_debug_file_from_fd(const int fd);
int get_fd_from_debug_file(void);
@@ -129,9 +129,9 @@ int get_fd_from_debug_file(void);
#define DEBUG(level, format, ...) do { \
int __debug_macro_level = level; \
if (DEBUG_IS_SET(__debug_macro_level)) { \
- debug_fn(__FILE__, __LINE__, __FUNCTION__, \
- __debug_macro_level, \
- format, ##__VA_ARGS__); \
+ sss_debug_fn(__FILE__, __LINE__, __FUNCTION__, \
+ __debug_macro_level, \
+ format, ##__VA_ARGS__); \
} \
} while (0)
--
2.5.0

View File

@ -1,97 +0,0 @@
From 55928e9989e53b8333ce44cded97ce244b5ce048 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 11 Jan 2016 11:06:22 +0100
Subject: [PATCH 70/86] UTIL: Provide varargs version of debug_fn
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 22bbd95a48d21452fa5bb1a96b43334503bf8132)
(cherry picked from commit c99096a5f0a6e47c50e91ecd9ebbdf2a18195fa8)
---
src/util/debug.c | 29 +++++++++++++++++++----------
src/util/util.h | 6 ++++++
2 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/src/util/debug.c b/src/util/debug.c
index 570c80273c0bdda1cc8df0e6af825595cfa339e0..1b7aef467ff336e3316ab39f3a7d0b22ff3a0ed0 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -206,13 +206,13 @@ journal_done:
}
#endif /* WiTH_JOURNALD */
-void sss_debug_fn(const char *file,
- long line,
- const char *function,
- int level,
- const char *format, ...)
+void sss_vdebug_fn(const char *file,
+ long line,
+ const char *function,
+ int level,
+ const char *format,
+ va_list ap)
{
- va_list ap;
struct timeval tv;
struct tm *tm;
char datetime[20];
@@ -230,10 +230,8 @@ void sss_debug_fn(const char *file,
* can also provide extra structuring data to make it more easily
* searchable.
*/
- va_start(ap, format);
va_copy(ap_fallback, ap);
ret = journal_send(file, line, function, level, format, ap);
- va_end(ap);
if (ret != EOK) {
/* Emergency fallback, send to STDERR */
debug_vprintf(format, ap_fallback);
@@ -266,12 +264,23 @@ void sss_debug_fn(const char *file,
debug_prg_name, function, level);
}
- va_start(ap, format);
debug_vprintf(format, ap);
- va_end(ap);
debug_fflush();
}
+void sss_debug_fn(const char *file,
+ long line,
+ const char *function,
+ int level,
+ const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ sss_vdebug_fn(file, line, function, level, format, ap);
+ va_end(ap);
+}
+
void ldb_debug_messages(void *context, enum ldb_debug_level level,
const char *fmt, va_list ap)
{
diff --git a/src/util/util.h b/src/util/util.h
index 0b50d5abf6f1651dcf350e2c235702b5a21536d1..9b5262995630b1b98f8658b3c32e1b83b0d31307 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -71,6 +71,12 @@ extern int debug_microseconds;
extern int debug_to_file;
extern int debug_to_stderr;
extern const char *debug_log_file;
+void sss_vdebug_fn(const char *file,
+ long line,
+ const char *function,
+ int level,
+ const char *format,
+ va_list ap);
void sss_debug_fn(const char *file,
long line,
const char *function,
--
2.5.0

View File

@ -1,84 +0,0 @@
From 7b06c5415f24fe7d20253b101a6462d1944854d0 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 11 Jan 2016 19:13:06 +0100
Subject: [PATCH 71/86] UTIL: Use sss_vdebug_fn for callbacks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit f6c1f6a561bdd5b4bba03c02988a724da3dad387)
(cherry picked from commit 86ba562d09e1ee9aa55819d748722c2d3ac00600)
---
src/util/debug.c | 13 ++-----------
src/util/sss_semanage.c | 14 +++-----------
2 files changed, 5 insertions(+), 22 deletions(-)
diff --git a/src/util/debug.c b/src/util/debug.c
index 1b7aef467ff336e3316ab39f3a7d0b22ff3a0ed0..03dc26d6d4e976866a3f9395598840e28997f69a 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -285,8 +285,6 @@ void ldb_debug_messages(void *context, enum ldb_debug_level level,
const char *fmt, va_list ap)
{
int loglevel = SSSDBG_UNRESOLVED;
- int ret;
- char * message = NULL;
switch(level) {
case LDB_DEBUG_FATAL:
@@ -303,16 +301,9 @@ void ldb_debug_messages(void *context, enum ldb_debug_level level,
break;
}
- ret = vasprintf(&message, fmt, ap);
- if (ret < 0) {
- /* ENOMEM */
- return;
+ if (DEBUG_IS_SET(loglevel)) {
+ sss_vdebug_fn(__FILE__, __LINE__, "ldb", loglevel, fmt, ap);
}
-
- if (DEBUG_IS_SET(loglevel))
- sss_debug_fn(__FILE__, __LINE__, "ldb", loglevel, "%s\n", message);
-
- free(message);
}
/* In cases SSSD used to run as the root user, but runs as the SSSD user now,
diff --git a/src/util/sss_semanage.c b/src/util/sss_semanage.c
index 4fb9df589bbfddcc815ed321b6e3b32655d44a0c..7f746491174730acbf1539acaf3f6467ff92afcf 100644
--- a/src/util/sss_semanage.c
+++ b/src/util/sss_semanage.c
@@ -39,8 +39,6 @@ static void sss_semanage_error_callback(void *varg,
const char *fmt, ...)
{
int level = SSSDBG_INVALID;
- int ret;
- char * message = NULL;
va_list ap;
switch (semanage_msg_get_level(handle)) {
@@ -56,16 +54,10 @@ static void sss_semanage_error_callback(void *varg,
}
va_start(ap, fmt);
- ret = vasprintf(&message, fmt, ap);
+ if (DEBUG_IS_SET(level)) {
+ sss_vdebug_fn(__FILE__, __LINE__, "libsemanage", level, fmt, ap);
+ }
va_end(ap);
- if (ret < 0) {
- /* ENOMEM */
- return;
- }
-
- if (DEBUG_IS_SET(level))
- sss_debug_fn(__FILE__, __LINE__, "libsemanage", level, "%s\n", message);
- free(message);
}
static void sss_semanage_close(semanage_handle_t *handle)
--
2.5.0

View File

@ -1,75 +0,0 @@
From 910cd1c35859213319537072c48429e768b53b86 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 25 Jan 2016 11:46:54 +0100
Subject: [PATCH 72/86] Revert "DEBUG: Preventing chown_debug_file if journald
on"
This reverts commit 6e2822b151c21ce6e3287a0cf25d40e9f10a6127.
The function chown_debug_file is called before initialization
of debug stuff in sssd. Therefore variable debug_file cannot be
initialized. Therefore reverted commit completely turned off
changing owner of debug files. Side effect of this change
was that annoying error messages was not logged in case of
journald.
Resolves:
https://fedorahosted.org/sssd/ticket/2938
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 9f1186e7be7ece4d2b9bbbe444d3fc42ab57b808)
---
src/util/debug.c | 35 ++++++++++++++++-------------------
1 file changed, 16 insertions(+), 19 deletions(-)
diff --git a/src/util/debug.c b/src/util/debug.c
index 03dc26d6d4e976866a3f9395598840e28997f69a..d10b456acd14f32590e8b4111596f95a555ac828 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -316,27 +316,24 @@ int chown_debug_file(const char *filename,
const char *log_file;
errno_t ret;
- if (debug_file) {
+ if (filename == NULL) {
+ log_file = debug_log_file;
+ } else {
+ log_file = filename;
+ }
- if (filename == NULL) {
- log_file = debug_log_file;
- } else {
- log_file = filename;
- }
+ ret = asprintf(&logpath, "%s/%s.log", LOG_PATH, log_file);
+ if (ret == -1) {
+ return ENOMEM;
+ }
- ret = asprintf(&logpath, "%s/%s.log", LOG_PATH, log_file);
- if (ret == -1) {
- return ENOMEM;
- }
-
- ret = chown(logpath, uid, gid);
- free(logpath);
- if (ret != 0) {
- ret = errno;
- DEBUG(SSSDBG_FATAL_FAILURE, "chown failed for [%s]: [%d]\n",
- log_file, ret);
- return ret;
- }
+ ret = chown(logpath, uid, gid);
+ free(logpath);
+ if (ret != 0) {
+ ret = errno;
+ DEBUG(SSSDBG_FATAL_FAILURE, "chown failed for [%s]: [%d]\n",
+ log_file, ret);
+ return ret;
}
return EOK;
--
2.5.0

View File

@ -1,35 +0,0 @@
From 214a61d2169329106da654c06a5faaeaf645852d Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Fri, 22 Jan 2016 15:04:48 +0100
Subject: [PATCH 73/86] DEBUG: Ignore ENOENT for change owner of log files
Resolves:
https://fedorahosted.org/sssd/ticket/2493
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit cbb04b9439d73fff027e193093a49cdac3cdb499)
---
src/util/debug.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/util/debug.c b/src/util/debug.c
index d10b456acd14f32590e8b4111596f95a555ac828..a014bc3850641ad1f37c72df5a6181fed8391cfb 100644
--- a/src/util/debug.c
+++ b/src/util/debug.c
@@ -331,6 +331,13 @@ int chown_debug_file(const char *filename,
free(logpath);
if (ret != 0) {
ret = errno;
+ if (ret == ENOENT) {
+ /* Log does not exist. We might log to journald
+ * or starting for first time.
+ * It's not a failure. */
+ return EOK;
+ }
+
DEBUG(SSSDBG_FATAL_FAILURE, "chown failed for [%s]: [%d]\n",
log_file, ret);
return ret;
--
2.5.0

View File

@ -1,39 +0,0 @@
From dd7a1a508bdc60b62b5ef4ce22fcf31dace3f3c2 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Fri, 19 Feb 2016 16:18:02 +0100
Subject: [PATCH 74/86] TOOLS: Fix minor memory leak in sss_colondb_writeline
The variable line was initialized to NULL.
The we created temporary context tmp_ctx.
We use talloc_asprintf_append to append string to line which is initially
NULL and therefore new context which was not connected to tmp_ctx.
man 3 talloc_string -> talloc_asprintf_append
Reviewed-by: Petr Cech <pcech@redhat.com>
(cherry picked from commit 6977d7c84145ac69195be58b3330861b9b8a3b72)
(cherry picked from commit d75ac50d0c065974a7ec2330f60657ae85e487c0)
---
src/tools/common/sss_colondb.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/src/tools/common/sss_colondb.c b/src/tools/common/sss_colondb.c
index a41b12fb9c097ff0e03da6d1c5cfe2fb24b63d54..b9af5f7e50c1166ca518a4e342637dc62518c567 100644
--- a/src/tools/common/sss_colondb.c
+++ b/src/tools/common/sss_colondb.c
@@ -198,6 +198,13 @@ errno_t sss_colondb_writeline(struct sss_colondb *db,
return ENOMEM;
}
+ line = talloc_strdup(tmp_ctx, "");
+ if (line == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
for (i = 0; table[i].type != SSS_COLONDB_SENTINEL; i++) {
switch (table[i].type) {
case SSS_COLONDB_UINT32:
--
2.5.0

View File

@ -1,47 +0,0 @@
From 38bd263de5b83710898406640a77c15edea712fe Mon Sep 17 00:00:00 2001
From: Petr Cech <pcech@redhat.com>
Date: Thu, 18 Feb 2016 06:33:53 -0500
Subject: [PATCH 75/86] TOOLS: Fix memory leak after getline() failed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch fixes buffer freeing in case if getline() failed
in function sss_colondb_readline().
ssize_t getline(char **lineptr, size_t *n, FILE *stream);
If *lineptr is set to NULL and *n is set 0 before the call, then
getline() will allocate a buffer for storing the line. This buffer
should be freed by the user program even if getline() failed.
man 3 getline
This patch fix buffer freeing in case if getline() failed.
Resolves:
https://fedorahosted.org/sssd/ticket/2764
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit 2dd75ea79a57615808754c0ce550786edbc17d69)
(cherry picked from commit 34ba0c53d0d966c64ea11a6269cdd0ad985f4068)
---
src/tools/common/sss_colondb.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/tools/common/sss_colondb.c b/src/tools/common/sss_colondb.c
index b9af5f7e50c1166ca518a4e342637dc62518c567..e8aeb315c9ed0efde15553e2d741d04c5d895b1a 100644
--- a/src/tools/common/sss_colondb.c
+++ b/src/tools/common/sss_colondb.c
@@ -121,6 +121,10 @@ errno_t sss_colondb_readline(TALLOC_CTX *mem_ctx,
readchars = getline(&line, &linelen, db->file);
if (readchars == -1) {
/* Nothing was read. */
+
+ free(line);
+ line = NULL;
+
if (errno != 0) {
ret = errno;
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read line [%d]: %s\n",
--
2.5.0

View File

@ -1,74 +0,0 @@
From 3ca35b1781ef5a1f50c5165882b9ff4cebbbb7ac Mon Sep 17 00:00:00 2001
From: Petr Cech <pcech@redhat.com>
Date: Tue, 24 Nov 2015 10:34:10 -0500
Subject: [PATCH 76/86] TOOLS: Add comments on functions in colondb
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The colondb API provides three function:
* sss_colondb_open()
* sss_colondb_write_field()
* sss_colondb_read_field()
It is not obvious that sss_colondb_open() add destructor on talloc
context which close the colondb during free context. And there is
expectation that SSS_COLONDB_SENTINEL is type of last item in line.
So this patch adds simple lightening comments in doxygen style.
Resolves:
https://fedorahosted.org/sssd/ticket/2764
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit cf1109e30320a994187edeb438ac7cdc36f0dd2b)
(cherry picked from commit fbf7d5683287fa2c7b450b8f5b0df63673f25d83)
---
src/tools/common/sss_colondb.h | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/src/tools/common/sss_colondb.h b/src/tools/common/sss_colondb.h
index 6edd99cbe3b9ef5c86a48632ac3fc71e8a3e55fe..cb9040088c65fdbe35c787b8942aaf1b14a2778d 100644
--- a/src/tools/common/sss_colondb.h
+++ b/src/tools/common/sss_colondb.h
@@ -59,14 +59,37 @@ struct sss_colondb_read_field {
union sss_colondb_read_data data;
};
+/**
+ * Open colon DB and return connection.
+ * @param[in|out] mem_ctx Memory context. Internal sss_colondb_close() is set
+ * on destructor of this memory context.
+ * @param[in] mode Open mode of db: SSS_COLONDB_READ or SSS_COLONDB_WRITE.
+ * @param[in] filename Name of file.
+ * @return Pointer to structure holding DB connection, or NULL if fail.
+ */
struct sss_colondb *sss_colondb_open(TALLOC_CTX *mem_ctx,
enum sss_colondb_mode mode,
const char *filename);
+/**
+ * Read line from colon DB.
+ * @param[in|out] mem_ctx Memory context.
+ * @param[in] db Pointer to structure holding DB connection.
+ * @param[in|out] table Array of expected structure of line. It is expected
+ * that last item has SSS_COLONDB_SENTINEL type.
+ * @return EOK if success, else error code.
+ */
errno_t sss_colondb_readline(TALLOC_CTX *mem_ctx,
struct sss_colondb *db,
struct sss_colondb_read_field *table);
+/**
+ * Write line to colon DB.
+ * @param[in] db Pointer to structure holding DB connection.
+ * @param[in] table Array with data. It is expected that last item has
+ * SSS_COLONDB_SENTINEL type.
+ * @return EOK if success, else error code.
+ */
errno_t sss_colondb_writeline(struct sss_colondb *db,
struct sss_colondb_write_field *table);
--
2.5.0

View File

@ -1,504 +0,0 @@
From eb2ce6f47fd9a676bf5405deda2ccfabc42a437c Mon Sep 17 00:00:00 2001
From: Petr Cech <pcech@redhat.com>
Date: Fri, 27 Nov 2015 06:39:37 -0500
Subject: [PATCH 77/86] TEST_TOOLS_COLONDB: Add tests for sss_colondb_*
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There are three functions at API of colondb wrapper:
* sss_colondb_open()
* sss_colondb_readline()
* sss_colondb_writeline()
This patch adds tests for all of them.
We test those cases:
* open nonexisting file for read
* open nonexisting file for write
* open existing empty file for read
* open existing file with records for read
* open existing empty file for write
* open existing file with records for write
* write to empty file
* write to file with existing records
* sss_colondb_open()
* sss_colondb_readline()
* sss_colondb_write_line()
* write to empty file and read it
Resolves:
https://fedorahosted.org/sssd/ticket/2764
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit b590f44c06158485357d69cc5b24d5af05f1bb95)
(cherry picked from commit b269edafff139510ee1e9c00bdbc8f27e8aea691)
---
Makefile.am | 17 ++
src/tests/cmocka/test_tools_colondb.c | 419 ++++++++++++++++++++++++++++++++++
2 files changed, 436 insertions(+)
create mode 100644 src/tests/cmocka/test_tools_colondb.c
diff --git a/Makefile.am b/Makefile.am
index 22653cfe08ca1fa42f551bdd585868a7e56046ba..9bd5d0ba895bf699c0b9a46f86419adbd266aece 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -241,6 +241,7 @@ if HAVE_CMOCKA
pam-srv-tests \
test_ipa_subdom_util \
test_ipa_subdom_server \
+ test_tools_colondb \
test_krb5_wait_queue \
test_cert_utils \
test_ldap_id_cleanup \
@@ -2579,6 +2580,22 @@ test_ipa_subdom_server_LDADD = \
libdlopen_test_providers.la \
$(NULL)
+test_tools_colondb_SOURCES = \
+ src/tests/cmocka/test_tools_colondb.c \
+ src/tools/common/sss_colondb.c \
+ $(NULL)
+test_tools_colondb_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(NULL)
+test_tools_colondb_LDFLAGS = \
+ $(NULL)
+test_tools_colondb_LDADD = \
+ $(CMOCKA_LIBS) \
+ $(SSSD_INTERNAL_LTLIBS) \
+ $(POPT_LIBS) \
+ libsss_test_common.la \
+ $(NULL)
+
test_krb5_wait_queue_SOURCES = \
src/tests/cmocka/common_mock_be.c \
src/tests/cmocka/test_krb5_wait_queue.c \
diff --git a/src/tests/cmocka/test_tools_colondb.c b/src/tests/cmocka/test_tools_colondb.c
new file mode 100644
index 0000000000000000000000000000000000000000..5aa105896b3690127b5bf3241fe2b27d2ae2f920
--- /dev/null
+++ b/src/tests/cmocka/test_tools_colondb.c
@@ -0,0 +1,419 @@
+/*
+ Authors:
+ Petr Čech <pcech@redhat.com>
+
+ Copyright (C) 2015 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 <talloc.h>
+#include <errno.h>
+#include <popt.h>
+
+#include "tests/cmocka/common_mock.h"
+#include "src/tools/common/sss_colondb.h"
+
+#define TESTS_PATH "tp_" BASE_FILE_STEM
+#define TESTS_FILE "test_colondb.ldb"
+
+const char *TEST_STRING1 = "white";
+const int TEST_INT1 = 12;
+
+const char *TEST_STRING2 = "black";
+const int TEST_INT2 = 34;
+
+static void create_dir(const char *path)
+{
+ errno_t ret;
+
+ errno = 0;
+ ret = mkdir(path, 0775);
+ assert_return_code(ret, errno);
+}
+
+static void create_empty_file(TALLOC_CTX *test_ctx, const char *path,
+ const char *name)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ char *file_name = NULL;
+ FILE *fp = NULL;
+
+ tmp_ctx = talloc_new(test_ctx);
+ assert_non_null(tmp_ctx);
+
+ create_dir(path);
+
+ file_name = talloc_asprintf(tmp_ctx, "%s/%s", path, name);
+ assert_non_null(file_name);
+
+ fp = fopen(file_name, "w");
+ assert_non_null(fp);
+ fclose(fp);
+
+ talloc_free(tmp_ctx);
+}
+
+static void create_nonempty_file(TALLOC_CTX *test_ctx,
+ const char *path, const char *name)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ struct sss_colondb *db = NULL;
+ errno_t ret;
+ struct sss_colondb_write_field table[] = {
+ { SSS_COLONDB_STRING, { .str = TEST_STRING2 } },
+ { SSS_COLONDB_UINT32, { .uint32 = TEST_INT2 } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+
+ tmp_ctx = talloc_new(test_ctx);
+ assert_non_null(tmp_ctx);
+
+ create_empty_file(test_ctx, TESTS_PATH, TESTS_FILE);
+
+ db = sss_colondb_open(tmp_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_writeline(db, table);
+ assert_int_equal(ret, EOK);
+
+ talloc_free(db);
+ talloc_free(tmp_ctx);
+}
+
+static int setup(void **state, int file_state)
+{
+ TALLOC_CTX *test_ctx = NULL;
+
+ assert_true(leak_check_setup());
+
+ check_leaks_push(global_talloc_context);
+ test_ctx = talloc_new(global_talloc_context);
+ assert_non_null(test_ctx);
+
+ switch (file_state) {
+ case 0:
+ break;
+ case 1:
+ create_empty_file(test_ctx, TESTS_PATH, TESTS_FILE);
+ break;
+ case 2:
+ create_nonempty_file(test_ctx, TESTS_PATH, TESTS_FILE);
+ break;
+ default:
+ break;
+ }
+
+ check_leaks_push(test_ctx);
+ *state = test_ctx;
+
+ return 0;
+}
+
+static int without_file_setup(void **state)
+{
+ return setup(state, 0);
+}
+
+static int with_empty_file_setup(void **state)
+{
+ return setup(state, 1);
+}
+
+static int with_nonempty_file_setup(void **state)
+{
+ return setup(state, 2);
+}
+
+static int teardown(void **state)
+{
+ errno_t ret;
+
+ errno = 0;
+ ret = unlink(TESTS_PATH "/" TESTS_FILE);
+ if (ret != 0) {
+ assert_int_equal(errno, ENOENT);
+ }
+
+ assert_true(check_leaks_pop(*state));
+ talloc_zfree(*state);
+
+ test_dom_suite_cleanup(TESTS_PATH, NULL, NULL);
+ assert_true(check_leaks_pop(global_talloc_context));
+ assert_true(leak_check_teardown());
+
+ return 0;
+}
+
+void test_open_nonexist_for_read(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_null(db);
+ talloc_free(db);
+}
+
+void test_open_nonexist_for_write(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_null(db);
+ talloc_free(db);
+}
+
+void test_open_exist_for_read(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+ talloc_free(db);
+}
+
+void test_open_exist_for_write(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+ talloc_free(db);
+}
+
+void test_open_nonempty_for_read(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+ talloc_free(db);
+}
+
+void test_open_nonempty_for_write(void **state)
+{
+
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+ talloc_free(db);
+}
+
+void test_write_to_empty(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+ struct sss_colondb_write_field table[] = {
+ { SSS_COLONDB_STRING, { .str = TEST_STRING1 } },
+ { SSS_COLONDB_UINT32, { .uint32 = TEST_INT1 } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+ errno_t ret;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_writeline(db, table);
+ assert_int_equal(ret, 0);
+
+ talloc_free(db);
+}
+
+void test_write_to_nonempty(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+ struct sss_colondb_write_field table[] = {
+ { SSS_COLONDB_STRING, { .str = TEST_STRING1 } },
+ { SSS_COLONDB_UINT32, { .uint32 = TEST_INT1 } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+ errno_t ret;
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_writeline(db, table);
+ assert_int_equal(ret, 0);
+
+ talloc_free(db);
+}
+
+void test_read_from_nonempty(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+ errno_t ret;
+ const char *string = NULL;
+ uint32_t number;
+ struct sss_colondb_read_field table[] = {
+ { SSS_COLONDB_STRING, { .str = &string } },
+ { SSS_COLONDB_UINT32, { .uint32 = &number } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_readline(test_ctx, db, table);
+ assert_int_equal(ret, 0);
+ assert_string_equal(string, TEST_STRING2);
+ assert_int_equal(number, TEST_INT2);
+
+ talloc_zfree(string);
+ talloc_free(db);
+}
+
+void test_read_from_empty(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+ errno_t ret;
+ const char *string;
+ uint32_t number;
+ struct sss_colondb_read_field table[] = {
+ { SSS_COLONDB_STRING, { .str = &string } },
+ { SSS_COLONDB_UINT32, { .uint32 = &number } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_readline(test_ctx, db, table);
+ assert_int_equal(ret, EOF);
+
+ talloc_free(db);
+}
+
+void test_write_read(void **state)
+{
+ TALLOC_CTX *test_ctx = *state;
+ struct sss_colondb *db = NULL;
+ errno_t ret;
+ const char *string = NULL;
+ uint32_t number;
+ struct sss_colondb_write_field table_in[] = {
+ { SSS_COLONDB_STRING, { .str = TEST_STRING2 } },
+ { SSS_COLONDB_UINT32, { .uint32 = TEST_INT2 } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+ struct sss_colondb_read_field table_out[] = {
+ { SSS_COLONDB_STRING, { .str = &string } },
+ { SSS_COLONDB_UINT32, { .uint32 = &number } },
+ { SSS_COLONDB_SENTINEL, { 0 } }
+ };
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_WRITE,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_writeline(db, table_in);
+ assert_int_equal(ret, 0);
+
+ talloc_free(db);
+
+ db = sss_colondb_open(test_ctx, SSS_COLONDB_READ,
+ TESTS_PATH "/" TESTS_FILE);
+ assert_non_null(db);
+
+ ret = sss_colondb_readline(test_ctx, db, table_out);
+ assert_int_equal(ret, 0);
+ assert_string_equal(string, TEST_STRING2);
+ assert_int_equal(number, TEST_INT2);
+
+ talloc_zfree(string);
+ talloc_free(db);
+}
+
+int main(int argc, const char *argv[])
+{
+ poptContext pc;
+ int opt;
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ SSSD_DEBUG_OPTS
+ POPT_TABLEEND
+ };
+
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(test_open_nonexist_for_read,
+ without_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_open_nonexist_for_write,
+ without_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_open_exist_for_read,
+ with_empty_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_open_exist_for_write,
+ with_empty_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_open_nonempty_for_read,
+ with_nonempty_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_open_nonempty_for_write,
+ with_nonempty_file_setup, teardown),
+
+ cmocka_unit_test_setup_teardown(test_write_to_empty,
+ with_empty_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_write_to_nonempty,
+ with_nonempty_file_setup, teardown),
+
+ cmocka_unit_test_setup_teardown(test_read_from_empty,
+ with_empty_file_setup, teardown),
+ cmocka_unit_test_setup_teardown(test_read_from_nonempty,
+ with_nonempty_file_setup, teardown),
+
+ cmocka_unit_test_setup_teardown(test_write_read,
+ with_empty_file_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);
+
+ /* Even though normally the tests should clean up after themselves
+ * they might not after a failed run. Remove the old db to be sure */
+ tests_set_cwd();
+ test_dom_suite_cleanup(TESTS_PATH, NULL, NULL);
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}
--
2.5.0

View File

@ -1,178 +0,0 @@
From 7dcecb5e2fb9fe83c3bbf52306e7c2b0365ff96d Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 25 Jan 2016 16:03:23 +0100
Subject: [PATCH 78/86] Add a new option ldap_group_external_member
Required for:
https://fedorahosted.org/sssd/ticket/2522
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 3cf7fdfcaedb986f42a6640e26aa057007b64045)
(cherry picked from commit 7db3bdfd6b1b845866c1ff062d25de5804141e89)
---
src/config/SSSDConfig/__init__.py.in | 1 +
src/config/etc/sssd.api.d/sssd-ad.conf | 1 +
src/config/etc/sssd.api.d/sssd-ipa.conf | 1 +
src/config/etc/sssd.api.d/sssd-ldap.conf | 1 +
src/db/sysdb.h | 1 +
src/man/sssd-ldap.5.xml | 16 ++++++++++++++++
src/providers/ad/ad_opts.c | 1 +
src/providers/ipa/ipa_opts.c | 1 +
src/providers/ldap/ldap_opts.c | 3 +++
src/providers/ldap/sdap.h | 1 +
10 files changed, 27 insertions(+)
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 09284fdd7c8e630b3745367b33b8ea0424ff466f..a400c831eb0e44f562c010f2a3649def21913287 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -333,6 +333,7 @@ option_strings = {
'ldap_group_objectsid' : _("objectSID attribute"),
'ldap_group_modify_timestamp' : _('Modification time attribute for groups'),
'ldap_group_type' : _('Type of the group and other flags'),
+ 'ldap_group_external_member' : _('The LDAP group external member attribute'),
#replaced by ldap_entry_usn# 'ldap_group_entry_usn' : _('entryUSN attribute'),
'ldap_group_nesting_level' : _('Maximum nesting level SSSd will follow'),
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index 149590f4f30de3438f2fc5534ae65c98ee0f10ad..23006d26ca6fe7ca2b912ef091b4c73d5d23bee1 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -110,6 +110,7 @@ ldap_group_objectsid = str, None, false
ldap_group_modify_timestamp = str, None, false
ldap_group_entry_usn = str, None, false
ldap_group_type = int, None, false
+ldap_group_external_member = str, None, false
ldap_force_upper_case_realm = bool, None, false
ldap_group_nesting_level = int, None, false
ldap_netgroup_search_base = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 822599db6390ad2244a71db770c0b162345a3321..8cd20c0c621a513ca7bc85be6908de41d024b148 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -104,6 +104,7 @@ ldap_group_objectsid = str, None, false
ldap_group_modify_timestamp = str, None, false
ldap_group_entry_usn = str, None, false
ldap_group_type = int, None, false
+ldap_group_external_member = str, None, false
ldap_force_upper_case_realm = bool, None, false
ldap_group_nesting_level = int, None, false
ldap_netgroup_search_base = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index fc9fcefce94891760a3f3ada4c044dbcaf156945..8b52f268af195bc68d45389cda52a0ad0aba1aa3 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -98,6 +98,7 @@ ldap_group_objectsid = str, None, false
ldap_group_modify_timestamp = str, None, false
ldap_group_entry_usn = str, None, false
ldap_group_type = int, None, false
+ldap_group_external_member = str, None, false
ldap_group_nesting_level = int, None, false
ldap_force_upper_case_realm = bool, None, false
ldap_netgroup_search_base = str, None, false
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 2e797fd7fa39163c2ab6a10e51228e0f1af3f9e3..95a9086766228a6c36c56d3a68a0bb0e493c0cbe 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -81,6 +81,7 @@
#define SYSDB_USER_CATEGORY "userCategory"
#define SYSDB_HOST_CATEGORY "hostCategory"
#define SYSDB_GROUP_TYPE "groupType"
+#define SYSDB_EXTERNAL_MEMBER "externalMember"
#define SYSDB_GECOS "gecos"
#define SYSDB_LAST_LOGIN "lastLogin"
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index 66b9024bcdc6faced67c4e44f9cde7caa9a5ecc8..a30100408c6e77f9156878cb6ff63dfbf7b041d1 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -942,6 +942,22 @@
</varlistentry>
<varlistentry>
+ <term>ldap_group_external_member (string)</term>
+ <listitem>
+ <para>
+ The LDAP attribute that references group
+ members that are defined in an external
+ domain. At the moment, only IPA's external
+ members are supported.
+ </para>
+ <para>
+ Default: ipaExternalMember in the IPA provider,
+ otherwise unset.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>ldap_group_nesting_level (integer)</term>
<listitem>
<para>
diff --git a/src/providers/ad/ad_opts.c b/src/providers/ad/ad_opts.c
index 28d4768b20bd035f7c1971c95f9b6b690844816e..15024adb7959de9e16cdc92ca30daa74bb5f648d 100644
--- a/src/providers/ad/ad_opts.c
+++ b/src/providers/ad/ad_opts.c
@@ -233,6 +233,7 @@ struct sdap_attr_map ad_2008r2_group_map[] = {
{ "ldap_group_modify_timestamp", "whenChanged", SYSDB_ORIG_MODSTAMP, NULL },
{ "ldap_group_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL },
{ "ldap_group_type", "groupType", SYSDB_GROUP_TYPE, NULL },
+ { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
index cd87852e5891fd43d7ec728f76860f3050a54d2f..fe469852b527ad872502b3346c8c11ef9eea3bcd 100644
--- a/src/providers/ipa/ipa_opts.c
+++ b/src/providers/ipa/ipa_opts.c
@@ -219,6 +219,7 @@ struct sdap_attr_map ipa_group_map[] = {
{ "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
{ "ldap_group_entry_usn", NULL, SYSDB_USN, NULL },
{ "ldap_group_type", NULL, SYSDB_GROUP_TYPE, NULL },
+ { "ldap_group_external_member", "ipaExternalMember", SYSDB_EXTERNAL_MEMBER, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ldap/ldap_opts.c b/src/providers/ldap/ldap_opts.c
index 84ba2b54271bcb6650e0336131ace8bfc1a40fc8..ff9bf0d8b6d4a8f677e08219e5105e3750b7a4a8 100644
--- a/src/providers/ldap/ldap_opts.c
+++ b/src/providers/ldap/ldap_opts.c
@@ -195,6 +195,7 @@ struct sdap_attr_map rfc2307_group_map[] = {
{ "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
{ "ldap_group_entry_usn", NULL, SYSDB_USN, NULL },
{ "ldap_group_type", NULL, SYSDB_GROUP_TYPE, NULL },
+ { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
@@ -251,6 +252,7 @@ struct sdap_attr_map rfc2307bis_group_map[] = {
{ "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL },
{ "ldap_group_entry_usn", NULL, SYSDB_USN, NULL },
{ "ldap_group_type", NULL, SYSDB_GROUP_TYPE, NULL },
+ { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
@@ -307,6 +309,7 @@ struct sdap_attr_map gen_ad2008r2_group_map[] = {
{ "ldap_group_modify_timestamp", "whenChanged", SYSDB_ORIG_MODSTAMP, NULL },
{ "ldap_group_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL },
{ "ldap_group_type", "groupType", SYSDB_GROUP_TYPE, NULL },
+ { "ldap_group_external_member", NULL, SYSDB_EXTERNAL_MEMBER, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index e06f2b6ac47990f21985fb86f8ad3f3ae5a74df3..9dc2e16a0da76246a1f4492cf70e9124edba4a31 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -304,6 +304,7 @@ enum sdap_group_attrs {
SDAP_AT_GROUP_MODSTAMP,
SDAP_AT_GROUP_USN,
SDAP_AT_GROUP_TYPE,
+ SDAP_AT_GROUP_EXT_MEMBER,
SDAP_OPTS_GROUP /* attrs counter */
};
--
2.5.0

View File

@ -1,446 +0,0 @@
From 3725d2a83ae64be47c1bb645933f3a2abc91bd08 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 25 Jan 2016 16:11:59 +0100
Subject: [PATCH 79/86] IPA: Add interface to call into IPA provider from LDAP
provider
https://fedorahosted.org/sssd/ticket/2522
Adds a pluggable interface that is able to resolve the IPA group's
external members. At the moment, the request calls the full be_
interface to make sure all corner cases like id-views are handled
internally.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit e2d96566aeb881bd89e5c9236d663f6a9a88019a)
(cherry picked from commit 00ee45423f0712b83926c6f8b354a1a18ff741c8)
---
src/providers/ipa/ipa_id.c | 5 +-
src/providers/ipa/ipa_init.c | 28 +++
src/providers/ipa/ipa_subdomains.h | 11 ++
src/providers/ipa/ipa_subdomains_ext_groups.c | 275 ++++++++++++++++++++++++++
src/providers/ipa/ipa_subdomains_id.c | 1 +
src/providers/ldap/sdap.h | 23 +++
6 files changed, 342 insertions(+), 1 deletion(-)
diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c
index 27cc2548d8802c81311c6c5bd10a0db4e8930fa1..29e22982c415220c931f0422e10cd06dfa1a195b 100644
--- a/src/providers/ipa/ipa_id.c
+++ b/src/providers/ipa/ipa_id.c
@@ -405,7 +405,10 @@ static int ipa_initgr_get_overrides_step(struct tevent_req *req)
/* This should never happen, the search filter used to get the list
* of groups includes "uuid=*"
*/
- DEBUG(SSSDBG_OP_FAILURE, "A group with no UUID, error!\n");
+ DEBUG(SSSDBG_OP_FAILURE,
+ "The group %s has no UUID attribute %s, error!\n",
+ ldb_dn_get_linearized(state->groups[state->group_idx]->dn),
+ state->groups_id_attr);
return EINVAL;
}
diff --git a/src/providers/ipa/ipa_init.c b/src/providers/ipa/ipa_init.c
index 0e16dd97c78a087256fb77be500c9741484867c5..453e2b25673ac709c9fa3809d35b7885630c8b24 100644
--- a/src/providers/ipa/ipa_init.c
+++ b/src/providers/ipa/ipa_init.c
@@ -139,6 +139,24 @@ int common_ipa_init(struct be_ctx *bectx)
return EOK;
}
+static struct sdap_ext_member_ctx *
+ipa_create_ext_members_ctx(TALLOC_CTX *mem_ctx,
+ struct ipa_id_ctx *id_ctx)
+{
+ struct sdap_ext_member_ctx *ext_ctx = NULL;
+
+ ext_ctx = talloc_zero(mem_ctx, struct sdap_ext_member_ctx);
+ if (ext_ctx == NULL) {
+ return NULL;
+ }
+
+ ext_ctx->pvt = id_ctx;
+ ext_ctx->ext_member_resolve_send = ipa_ext_group_member_send;
+ ext_ctx->ext_member_resolve_recv = ipa_ext_group_member_recv;
+
+ return ext_ctx;
+}
+
int sssm_ipa_id_init(struct be_ctx *bectx,
struct bet_ops **ops,
void **pvt_data)
@@ -360,6 +378,16 @@ int sssm_ipa_id_init(struct be_ctx *bectx,
"will not work [%d]: %s\n", ret, strerror(ret));
}
+ ipa_ctx->sdap_id_ctx->opts->ext_ctx = ipa_create_ext_members_ctx(
+ ipa_ctx->sdap_id_ctx->opts,
+ ipa_ctx);
+ if (ipa_ctx->sdap_id_ctx->opts->ext_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Unable to set SRV the extrernal group ctx\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
*ops = &ipa_id_ops;
*pvt_data = ipa_ctx;
ret = EOK;
diff --git a/src/providers/ipa/ipa_subdomains.h b/src/providers/ipa/ipa_subdomains.h
index 0c13f8ed2eeda87237dfb097f532c7137095ddf1..23c3b7e3cd3ee1e0ac1dbcf98dc71a6c2337b835 100644
--- a/src/providers/ipa/ipa_subdomains.h
+++ b/src/providers/ipa/ipa_subdomains.h
@@ -137,4 +137,15 @@ struct tevent_req *ipa_get_ad_memberships_send(TALLOC_CTX *mem_ctx,
const char *domain);
errno_t ipa_get_ad_memberships_recv(struct tevent_req *req, int *dp_error_out);
+
+struct tevent_req *ipa_ext_group_member_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ const char *ext_member,
+ void *pvt);
+errno_t ipa_ext_group_member_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ enum sysdb_member_type *_member_type,
+ struct sss_domain_info **_dom,
+ struct sysdb_attrs **_member);
+
#endif /* _IPA_SUBDOMAINS_H_ */
diff --git a/src/providers/ipa/ipa_subdomains_ext_groups.c b/src/providers/ipa/ipa_subdomains_ext_groups.c
index d487a58b8adffabe09ff50e31cb750b800b1d252..5dc6d0d6417ec3fb5e7865e4cbaf3c07f4afbd07 100644
--- a/src/providers/ipa/ipa_subdomains_ext_groups.c
+++ b/src/providers/ipa/ipa_subdomains_ext_groups.c
@@ -923,3 +923,278 @@ static errno_t ipa_add_ad_memberships_recv(struct tevent_req *req,
return EOK;
}
+
+static errno_t
+search_user_or_group_by_sid_str(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *sid_str,
+ enum sysdb_member_type *_member_type,
+ struct ldb_message **_msg)
+{
+ errno_t ret;
+ struct ldb_message *msg = NULL;
+ const char *attrs[] = { SYSDB_NAME,
+ SYSDB_SID_STR,
+ SYSDB_ORIG_DN,
+ SYSDB_OBJECTCLASS,
+ SYSDB_CACHE_EXPIRE,
+ NULL };
+ TALLOC_CTX *tmp_ctx = NULL;
+ char *sanitized_sid = NULL;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+ return ENOMEM;
+ }
+
+ /* In theory SID shouldn't contain any special LDAP characters, but let's
+ * be paranoid
+ */
+ ret = sss_filter_sanitize(tmp_ctx, sid_str, &sanitized_sid);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = sysdb_search_user_by_sid_str(tmp_ctx, domain,
+ sid_str, attrs, &msg);
+ if (ret == EOK) {
+ *_member_type = SYSDB_MEMBER_USER;
+ } else if (ret == ENOENT) {
+ ret = sysdb_search_group_by_sid_str(tmp_ctx, domain,
+ sid_str, attrs, &msg);
+ if (ret == EOK) {
+ *_member_type = SYSDB_MEMBER_GROUP;
+ }
+ }
+
+ switch (ret) {
+ case EOK:
+ DEBUG(SSSDBG_TRACE_FUNC, "Found %s in sysdb\n", sid_str);
+ *_msg = talloc_steal(mem_ctx, msg);
+ break;
+ case ENOENT:
+ DEBUG(SSSDBG_TRACE_FUNC,
+ "Could not find %s in sysdb", sid_str);
+ break;
+ default:
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Error looking for %s in sysdb [%d]: %s\n",
+ sid_str, ret, sss_strerror(ret));
+ break;
+ }
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+static errno_t
+ipa_ext_group_member_check(TALLOC_CTX *mem_ctx,
+ struct ipa_id_ctx *ipa_ctx,
+ struct sss_domain_info *member_dom,
+ const char *ext_member,
+ enum sysdb_member_type *_member_type,
+ struct sysdb_attrs **_member)
+{
+ TALLOC_CTX *tmp_ctx = NULL;
+ errno_t ret;
+ uint64_t expire;
+ time_t now = time(NULL);
+ struct ldb_message *msg;
+ struct sysdb_attrs **members;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
+ return ENOMEM;
+ }
+
+ ret = search_user_or_group_by_sid_str(tmp_ctx, member_dom, ext_member,
+ _member_type, &msg);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Error looking up sid %s: [%d]: %s\n",
+ ext_member, ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = sysdb_msg2attrs(tmp_ctx, 1, &msg, &members);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Could not convert result to sysdb_attrs [%d]: %s\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ /* Return the member both expired and valid */
+ *_member = talloc_steal(mem_ctx, members[0]);
+
+ expire = ldb_msg_find_attr_as_uint64(msg, SYSDB_CACHE_EXPIRE, 0);
+ if (expire != 0 && expire <= now) {
+ DEBUG(SSSDBG_TRACE_FUNC, "%s is expired", ext_member);
+ ret = EAGAIN;
+ goto done;
+ }
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+/* For the IPA external member resolution, we expect a SID as the input.
+ * The _recv() function output is the member and a type (user/group)
+ * since nothing else can be a group member.
+ */
+struct ipa_ext_member_state {
+ const char *ext_member;
+ struct sss_domain_info *dom;
+
+ enum sysdb_member_type member_type;
+ struct sysdb_attrs *member;
+};
+
+static void ipa_ext_group_member_done(struct tevent_req *subreq);
+
+struct tevent_req *ipa_ext_group_member_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ const char *ext_member,
+ void *pvt)
+{
+ struct ipa_id_ctx *ipa_ctx;
+ struct ipa_ext_member_state *state;
+ struct tevent_req *req;
+ struct tevent_req *subreq;
+ struct be_acct_req *ar;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state, struct ipa_ext_member_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->ext_member = ext_member;
+
+ ipa_ctx = talloc_get_type(pvt, struct ipa_id_ctx);
+ if (ipa_ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Wrong private context!\n");
+ ret = EINVAL;
+ goto immediate;
+ }
+
+ state->dom = find_domain_by_sid(ipa_ctx->sdap_id_ctx->be->domain,
+ ext_member);
+ if (state->dom == NULL) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Cannot find domain of SID [%s]\n", ext_member);
+ ret = ENOENT;
+ goto immediate;
+ }
+
+ ret = ipa_ext_group_member_check(state, ipa_ctx, state->dom, ext_member,
+ &state->member_type, &state->member);
+ if (ret == EOK) {
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ "external member %s already cached\n", ext_member);
+ goto immediate;
+ }
+
+ ret = get_be_acct_req_for_sid(state, ext_member, state->dom->name, &ar);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Cannot create the account request for [%s]\n", ext_member);
+ goto immediate;
+ }
+
+ subreq = be_get_account_info_send(state, ev, NULL,
+ ipa_ctx->sdap_id_ctx->be, ar);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto immediate;
+ }
+ tevent_req_set_callback(subreq, ipa_ext_group_member_done, req);
+
+ return req;
+
+immediate:
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ } else {
+ tevent_req_done(req);
+ }
+ tevent_req_post(req, ev);
+ return req;
+}
+
+static void ipa_ext_group_member_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct ipa_ext_member_state *state = tevent_req_data(req,
+ struct ipa_ext_member_state);
+ errno_t ret;
+ int err_maj;
+ int err_min;
+ const char *err_msg;
+ struct ldb_message *msg;
+ struct sysdb_attrs **members;
+
+ ret = be_get_account_info_recv(subreq, state,
+ &err_maj, &err_min, &err_msg);
+ talloc_free(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "be request failed %d:%d: %s\n", err_maj, err_min, err_msg);
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ ret = search_user_or_group_by_sid_str(state,
+ state->dom,
+ state->ext_member,
+ &state->member_type,
+ &msg);
+ if (ret != EOK) {
+ DEBUG(ret == ENOENT ? SSSDBG_TRACE_FUNC : SSSDBG_OP_FAILURE,
+ "Could not find %s in sysdb [%d]: %s\n",
+ state->ext_member, ret, sss_strerror(ret));
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ ret = sysdb_msg2attrs(state, 1, &msg, &members);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Could not convert result to sysdb_attrs [%d]: %s\n",
+ ret, sss_strerror(ret));
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ state->member = members[0];
+ tevent_req_done(req);
+}
+
+errno_t ipa_ext_group_member_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ enum sysdb_member_type *_member_type,
+ struct sss_domain_info **_dom,
+ struct sysdb_attrs **_member)
+{
+ struct ipa_ext_member_state *state = tevent_req_data(req,
+ struct ipa_ext_member_state);
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ if (_member_type != NULL) {
+ *_member_type = state->member_type;
+ }
+
+ if (_dom) {
+ *_dom = state->dom;
+ }
+
+ if (_member != NULL) {
+ *_member = talloc_steal(mem_ctx, state->member);
+ }
+
+ return EOK;
+}
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index 472985d4ab4f785aa9c4af94bf8021829ca1c3c8..70a1b6a12799b5a645bbf69f8cc19c30dcff82c5 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -1230,6 +1230,7 @@ static errno_t ipa_get_ad_apply_override_step(struct tevent_req *req)
* attributes set, i.e. where overrides might not have been applied. */
ret = sysdb_asq_search(state, state->obj_dom, state->obj_msg->dn,
"(&("SYSDB_GC")("SYSDB_GIDNUM"=*)" \
+ "("SYSDB_POSIX"=TRUE)" \
"(!("ORIGINALAD_PREFIX SYSDB_GIDNUM"=*))" \
"(!("ORIGINALAD_PREFIX SYSDB_NAME"=*)))",
SYSDB_INITGR_ATTR,
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 9dc2e16a0da76246a1f4492cf70e9124edba4a31..e0e05da0c8270a8f131870bc755da862e43783cb 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -423,6 +423,26 @@ struct sdap_domain {
void *pvt;
};
+typedef struct tevent_req *
+(*ext_member_send_fn_t)(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ const char *ext_member,
+ void *pvt);
+typedef errno_t
+(*ext_member_recv_fn_t)(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req,
+ enum sysdb_member_type *member_type,
+ struct sss_domain_info **_dom,
+ struct sysdb_attrs **_member);
+
+struct sdap_ext_member_ctx {
+ /* Typically ID context of the external ID provider */
+ void *pvt;
+
+ ext_member_send_fn_t ext_member_resolve_send;
+ ext_member_recv_fn_t ext_member_resolve_recv;
+};
+
struct sdap_options {
struct dp_option *basic;
struct sdap_attr_map *gen_map;
@@ -435,6 +455,9 @@ struct sdap_options {
/* ID-mapping support */
struct sdap_idmap_ctx *idmap_ctx;
+ /* Resolving external members */
+ struct sdap_ext_member_ctx *ext_ctx;
+
/* FIXME - should this go to a special struct to avoid mixing with name-service-switch maps? */
struct sdap_attr_map *sudorule_map;
struct sdap_attr_map *autofs_mobject_map;
--
2.5.0

View File

@ -1,913 +0,0 @@
From 78e95161eb7e27f2160d47580c650930db42b5e8 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 25 Jan 2016 16:13:03 +0100
Subject: [PATCH 80/86] LDAP: Use the IPA provider interface to resolve
external group members
Resolves:
https://fedorahosted.org/sssd/ticket/2522
Currently the approach is not optimized for performance, because each
external member is resolved in a full transaction to make sure even ID
views and similar information is processed.
In future, we should implement https://fedorahosted.org/sssd/ticket/2943
we will again be able to process all the data in a single transaction.
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit c32266e79f9d4bebd0c31eaa8d6fa26050e7fb3e)
(cherry picked from commit 19194cb18a1cc20f02423861dd831aa5bc3a1003)
---
src/providers/ldap/sdap_async_groups.c | 49 +-
src/providers/ldap/sdap_async_nested_groups.c | 615 +++++++++++++++++++++++++-
src/providers/ldap/sdap_async_private.h | 16 +-
src/tests/cmocka/test_nested_groups.c | 4 +-
4 files changed, 656 insertions(+), 28 deletions(-)
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 31e0b86a94f1c3969c8fcafe463c591423a835f0..3c274bfccbe65aac9a7ce0fac55839fe05840b79 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -1758,6 +1758,7 @@ struct sdap_get_groups_state {
struct sysdb_attrs **groups;
size_t count;
size_t check_count;
+ hash_table_t *missing_external;
hash_table_t *user_hash;
hash_table_t *group_hash;
@@ -2333,6 +2334,8 @@ int sdap_get_groups_recv(struct tevent_req *req,
return EOK;
}
+static void sdap_nested_ext_done(struct tevent_req *subreq);
+
static void sdap_nested_done(struct tevent_req *subreq)
{
errno_t ret, tret;
@@ -2348,7 +2351,8 @@ static void sdap_nested_done(struct tevent_req *subreq)
struct sdap_get_groups_state);
ret = sdap_nested_group_recv(state, subreq, &user_count, &users,
- &group_count, &groups);
+ &group_count, &groups,
+ &state->missing_external);
talloc_zfree(subreq);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE, "Nested group processing failed: [%d][%s]\n",
@@ -2387,8 +2391,25 @@ static void sdap_nested_done(struct tevent_req *subreq)
}
in_transaction = false;
- /* Processing complete */
- tevent_req_done(req);
+ if (hash_count(state->missing_external) == 0) {
+ /* No external members. Processing complete */
+ DEBUG(SSSDBG_TRACE_INTERNAL, "No external members, done");
+ tevent_req_done(req);
+ return;
+ }
+
+ /* At the moment, we need to save the direct groups & members in one
+ * transaction and then query the others in a separate requests
+ */
+ subreq = sdap_nested_group_lookup_external_send(state, state->ev,
+ state->dom,
+ state->opts->ext_ctx,
+ state->missing_external);
+ if (subreq == NULL) {
+ ret = ENOMEM;
+ goto fail;
+ }
+ tevent_req_set_callback(subreq, sdap_nested_ext_done, req);
return;
fail:
@@ -2401,6 +2422,28 @@ fail:
tevent_req_error(req, ret);
}
+static void sdap_nested_ext_done(struct tevent_req *subreq)
+{
+ errno_t ret;
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct sdap_get_groups_state *state = tevent_req_data(req,
+ struct sdap_get_groups_state);
+
+ ret = sdap_nested_group_lookup_external_recv(state, subreq);
+ talloc_free(subreq);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Cannot resolve external members [%d]: %s\n",
+ ret, sss_strerror(ret));
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ tevent_req_done(req);
+ return;
+}
+
static errno_t sdap_nested_group_populate_users(TALLOC_CTX *mem_ctx,
struct sysdb_ctx *sysdb,
struct sss_domain_info *domain,
diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c
index 9d715225243d8672850563473bd3938d4cc5db6b..f0d04fa0948abd58470785d07b8d42f3cfeb9eb0 100644
--- a/src/providers/ldap/sdap_async_nested_groups.c
+++ b/src/providers/ldap/sdap_async_nested_groups.c
@@ -56,6 +56,13 @@ struct sdap_nested_group_member {
const char *group_filter;
};
+const size_t external_members_chunk = 16;
+
+struct sdap_external_missing_member {
+ const char **parent_group_dns;
+ size_t parent_dn_idx;
+};
+
struct sdap_nested_group_ctx {
struct sss_domain_info *domain;
struct sdap_options *opts;
@@ -64,6 +71,7 @@ struct sdap_nested_group_ctx {
struct sdap_handle *sh;
hash_table_t *users;
hash_table_t *groups;
+ hash_table_t *missing_external;
bool try_deref;
int deref_treshold;
int max_nesting_level;
@@ -184,37 +192,32 @@ done:
return ret;
}
-static errno_t sdap_nested_group_hash_entry(hash_table_t *table,
- struct sysdb_attrs *entry,
- const char *table_name)
+static errno_t sdap_nested_group_hash_insert(hash_table_t *table,
+ const char *entry_key,
+ void *entry_value,
+ bool overwrite,
+ const char *table_name)
{
hash_key_t key;
hash_value_t value;
- const char *name = NULL;
- errno_t ret;
int hret;
- ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &name);
- if (ret != EOK) {
- return ret;
- }
-
DEBUG(SSSDBG_TRACE_ALL, "Inserting [%s] into hash table [%s]\n",
- name, table_name);
+ entry_key, table_name);
key.type = HASH_KEY_STRING;
- key.str = talloc_strdup(NULL, name);
+ key.str = talloc_strdup(NULL, entry_key);
if (key.str == NULL) {
return ENOMEM;
}
- if (hash_has_key(table, &key)) {
+ if (overwrite == false && hash_has_key(table, &key)) {
talloc_free(key.str);
return EEXIST;
}
value.type = HASH_VALUE_PTR;
- value.ptr = entry;
+ value.ptr = entry_value;
hret = hash_enter(table, &key, &value);
if (hret != HASH_SUCCESS) {
@@ -228,6 +231,21 @@ static errno_t sdap_nested_group_hash_entry(hash_table_t *table,
return EOK;
}
+static errno_t sdap_nested_group_hash_entry(hash_table_t *table,
+ struct sysdb_attrs *entry,
+ const char *table_name)
+{
+ const char *name = NULL;
+ errno_t ret;
+
+ ret = sysdb_attrs_get_string(entry, SYSDB_ORIG_DN, &name);
+ if (ret != EOK) {
+ return ret;
+ }
+
+ return sdap_nested_group_hash_insert(table, name, entry, false, table_name);
+}
+
static errno_t
sdap_nested_group_hash_user(struct sdap_nested_group_ctx *group_ctx,
struct sysdb_attrs *user)
@@ -297,6 +315,76 @@ sdap_nested_group_hash_group(struct sdap_nested_group_ctx *group_ctx,
return sdap_nested_group_hash_entry(group_ctx->groups, group, "groups");
}
+static errno_t sdap_nested_group_external_add(hash_table_t *table,
+ const char *ext_member,
+ const char *parent_group_dn)
+{
+ hash_key_t key;
+ hash_value_t value;
+ int hret;
+ int ret;
+ struct sdap_external_missing_member *ext_mem;
+
+ key.type = HASH_KEY_STRING;
+ key.str = discard_const(ext_member);
+
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Inserting external member [%s] into external members hash table\n",
+ ext_member);
+
+ hret = hash_lookup(table, &key, &value);
+ switch (hret) {
+ case HASH_ERROR_KEY_NOT_FOUND:
+ ext_mem = talloc_zero(table, struct sdap_external_missing_member);
+ if (ext_mem == NULL) {
+ return ENOMEM;
+ }
+ ext_mem->parent_group_dns = talloc_zero_array(ext_mem,
+ const char *,
+ external_members_chunk);
+ if (ext_mem->parent_group_dns == NULL) {
+ talloc_free(ext_mem);
+ return ENOMEM;
+ }
+
+ ret = sdap_nested_group_hash_insert(table, ext_member, ext_mem,
+ true, "missing external users");
+ if (ret != EOK) {
+ return ret;
+ }
+ break;
+
+ case HASH_SUCCESS:
+ ext_mem = talloc_get_type(value.ptr,
+ struct sdap_external_missing_member);
+ if (ext_mem->parent_dn_idx == \
+ talloc_array_length(ext_mem->parent_group_dns)) {
+ ext_mem->parent_group_dns = talloc_realloc(ext_mem,
+ ext_mem->parent_group_dns,
+ const char *,
+ ext_mem->parent_dn_idx + \
+ external_members_chunk);
+ if (ext_mem->parent_group_dns == NULL) {
+ talloc_free(ext_mem);
+ return ENOMEM;
+ }
+ }
+ break;
+ default:
+ return EIO;
+ }
+
+ ext_mem->parent_group_dns[ext_mem->parent_dn_idx] = \
+ talloc_strdup(ext_mem->parent_group_dns,
+ parent_group_dn);
+ if (ext_mem->parent_group_dns[ext_mem->parent_dn_idx] == NULL) {
+ return ENOMEM;
+ }
+ ext_mem->parent_dn_idx++;
+
+ return EOK;
+}
+
static errno_t sdap_nested_group_sysdb_search(struct sss_domain_info *domain,
const char *filter,
bool user)
@@ -478,6 +566,13 @@ sdap_nested_group_split_members(TALLOC_CTX *mem_ctx,
errno_t ret;
int i;
+ if (members == NULL) {
+ *_missing = NULL;
+ *_num_missing = 0;
+ *_num_groups = 0;
+ return EOK;
+ }
+
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
@@ -619,6 +714,65 @@ done:
return ret;
}
+static errno_t
+sdap_nested_group_add_ext_members(TALLOC_CTX *mem_ctx,
+ struct sdap_nested_group_ctx *group_ctx,
+ struct sysdb_attrs *group,
+ struct ldb_message_element *ext_members)
+{
+ errno_t ret;
+ const char *ext_member_attr;
+ const char *orig_dn;
+
+ if (ext_members == NULL) {
+ return EOK;
+ }
+
+ ret = sysdb_attrs_get_string(group, SYSDB_ORIG_DN, &orig_dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "A group with no originalDN!?!\n");
+ return ret;
+ }
+
+ for (size_t i = 0; i < ext_members->num_values; i++) {
+ ext_member_attr = (const char *) ext_members->values[i].data;
+
+ ret = sdap_nested_group_external_add(group_ctx->missing_external,
+ ext_member_attr,
+ orig_dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot add %s into external members [%d]: %s\n",
+ ext_member_attr, ret, sss_strerror(ret));
+ return ret;
+ }
+ }
+
+ return EOK;
+}
+
+static struct ldb_message_element *
+sdap_nested_group_ext_members(struct sdap_options *opts,
+ struct sysdb_attrs *group)
+{
+ errno_t ret;
+ struct ldb_message_element *ext_members = NULL;
+
+ if (opts->ext_ctx == NULL) {
+ return NULL;
+ }
+
+ ret = sysdb_attrs_get_el_ext(group,
+ opts->group_map[SDAP_AT_GROUP_EXT_MEMBER].sys_name,
+ false, &ext_members);
+ if (ret != EOK && ret != ENOENT) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve external member list "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ }
+
+ return ext_members;
+}
+
struct sdap_nested_group_state {
struct sdap_nested_group_ctx *group_ctx;
@@ -667,6 +821,14 @@ sdap_nested_group_send(TALLOC_CTX *mem_ctx,
goto immediately;
}
+ ret = sss_hash_create(state->group_ctx, 32,
+ &state->group_ctx->missing_external);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n",
+ ret, strerror(ret));
+ goto immediately;
+ }
+
state->group_ctx->try_deref = true;
state->group_ctx->deref_treshold = dp_opt_get_int(opts->basic,
SDAP_DEREF_THRESHOLD);
@@ -760,7 +922,8 @@ errno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx,
unsigned long *_num_users,
struct sysdb_attrs ***_users,
unsigned long *_num_groups,
- struct sysdb_attrs ***_groups)
+ struct sysdb_attrs ***_groups,
+ hash_table_t **_missing_external)
{
struct sdap_nested_group_state *state = NULL;
struct sysdb_attrs **users = NULL;
@@ -807,6 +970,11 @@ errno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx,
*_groups = talloc_steal(mem_ctx, groups);
}
+ if (_missing_external) {
+ *_missing_external = talloc_steal(mem_ctx,
+ state->group_ctx->missing_external);
+ }
+
return EOK;
}
@@ -816,6 +984,7 @@ struct sdap_nested_group_process_state {
struct sdap_nested_group_member *missing;
int num_missing_total;
int num_missing_groups;
+ struct ldb_message_element *ext_members;
int nesting_level;
char *group_dn;
bool deref;
@@ -866,13 +1035,16 @@ sdap_nested_group_process_send(TALLOC_CTX *mem_ctx,
DEBUG(SSSDBG_TRACE_INTERNAL, "About to process group [%s]\n", orig_dn);
- /* get member list */
+ /* get member list, both direct and external */
+ state->ext_members = sdap_nested_group_ext_members(state->group_ctx->opts,
+ group);
+
ret = sysdb_attrs_get_el_ext(group, group_map[SDAP_AT_GROUP_MEMBER].sys_name,
false, &members);
- if (ret == ENOENT) {
- ret = EOK; /* no members */
+ if (ret == ENOENT && state->ext_members == NULL) {
+ ret = EOK; /* no members, direct or external */
goto immediately;
- } else if (ret != EOK) {
+ } else if (ret != EOK && ret != ENOENT) {
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to retrieve member list "
"[%d]: %s\n", ret, strerror(ret));
goto immediately;
@@ -890,14 +1062,31 @@ sdap_nested_group_process_send(TALLOC_CTX *mem_ctx,
goto immediately;
}
- DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up %d/%d members of group [%s]\n",
- state->num_missing_total, members->num_values, orig_dn);
+ ret = sdap_nested_group_add_ext_members(state,
+ state->group_ctx,
+ group,
+ state->ext_members);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to split external member list "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto immediately;
+ }
- if (state->num_missing_total == 0) {
+ if (state->num_missing_total == 0
+ && hash_count(state->group_ctx->missing_external) == 0) {
ret = EOK; /* we're done */
goto immediately;
}
+ /* If there are only indirect members of the group, it's still safe to
+ * proceed and let the direct lookup code just fall through.
+ */
+
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Looking up %d/%d members of group [%s]\n",
+ state->num_missing_total,
+ members ? members->num_values : 0,
+ orig_dn);
+
/* process members */
if (group_ctx->try_deref
&& state->num_missing_total > group_ctx->deref_treshold) {
@@ -2268,3 +2457,385 @@ static errno_t sdap_nested_group_deref_recv(struct tevent_req *req)
return EOK;
}
+
+struct sdap_ext_member {
+ struct sdap_external_missing_member *missing_mem;
+ const char *ext_member_attr;
+
+ enum sysdb_member_type member_type;
+ struct sss_domain_info *dom;
+ struct sysdb_attrs *attrs;
+};
+
+struct sdap_nested_group_lookup_external_state {
+ struct tevent_context *ev;
+ struct sdap_ext_member_ctx *ext_ctx;
+ struct sss_domain_info *group_dom;
+ hash_table_t *missing_external;
+
+ hash_entry_t *entries;
+ unsigned long n_entries;
+ unsigned long eniter;
+
+ struct sdap_ext_member *ext_members;
+
+ ext_member_send_fn_t ext_member_resolve_send;
+ ext_member_recv_fn_t ext_member_resolve_recv;
+};
+
+static errno_t
+sdap_nested_group_lookup_external_step(struct tevent_req *req);
+static void
+sdap_nested_group_lookup_external_done(struct tevent_req *subreq);
+static errno_t
+sdap_nested_group_lookup_external_link(struct tevent_req *req);
+static errno_t
+sdap_nested_group_lookup_external_link_member(
+ struct sdap_nested_group_lookup_external_state *state,
+ struct sdap_ext_member *member);
+static errno_t
+sdap_nested_group_memberof_dn_by_original_dn(
+ TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *group_dom,
+ const char *original_dn,
+ const char ***_parents);
+
+struct tevent_req *
+sdap_nested_group_lookup_external_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sss_domain_info *group_dom,
+ struct sdap_ext_member_ctx *ext_ctx,
+ hash_table_t *missing_external)
+{
+ struct sdap_nested_group_lookup_external_state *state = NULL;
+ struct tevent_req *req = NULL;
+ errno_t ret;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct sdap_nested_group_lookup_external_state);
+ if (req == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "tevent_req_create() failed\n");
+ return NULL;
+ }
+
+ state->ev = ev;
+ state->group_dom = group_dom;
+ state->ext_ctx = ext_ctx;
+ state->missing_external = missing_external;
+
+ if (state->ext_ctx->ext_member_resolve_send == NULL
+ || state->ext_ctx->ext_member_resolve_recv == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Wrong private context\n");
+ ret = EINVAL;
+ goto immediately;
+ }
+
+ ret = hash_entries(state->missing_external,
+ &state->n_entries, &state->entries);
+ if (ret != HASH_SUCCESS) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "hash_entries returned %d\n", ret);
+ ret = EIO;
+ goto immediately;
+ }
+ state->eniter = 0;
+
+ state->ext_members = talloc_zero_array(state,
+ struct sdap_ext_member,
+ state->n_entries);
+ if (state->ext_members == NULL) {
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ ret = sdap_nested_group_lookup_external_step(req);
+ if (ret != EAGAIN) {
+ goto immediately;
+ }
+
+ return req;
+
+immediately:
+ if (ret == EOK) {
+ tevent_req_done(req);
+ } else {
+ tevent_req_error(req, ret);
+ }
+ tevent_req_post(req, ev);
+ return req;
+}
+
+static errno_t
+sdap_nested_group_lookup_external_step(struct tevent_req *req)
+{
+ struct tevent_req *subreq = NULL;
+ struct sdap_nested_group_lookup_external_state *state = NULL;
+ state = tevent_req_data(req,
+ struct sdap_nested_group_lookup_external_state);
+
+ subreq = state->ext_ctx->ext_member_resolve_send(state,
+ state->ev,
+ state->entries[state->eniter].key.str,
+ state->ext_ctx->pvt);
+ if (subreq == NULL) {
+ return ENOMEM;
+ }
+ DEBUG(SSSDBG_TRACE_FUNC, "Refreshing member %lu/%lu\n",
+ state->eniter, state->n_entries);
+ tevent_req_set_callback(subreq,
+ sdap_nested_group_lookup_external_done,
+ req);
+
+ return EAGAIN;
+}
+
+static void
+sdap_nested_group_lookup_external_done(struct tevent_req *subreq)
+{
+ errno_t ret;
+ struct tevent_req *req = NULL;
+ struct sdap_nested_group_lookup_external_state *state = NULL;
+ enum sysdb_member_type member_type;
+ struct sysdb_attrs *member;
+ struct sss_domain_info *member_dom;
+
+ req = tevent_req_callback_data(subreq, struct tevent_req);
+ state = tevent_req_data(req,
+ struct sdap_nested_group_lookup_external_state);
+
+ ret = state->ext_ctx->ext_member_resolve_recv(state, subreq,
+ &member_type,
+ &member_dom,
+ &member);
+ talloc_free(subreq);
+ if (ret == EOK) {
+ DEBUG(SSSDBG_TRACE_FUNC, "Refreshing member %lu\n", state->eniter);
+ state->ext_members[state->eniter].missing_mem = \
+ state->entries[state->eniter].value.ptr;
+ state->ext_members[state->eniter].dom = member_dom;
+
+ state->ext_members[state->eniter].ext_member_attr = \
+ talloc_steal(state->ext_members,
+ state->entries[state->eniter].key.str);
+ state->ext_members[state->eniter].member_type = member_type;
+ state->ext_members[state->eniter].attrs = \
+ talloc_steal(state->ext_members, member);
+ }
+
+ state->eniter++;
+ if (state->eniter >= state->n_entries) {
+ DEBUG(SSSDBG_TRACE_FUNC, "All external members processed\n");
+ ret = sdap_nested_group_lookup_external_link(req);
+ if (ret != EOK) {
+ tevent_req_error(req, ret);
+ return;
+ }
+ tevent_req_done(req);
+ return;
+ }
+
+ ret = sdap_nested_group_lookup_external_step(req);
+ if (ret != EOK && ret != EAGAIN) {
+ tevent_req_error(req, ret);
+ return;
+ }
+
+ return;
+}
+
+static errno_t
+sdap_nested_group_lookup_external_link(struct tevent_req *req)
+{
+ errno_t ret, tret;
+ bool in_transaction = false;
+ struct sdap_nested_group_lookup_external_state *state = NULL;
+ state = tevent_req_data(req,
+ struct sdap_nested_group_lookup_external_state);
+
+ ret = sysdb_transaction_start(state->group_dom->sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
+ goto fail;
+ }
+ in_transaction = true;
+
+
+ for (size_t i = 0; i < state->eniter; i++) {
+ if (state->ext_members[i].attrs == NULL) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "The member %s could not be resolved\n",
+ state->ext_members[i].ext_member_attr);
+ continue;
+ }
+
+ ret = sdap_nested_group_lookup_external_link_member(state,
+ &state->ext_members[i]);
+ if (ret != EOK) {
+ goto fail;
+ }
+ }
+
+ ret = sysdb_transaction_commit(state->group_dom->sysdb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to commit transaction\n");
+ goto fail;
+ }
+ in_transaction = false;
+
+ return EOK;
+
+fail:
+ if (in_transaction) {
+ tret = sysdb_transaction_cancel(state->group_dom->sysdb);
+ if (tret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to cancel transaction\n");
+ }
+ }
+ return EFAULT;
+}
+
+static errno_t
+sdap_nested_group_lookup_external_link_member(
+ struct sdap_nested_group_lookup_external_state *state,
+ struct sdap_ext_member *member)
+{
+ const char *name;
+ int ret;
+ const char **parents = NULL;
+ size_t i;
+ TALLOC_CTX *tmp_ctx;
+ const char *orig_dn;
+
+ tmp_ctx = talloc_new(state);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sysdb_attrs_get_string(member->attrs, SYSDB_NAME, &name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "No name for a user\n");
+ goto done;
+ }
+
+ /* This only works because the groups were saved in a previous
+ * transaction */
+ for (i=0; i < member->missing_mem->parent_dn_idx; i++) {
+ orig_dn = member->missing_mem->parent_group_dns[i];
+ DEBUG(SSSDBG_TRACE_INTERNAL,
+ "Linking external members %s from domain %s to parents of %s\n",
+ name, member->dom->name, orig_dn);
+ ret = sdap_nested_group_memberof_dn_by_original_dn(tmp_ctx,
+ state->group_dom,
+ orig_dn,
+ &parents);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "Cannot find parents of %s\n", orig_dn);
+ continue;
+ }
+
+ /* We don't have to remove the members here, since all members attributes
+ * are always written anew
+ */
+ ret = sysdb_update_members_dn(member->dom, name, member->member_type,
+ parents, NULL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Cannot link %s@%s to its parents\n",
+ name, member->dom->name);
+ goto done;
+ }
+
+ }
+
+ ret = EOK;
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+static errno_t
+sdap_nested_group_memberof_dn_by_original_dn(
+ TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *group_dom,
+ const char *original_dn,
+ const char ***_parents)
+{
+ errno_t ret;
+ char *sanitized_dn;
+ char *filter;
+ const char *attrs[] = { SYSDB_NAME,
+ SYSDB_MEMBEROF,
+ NULL };
+ struct ldb_message **msgs = NULL;
+ size_t count;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_message_element *memberof;
+ const char **parents;
+
+ tmp_ctx = talloc_new(mem_ctx);
+ if (tmp_ctx == NULL) {
+ return ENOMEM;
+ }
+
+ ret = sss_filter_sanitize(tmp_ctx, original_dn, &sanitized_dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Cannot sanitize originalDN [%s]\n", original_dn);
+ goto done;
+ }
+
+ filter = talloc_asprintf(tmp_ctx, "(%s=%s)", SYSDB_ORIG_DN, sanitized_dn);
+ if (filter == NULL) {
+ goto done;
+ }
+
+ ret = sysdb_search_groups(tmp_ctx, group_dom, filter, attrs,
+ &count, &msgs);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ if (count != 1) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "More than one entry found by originalDN?\n");
+ goto done;
+ }
+
+ memberof = ldb_msg_find_element(msgs[0], SYSDB_MEMBEROF);
+ if (memberof == NULL || memberof->num_values == 0) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ "The external group is not a member of any groups\n");
+ ret = ENOENT;
+ goto done;
+ }
+
+ parents = talloc_zero_array(tmp_ctx,
+ const char *,
+ memberof->num_values + 1);
+ if (parents == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (size_t i = 0; i < memberof->num_values; i++) {
+ parents[i] = talloc_strdup(parents,
+ (const char *) memberof->values[i].data);
+ if (parents[i] == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ *_parents = talloc_steal(mem_ctx, parents);
+ ret = EOK;
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+errno_t
+sdap_nested_group_lookup_external_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req)
+{
+ TEVENT_REQ_RETURN_ON_ERROR(req);
+
+ return EOK;
+}
diff --git a/src/providers/ldap/sdap_async_private.h b/src/providers/ldap/sdap_async_private.h
index db542eaf869efcd53d0937bef3fc6e99cc78b938..9cde6f5dfe0114f797135b4989b9a4bd336a3f27 100644
--- a/src/providers/ldap/sdap_async_private.h
+++ b/src/providers/ldap/sdap_async_private.h
@@ -130,8 +130,20 @@ errno_t sdap_nested_group_recv(TALLOC_CTX *mem_ctx,
unsigned long *_num_users,
struct sysdb_attrs ***_users,
unsigned long *_num_groups,
- struct sysdb_attrs ***_groups);
+ struct sysdb_attrs ***_groups,
+ hash_table_t **missing_external);
+struct tevent_req *
+sdap_nested_group_lookup_external_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct sss_domain_info *group_dom,
+ struct sdap_ext_member_ctx *ext_ctx,
+ hash_table_t *missing_external);
+errno_t
+sdap_nested_group_lookup_external_recv(TALLOC_CTX *mem_ctx,
+ struct tevent_req *req);
+
+/* from sdap_async_initgroups.c */
errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
struct sss_domain_info *domain,
struct sdap_options *opts,
@@ -139,7 +151,7 @@ errno_t sdap_add_incomplete_groups(struct sysdb_ctx *sysdb,
struct sysdb_attrs **ldap_groups,
int ldap_groups_count);
-/* from sdap_async_nested_groups.c */
+/* from sdap_ad_groups.c */
errno_t sdap_check_ad_group_type(struct sss_domain_info *dom,
struct sdap_options *opts,
struct sysdb_attrs *group_attrs,
diff --git a/src/tests/cmocka/test_nested_groups.c b/src/tests/cmocka/test_nested_groups.c
index dc29768c5660d5815d5fab56ee70cc8c9caab330..a3345ef5e087fc90466ce8400dda549fa5d79af8 100644
--- a/src/tests/cmocka/test_nested_groups.c
+++ b/src/tests/cmocka/test_nested_groups.c
@@ -57,6 +57,7 @@ struct nested_groups_test_ctx {
struct sdap_domain *sdap_domain;
struct sdap_idmap_ctx *idmap_ctx;
struct sdap_id_ctx *sdap_id_ctx;
+ hash_table_t *missing_external;
struct sysdb_attrs **users;
struct sysdb_attrs **groups;
@@ -110,7 +111,8 @@ static void nested_groups_test_done(struct tevent_req *req)
ctx->tctx->error = sdap_nested_group_recv(ctx, req,
&ctx->num_users, &ctx->users,
- &ctx->num_groups, &ctx->groups);
+ &ctx->num_groups, &ctx->groups,
+ &ctx->missing_external);
talloc_zfree(req);
ctx->tctx->done = true;
--
2.5.0

View File

@ -1,37 +0,0 @@
From 245710d26dfa11db998f8a1406b086e76fb8f49b Mon Sep 17 00:00:00 2001
From: David Disseldorp <ddiss@samba.org>
Date: Wed, 24 Feb 2016 17:18:00 +0100
Subject: [PATCH 81/86] build: detect endianness at configure time
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
WORDS_BIGENDIAN, HAVE_BIG_ENDIAN and HAVE_LITTLE_ENDIAN are needed by
Samba. See Samba's byteorder.h header for an example.
Signed-off-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit faa16fc9f0c9a02b26497e7cf148a92586144c08)
(cherry picked from commit 15ccbb564d5cc7d6fc8e856811b7ed71c0e220a9)
---
configure.ac | 3 +++
1 file changed, 3 insertions(+)
diff --git a/configure.ac b/configure.ac
index 8ef2493c79a144d348200213f0ce1681d0fa3c1f..aebb3c3e9e8d3702295b1b5da28a04c46303af9b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -76,6 +76,9 @@ AC_CHECK_FUNCS([ utimensat \
#Check for endian headers
AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h])
+AC_C_BIGENDIAN([AC_DEFINE(HAVE_BIG_ENDIAN, [1], [whether platform is big endian])],
+ [AC_DEFINE(HAVE_LITTLE_ENDIAN, [1], [whether platform is little endian])])
+
#Set the NSS library install path
AC_ARG_ENABLE([nsslibdir], [AS_HELP_STRING([--enable-nsslibdir],
[Where to install nss libraries ($libdir)])],
--
2.5.0

View File

@ -1,143 +0,0 @@
From 75dabe3ec5398359f4cccfcd616959cd921cced2 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 18 Feb 2016 13:03:44 +0100
Subject: [PATCH 082/108] IPA: lookup idview name even if there is no master
domain record
Currently the IPA subdomain provider returns with a error if there is no
master domain record found. Since this record contains data which is
only needed to create a trust with AD, like e.g. the IPA domain SID,
this record is only created by ipa-adtrust-install. But the idview name
is read after the master domain record. To make the idview feature work
with a plain FreeIPA setup without running ipa-adtrust-install the
missing master domain record should be handled gracefully and the
following lookup should run as well.
Resolves https://fedorahosted.org/sssd/ticket/2960
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit b25d33b0a775e2337014a334699156ac56b08f9b)
(cherry picked from commit 022e4575980324c2c68a05b3f250bd1a72bc9885)
---
src/providers/ipa/ipa_subdomains.c | 80 +++++++++++++++++++++-----------------
1 file changed, 44 insertions(+), 36 deletions(-)
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index f13847f12a7eae42b13a51e3fe1d09b60878633b..c888279229c891f1d5b8763aa851617a5daedd51 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -1219,6 +1219,9 @@ static void ipa_subdomains_handler_master_done(struct tevent_req *req)
size_t reply_count = 0;
struct sysdb_attrs **reply = NULL;
struct ipa_subdomains_req_ctx *ctx;
+ const char *flat = NULL;
+ const char *id = NULL;
+ const char *realm = NULL;
ctx = tevent_req_callback_data(req, struct ipa_subdomains_req_ctx);
@@ -1230,10 +1233,6 @@ static void ipa_subdomains_handler_master_done(struct tevent_req *req)
}
if (reply_count) {
- const char *flat = NULL;
- const char *id = NULL;
- const char *realm;
-
ret = sysdb_attrs_get_string(reply[0], IPA_FLATNAME, &flat);
if (ret != EOK) {
goto done;
@@ -1244,31 +1243,9 @@ static void ipa_subdomains_handler_master_done(struct tevent_req *req)
goto done;
}
- realm = dp_opt_get_string(ctx->sd_ctx->id_ctx->ipa_options->basic,
- IPA_KRB5_REALM);
- if (realm == NULL) {
- DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n");
- ret = EINVAL;
- goto done;
- }
-
- ret = sysdb_master_domain_add_info(ctx->sd_ctx->be_ctx->domain,
- realm, flat, id, NULL);
- if (ret != EOK) {
- goto done;
- }
-
/* There is only one master record. Don't bother checking other IPA
* search bases; move to checking subdomains instead
*/
- ret = ipa_subdomains_handler_get_start(ctx,
- ctx->sd_ctx->search_bases,
- IPA_SUBDOMAINS_SLAVE);
- if (ret == EAGAIN) {
- return;
- }
-
- /* Either no search bases or an error. End the request in both cases */
} else {
ret = ipa_subdomains_handler_get_cont(ctx, IPA_SUBDOMAINS_MASTER);
if (ret == EAGAIN) {
@@ -1277,17 +1254,48 @@ static void ipa_subdomains_handler_master_done(struct tevent_req *req)
goto done;
}
- /* Right now we know there has been an error
- * and we don't have the master domain record
- */
- DEBUG(SSSDBG_CRIT_FAILURE, "Master domain record not found!\n");
-
- if (!ctx->sd_ctx->configured_explicit) {
- ctx->sd_ctx->disabled_until = time(NULL) +
- IPA_SUBDOMAIN_DISABLED_PERIOD;
+ /* All search paths are searched and no master domain record was
+ * found.
+ *
+ * A default IPA installation will not have a master domain record,
+ * this is only created by ipa-adtrust-install. Nevertheless we should
+ * continue to read other data like the idview on IPA clients. */
+
+ DEBUG(SSSDBG_TRACE_INTERNAL, "Master domain record not found!\n");
+
+ }
+
+ realm = dp_opt_get_string(ctx->sd_ctx->id_ctx->ipa_options->basic,
+ IPA_KRB5_REALM);
+ if (realm == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "No Kerberos realm for IPA?\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = sysdb_master_domain_add_info(ctx->sd_ctx->be_ctx->domain,
+ realm, flat, id, NULL);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ ret = ipa_subdomains_handler_get_start(ctx,
+ ctx->sd_ctx->search_bases,
+ IPA_SUBDOMAINS_SLAVE);
+ if (ret == EAGAIN) {
+ return;
+ } else if (ret == EOK) {
+ /* If there are no search bases defined for subdomains try to get the
+ * idview before ending the request */
+ if (ctx->sd_ctx->id_ctx->server_mode == NULL) {
+ /* Only get view on clients, on servers it is always 'default' */
+ ret = ipa_get_view_name(ctx);
+ if (ret == EAGAIN) {
+ return;
+ } else if (ret != EOK) {
+ goto done;
+ }
}
-
- ret = EIO;
}
done:
--
2.7.3

View File

@ -1,52 +0,0 @@
From 55fa5564a9835e9697555d1bfeb9336bcce2415f Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Mon, 22 Feb 2016 16:08:13 +0100
Subject: [PATCH 083/108] IPA: invalidate override data if original view is
missing
If the idview name cannot be read from cache this either means that the
cache was empty or the name wasn't written because of an error. In the
case of an error SSSD would assume that the default view was used. If
the new view is different from the default view the override data must be
invalidated. Since the sysdb call to invalidate the override data would
work with an empty cache as well and do nothing it is safe to call it on
both cases.
Related to https://fedorahosted.org/sssd/ticket/2960
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit b5d48539966aefbea703377ba2ebcb67f9cf88b8)
(cherry picked from commit 1d4d3f15b5cb9b9ffad521ddea0b1e3660587816)
---
src/providers/ipa/ipa_subdomains.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index c888279229c891f1d5b8763aa851617a5daedd51..cb5a23bfb8043e620061e11d5e567d3e39eab6e3 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -898,9 +898,19 @@ static void ipa_get_view_name_done(struct tevent_req *req)
} else {
if (ctx->sd_ctx->id_ctx->view_name == NULL
|| strcmp(ctx->sd_ctx->id_ctx->view_name, view_name) != 0) {
- /* View name changed */
+ /* View name changed. If there was a non-default non-local view
+ * was used the tree in cache containing the override values is
+ * removed. In all cases sysdb_invalidate_overrides() is called to
+ * remove the override attribute from the cached user objects.
+ *
+ * Typically ctx->sd_ctx->id_ctx->view_name == NULL means that the
+ * cache was empty but there was a bug in with caused that the
+ * view name was not written to the cache at all. In this case the
+ * cache must be invalidated if the new view is not the
+ * default-view as well. */
- if (ctx->sd_ctx->id_ctx->view_name != NULL) {
+ if (ctx->sd_ctx->id_ctx->view_name != NULL
+ || !is_default_view(view_name)) {
ret = sysdb_transaction_start(
ctx->sd_ctx->be_ctx->domain->sysdb);
if (ret != EOK) {
--
2.7.3

View File

@ -1,62 +0,0 @@
From 99c197025ad61a9ecd7ae3bcd02e9569415fb90a Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Fri, 26 Feb 2016 13:10:50 -0500
Subject: [PATCH 084/108] GPO: Add Cockpit to the Remote Interactive defaults
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The Cockpit Project is an administrative console that is gaining in
popularity and is a default component on some operating systems (such
as Fedora Server). Since it is becoming more common, we should ensure
that it is part of the standard mapping.
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit 0e799bc491f636c69657d1678af13d23bf7b7c10)
(cherry picked from commit 71e700368aa88a0adb14047b7fd8c97ff9487c28)
---
src/man/sssd-ad.5.xml | 5 +++++
src/providers/ad/ad_gpo.c | 4 +++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index 4280eac5f4594b26d158a0ea58622f9fe7beb53e..b042480dff164e3626f61c520e51bb756bcbfd9c 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -463,6 +463,11 @@ ad_gpo_map_remote_interactive = +my_pam_service, -sshd
sshd
</para>
</listitem>
+ <listitem>
+ <para>
+ cockpit
+ </para>
+ </listitem>
</itemizedlist>
</para>
</listitem>
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 00f4457ddfa35b8917d7babc6666fdc129fb63ae..69c462f04d60888f11bbf5359d0dda821339bb81 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -191,6 +191,7 @@ int ad_gpo_process_cse_recv(struct tevent_req *req);
#define GPO_SUDO "sudo"
#define GPO_SUDO_I "sudo-i"
#define GPO_SYSTEMD_USER "systemd-user"
+#define GPO_COCKPIT "cockpit"
struct gpo_map_option_entry {
enum gpo_map_type gpo_map_type;
@@ -203,7 +204,8 @@ struct gpo_map_option_entry {
const char *gpo_map_interactive_defaults[] =
{GPO_LOGIN, GPO_SU, GPO_SU_L,
GPO_GDM_FINGERPRINT, GPO_GDM_PASSWORD, GPO_GDM_SMARTCARD, GPO_KDM, NULL};
-const char *gpo_map_remote_interactive_defaults[] = {GPO_SSHD, NULL};
+const char *gpo_map_remote_interactive_defaults[] = {GPO_SSHD, GPO_COCKPIT,
+ NULL};
const char *gpo_map_network_defaults[] = {GPO_FTP, GPO_SAMBA, NULL};
const char *gpo_map_batch_defaults[] = {GPO_CROND, NULL};
const char *gpo_map_service_defaults[] = {NULL};
--
2.7.3

View File

@ -1,79 +0,0 @@
From 665fae391bbb6c5173ec0086247f20d95a0c9026 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh@redhat.com>
Date: Fri, 26 Feb 2016 13:21:23 -0500
Subject: [PATCH 085/108] GPO: Add other display managers to interactive logon
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Gone are the days when all systems used GDM or KDM. We need to support
other display managers in the default configuration to avoid issues
when enrolled in AD domains.
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
(cherry picked from commit 293cf52a00c9c67f0ad8f264027f81c020854f66)
(cherry picked from commit 26d4fe97a93b15da60eba98c5c26fde13efd950a)
---
src/man/sssd-ad.5.xml | 20 ++++++++++++++++++++
src/providers/ad/ad_gpo.c | 7 ++++++-
2 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/src/man/sssd-ad.5.xml b/src/man/sssd-ad.5.xml
index b042480dff164e3626f61c520e51bb756bcbfd9c..54a4b56271933bae5d0f86e24b39ddd3fbee7a37 100644
--- a/src/man/sssd-ad.5.xml
+++ b/src/man/sssd-ad.5.xml
@@ -422,6 +422,26 @@ ad_gpo_map_interactive = +my_pam_service, -login
kdm
</para>
</listitem>
+ <listitem>
+ <para>
+ lightdm
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ lxdm
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ sddm
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ xdm
+ </para>
+ </listitem>
</itemizedlist>
</para>
</listitem>
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
index 69c462f04d60888f11bbf5359d0dda821339bb81..a6ab1758d104a315ebf5e985f0ef32b58033c21c 100644
--- a/src/providers/ad/ad_gpo.c
+++ b/src/providers/ad/ad_gpo.c
@@ -184,6 +184,10 @@ int ad_gpo_process_cse_recv(struct tevent_req *req);
#define GPO_GDM_PASSWORD "gdm-password"
#define GPO_GDM_SMARTCARD "gdm-smartcard"
#define GPO_KDM "kdm"
+#define GPO_LIGHTDM "lightdm"
+#define GPO_LXDM "lxdm"
+#define GPO_SDDM "sddm"
+#define GPO_XDM "xdm"
#define GPO_SSHD "sshd"
#define GPO_FTP "ftp"
#define GPO_SAMBA "samba"
@@ -203,7 +207,8 @@ struct gpo_map_option_entry {
const char *gpo_map_interactive_defaults[] =
{GPO_LOGIN, GPO_SU, GPO_SU_L,
- GPO_GDM_FINGERPRINT, GPO_GDM_PASSWORD, GPO_GDM_SMARTCARD, GPO_KDM, NULL};
+ GPO_GDM_FINGERPRINT, GPO_GDM_PASSWORD, GPO_GDM_SMARTCARD, GPO_KDM,
+ GPO_LIGHTDM, GPO_LXDM, GPO_SDDM, GPO_XDM, NULL};
const char *gpo_map_remote_interactive_defaults[] = {GPO_SSHD, GPO_COCKPIT,
NULL};
const char *gpo_map_network_defaults[] = {GPO_FTP, GPO_SAMBA, NULL};
--
2.7.3

View File

@ -1,70 +0,0 @@
From a4b24aeab9f44b5fd937b456acc223a18d045bae Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Mon, 29 Feb 2016 10:41:50 +0100
Subject: [PATCH 086/108] CI: Use yum-deprecated instead of dnf
/usr/bin/yum is provided by the dnf-yum package and call /usr/bin/dnf
on new fedora distributions. We should directly use old style yum
which was renamed to /usr/bin/yum-deprecated and is still part of
the yum package.
Reviewed-by: Nikolai Kondrashov <Nikolai.Kondrashov@redhat.com>
(cherry picked from commit 73585f9af928913200999c5b3b983bb9266ee266)
(cherry picked from commit 8f0a510a8c324aa1fa0f318e340b554cd07baf8b)
---
contrib/ci/README.md | 7 ++++++-
contrib/ci/distro.sh | 14 +++++++++++---
2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/contrib/ci/README.md b/contrib/ci/README.md
index 50b73ec354f92e9909a57a82ec72ba1a8516aa1c..6bd2fd92c1bf2c0abe93a8ecb8432b6a7889e492 100644
--- a/contrib/ci/README.md
+++ b/contrib/ci/README.md
@@ -36,11 +36,16 @@ package and on Debian in `lsb-release`.
The rest of the required packages CI will attempt to install itself, using
the distribution's package manager invoked through sudo.
-A sudo rule can be employed to selectively avoid password prompts on Red Hat
+A sudo rule can be employed to selectively avoid password prompts on RHEL
distros:
<USER> ALL=(ALL:ALL) NOPASSWD: /usr/bin/yum --assumeyes install -- *
+on Fedora distros:
+
+ # We need to use yum-deprecated on Fedora because of BZ1215208.
+ <USER> ALL=(ALL:ALL) NOPASSWD: /usr/bin/yum-deprecated --assumeyes install -- *
+
and Debian-based distros:
<USER> ALL=(ALL:ALL) NOPASSWD: /usr/bin/apt-get --yes install -- *
diff --git a/contrib/ci/distro.sh b/contrib/ci/distro.sh
index da797d02f4b110f9e2c074fc2c97f092ae7200af..374e55696d3f2519151b73ff0fc397c04ff48325 100644
--- a/contrib/ci/distro.sh
+++ b/contrib/ci/distro.sh
@@ -50,11 +50,19 @@ function distro_pkg_install()
{
declare prompt=$'Need root permissions to install packages.\n'
prompt+="Enter sudo password for $USER: "
- if [[ "$DISTRO_BRANCH" == -redhat-* ]]; then
+ if [[ "$DISTRO_BRANCH" == -redhat-fedora-2[2-9]* ]]; then
+ # TODO switch fedora to DNF once
+ # https://bugzilla.redhat.com/show_bug.cgi?id=1215208 is fixed
+ [ $# != 0 ] && sudo -p "$prompt" \
+ yum-deprecated --assumeyes install -- "$@" |&
+ # Pass input to output, fail if a missing package is reported
+ awk 'BEGIN {s=0}
+ /^No package .* available.$/ {s=1}
+ {print}
+ END {exit s}'
+ elif [[ "$DISTRO_BRANCH" == -redhat-* ]]; then
[ $# != 0 ] && sudo -p "$prompt" yum --assumeyes install -- "$@" |&
# Pass input to output, fail if a missing package is reported
- # TODO Remove and switch to DNF once
- # https://bugzilla.redhat.com/show_bug.cgi?id=1215208 is fixed
awk 'BEGIN {s=0}
/^No package .* available.$/ {s=1}
{print}
--
2.7.3

View File

@ -1,120 +0,0 @@
From 4cf4c4a60aa226ed4a9e3da253ec9a598e9481a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 23 Feb 2016 11:02:42 +0100
Subject: [PATCH 087/108] remove user certificate if not found on the server
If the user is not found by cert lookup when the user is already
cached, two things may happen:
1) cert was removed from the user object
2) user was removed
Instead of issuing another cert lookup we will just remove cert
attribute from the cache not touching the expiration timestamp so
the user may be updated later when needed.
Resolves:
https://fedorahosted.org/sssd/ticket/2934
Reviewed-by: Sumit Bose <sbose@redhat.com>
(cherry picked from commit 659232f194f83ec7c450ce89c3fd41e4e74409f2)
(cherry picked from commit 90bd6598f0d8ad9fa8d05419c7e14b64e09e8a54)
---
src/db/sysdb.h | 3 ++-
src/db/sysdb_ops.c | 45 ++++++++++++++++++++++++++++++++++++++++++++
src/providers/ldap/ldap_id.c | 10 ++++++++++
3 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 95a9086766228a6c36c56d3a68a0bb0e493c0cbe..bb8ca08b12d7eee08d36e5e2f4ac47df686b1d69 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -1155,7 +1155,8 @@ errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx,
const char *cert,
struct ldb_result **res);
-
+errno_t sysdb_remove_cert(struct sss_domain_info *domain,
+ const char *cert);
/* === Functions related to GPOs === */
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index ab0d59ca6db620dfbf7e74a93745df242b6fc3a3..843251b3e87a697a0f9e8cb2bb2d83be0150a474 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -3764,6 +3764,51 @@ errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx,
return sysdb_search_object_by_cert(mem_ctx, domain, cert, user_attrs, res);
}
+errno_t sysdb_remove_cert(struct sss_domain_info *domain,
+ const char *cert)
+{
+ struct ldb_message_element el = { 0, SYSDB_USER_CERT, 0, NULL };
+ struct sysdb_attrs del_attrs = { 1, &el };
+ const char *attrs[] = {SYSDB_NAME, NULL};
+ struct ldb_result *res = NULL;
+ unsigned int i;
+ errno_t ret;
+
+ ret = sysdb_search_object_by_cert(NULL, domain, cert, attrs, &res);
+ if (ret == ENOENT || res == NULL) {
+ ret = EOK;
+ goto done;
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to lookup object by cert "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ /* Certificate may be found on more objects, remove it from all.
+ * If object contains more then one certificate, we still remove the
+ * whole attribute since it will be downloaded again. */
+ for (i = 0; i < res->count; i++) {
+ ret = sysdb_set_entry_attr(domain->sysdb, res->msgs[0]->dn,
+ &del_attrs, SYSDB_MOD_DEL);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to remove certificate "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ ret = sysdb_mark_entry_as_expired_ldb_dn(domain, res->msgs[0]->dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to expire object "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ continue;
+ }
+ }
+
+done:
+ talloc_free(res);
+ return ret;
+}
+
errno_t sysdb_get_sids_of_members(TALLOC_CTX *mem_ctx,
struct sss_domain_info *dom,
const char *group_name,
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index 905bbd94d36e52e212d118e728f5fe46fa5bc64a..7a986f43775a3d0219c91386d667ba910180b425 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -530,6 +530,16 @@ static void users_get_done(struct tevent_req *subreq)
*/
break;
+ case BE_FILTER_CERT:
+ ret = sysdb_remove_cert(state->domain, state->name);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to remove user certificate"
+ "[%d]: %s\n", ret, sss_strerror(ret));
+ tevent_req_error(req, ret);
+ return;
+ }
+ break;
+
default:
tevent_req_error(req, EINVAL);
return;
--
2.7.3

View File

@ -1,392 +0,0 @@
From 3968a8ddb1b0e55db8217031f92feb4d2ee25c4d Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 22 Jan 2016 18:14:45 +0100
Subject: [PATCH 088/108] sdap: improve filtering of multiple results in GC
lookups
The Global Catalog of AD contains some information about all users and
groups in an AD forest. Users from different domain in the forest can
have the same name. The most obvious example is the Administrator user
which is present in all domains. Although SSSD uses a domain specific
search base for looking up users in the GC the search might still return
multiple results if there is a user with the same name in one of the
child (or grand-child ...) domains because of the hierarchic nature of
the LDAP tree. Limiting the search depth would not help because users
can be created in deeply nested OUs.
Currently SSSD expects in this case that the user object is store in
CN=Users or below. This works for all default users like Administrator
but in general users can be created anywhere in the directory tree. If a
user is created outside of CN=Users and there is a user with the same
name in a child domain the initgroups command to look up the
group-memberships of the user fails because it is not clear which of the
two results should be used (initgroups for the child domain user works
fine).
This patch adds an additional scheme to select the right result based on
the domain component attribute name 'dc'. This attribute indicates an
additional component in the domain name and hence a child domain. So as
long as the result contains a dc component following out search base it
cannot be the object we are looking for. This scheme includes the old
CN=Users based one but since it is more expensive I kept the old scheme
which so far worked all the time and only use the new one if the old one
fails.
Resolves https://fedorahosted.org/sssd/ticket/2961
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 5ff7a765434ed0b4d37564ade26d7761d06f81c3)
(cherry picked from commit 52ea2caa4d21a980902cd0f2fd77ceba25062a8c)
---
src/db/sysdb.h | 6 ++
src/db/sysdb_subdomains.c | 153 +++++++++++++++++++++++++++++
src/providers/ldap/sdap_async_initgroups.c | 48 ++-------
src/tests/cmocka/test_sysdb_subdomains.c | 73 ++++++++++++++
4 files changed, 238 insertions(+), 42 deletions(-)
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index bb8ca08b12d7eee08d36e5e2f4ac47df686b1d69..4b2feffd058f314d4b0d7270d5a5b242d6555e39 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -1228,4 +1228,10 @@ errno_t sysdb_handle_original_uuid(const char *orig_name,
const char *src_name,
struct sysdb_attrs *dest_attrs,
const char *dest_name);
+
+errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
+ const char *domain_component_name,
+ struct sysdb_attrs **usr_attrs,
+ size_t count,
+ struct sysdb_attrs **exp_usr);
#endif /* __SYS_DB_H__ */
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index b2bf1a0742171b7beccb44fa915c8adba51fefa3..456e6621b3434a9dbf2e611ad880facbc171c174 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -1049,3 +1049,156 @@ done:
talloc_free(tmp_ctx);
return ret;
}
+
+errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
+ const char *domain_component_name,
+ struct sysdb_attrs **usr_attrs,
+ size_t count,
+ struct sysdb_attrs **exp_usr)
+{
+ char *dom_basedn;
+ size_t dom_basedn_len;
+ char *expected_basedn;
+ size_t expected_basedn_len;
+ size_t dn_len;
+ const char *orig_dn;
+ size_t c = 0;
+ int ret;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_context *ldb_ctx;
+ struct ldb_dn *ldb_dom_basedn;
+ int dom_basedn_comp_num;
+ struct ldb_dn *ldb_dn;
+ int dn_comp_num;
+ const char *component_name;
+ struct sysdb_attrs *result = NULL;
+ const char *result_dn_str = NULL;
+
+ if (dom == NULL || domain_component_name == NULL || usr_attrs == NULL
+ || count == 0) {
+ return EINVAL;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+ return ENOMEM;
+ }
+
+ ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
+ goto done;
+ }
+ expected_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn);
+ if (expected_basedn == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
+ if (ldb_ctx == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn);
+ if (ldb_dom_basedn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ dom_basedn_comp_num = ldb_dn_get_comp_num(ldb_dom_basedn);
+ dom_basedn_comp_num++;
+
+ DEBUG(SSSDBG_TRACE_ALL, "Expected BaseDN is [%s].\n", expected_basedn);
+ expected_basedn_len = strlen(expected_basedn);
+ dom_basedn_len = strlen(dom_basedn);
+
+ for (c = 0; c < count; c++) {
+ ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+ goto done;
+ }
+ dn_len = strlen(orig_dn);
+
+ if (dn_len > expected_basedn_len
+ && strcasecmp(orig_dn + (dn_len - expected_basedn_len),
+ expected_basedn) == 0) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Found matching dn [%s].\n", orig_dn);
+ if (result != NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Found 2 matching DN [%s] and [%s], expecting only 1.\n",
+ result_dn_str, orig_dn);
+ ret = EINVAL;
+ goto done;
+ }
+ result = usr_attrs[c];
+ result_dn_str = orig_dn;
+ }
+ }
+
+ if (result == NULL) {
+ for (c = 0; c < count; c++) {
+ ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+ goto done;
+ }
+ dn_len = strlen(orig_dn);
+
+ if (dn_len > dom_basedn_len
+ && strcasecmp(orig_dn + (dn_len - dom_basedn_len),
+ dom_basedn) == 0) {
+ ldb_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn);
+ if (ldb_dn == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ dn_comp_num = ldb_dn_get_comp_num(ldb_dn);
+ if (dn_comp_num > dom_basedn_comp_num) {
+ component_name = ldb_dn_get_component_name(ldb_dn,
+ (dn_comp_num - dom_basedn_comp_num));
+ DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n",
+ component_name,
+ domain_component_name);
+ if (component_name != NULL
+ && strcasecmp(component_name,
+ domain_component_name) != 0) {
+ DEBUG(SSSDBG_TRACE_ALL,
+ "Found matching dn [%s].\n", orig_dn);
+ if (result != NULL) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Found 2 matching DN [%s] and [%s], "
+ "expecting only 1.\n", result_dn_str, orig_dn);
+ ret = EINVAL;
+ goto done;
+ }
+ result = usr_attrs[c];
+ result_dn_str = orig_dn;
+ }
+ }
+ }
+ }
+ }
+
+ if (result == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n");
+ ret = ENOENT;
+ goto done;
+ }
+
+ *exp_usr = result;
+
+ ret = EOK;
+done:
+ talloc_free(tmp_ctx);
+
+ return ret;
+}
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 1e5f5ab49896b234bec0c7a2c1429f30d90ae32a..059b18354362a76376da9321118b8fdb12282b9a 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2832,10 +2832,6 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
const char *orig_dn;
const char *cname;
bool in_transaction = false;
- char *expected_basedn;
- size_t expected_basedn_len;
- size_t dn_len;
- size_t c = 0;
DEBUG(SSSDBG_TRACE_ALL, "Receiving info for the user\n");
@@ -2872,54 +2868,22 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
tevent_req_error(req, ret);
return;
}
+ } else if (count == 1) {
+ state->orig_user = usr_attrs[0];
} else if (count != 1) {
DEBUG(SSSDBG_OP_FAILURE,
"Expected one user entry and got %zu\n", count);
- ret = domain_to_basedn(state, state->dom->name, &expected_basedn);
+ ret = sysdb_try_to_find_expected_dn(state->dom, "dc", usr_attrs, count,
+ &state->orig_user);
if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
- tevent_req_error(req, ret);
- return;
- }
- expected_basedn = talloc_asprintf(state, "%s%s",
- "cn=users,", expected_basedn);
- if (expected_basedn == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "talloc_append failed.\n");
- tevent_req_error(req, ENOMEM);
- return;
- }
-
- DEBUG(SSSDBG_TRACE_ALL, "Expected BaseDN is [%s].\n", expected_basedn);
- expected_basedn_len = strlen(expected_basedn);
-
- for (c = 0; c < count; c++) {
- ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
- if (ret != EOK) {
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
- tevent_req_error(req, ret);
- return;
- }
- dn_len = strlen(orig_dn);
-
- if (dn_len > expected_basedn_len
- && strcasecmp(orig_dn + (dn_len - expected_basedn_len),
- expected_basedn) == 0) {
- DEBUG(SSSDBG_TRACE_ALL,
- "Found matching dn [%s].\n", orig_dn);
- break;
- }
- }
-
- if (c == count) {
- DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n");
+ DEBUG(SSSDBG_OP_FAILURE,
+ "try_to_find_expected_dn failed. No matching DN found.\n");
tevent_req_error(req, EINVAL);
return;
}
}
- state->orig_user = usr_attrs[c];
-
ret = sysdb_transaction_start(state->sysdb);
if (ret) {
DEBUG(SSSDBG_CRIT_FAILURE, "Failed to start transaction\n");
diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c
index 701bfb726ff7e950d4439b3dc1a3bee437c9e7ed..f55c2918015900351483e3471bf946ea60872dae 100644
--- a/src/tests/cmocka/test_sysdb_subdomains.c
+++ b/src/tests/cmocka/test_sysdb_subdomains.c
@@ -509,6 +509,76 @@ static void test_sysdb_link_ad_multidom(void **state)
}
+static void test_try_to_find_expected_dn(void **state)
+{
+ int ret;
+ struct sysdb_attrs *result;
+ struct sysdb_attrs *usr_attrs[10] = { NULL };
+ struct sss_domain_info *dom;
+ struct subdom_test_ctx *test_ctx =
+ talloc_get_type(*state, struct subdom_test_ctx);
+
+ dom = find_domain_by_name(test_ctx->tctx->dom,
+ "child2.test_sysdb_subdomains_2", true);
+ assert_non_null(dom);
+
+ usr_attrs[0] = sysdb_new_attrs(test_ctx);
+ assert_non_null(usr_attrs[0]);
+
+ ret = sysdb_attrs_add_string(usr_attrs[0], SYSDB_ORIG_DN,
+ "uid=user,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
+ assert_int_equal(ret, EOK);
+
+ ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, 0, NULL);
+ assert_int_equal(ret, EINVAL);
+
+ ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 1, &result);
+ assert_int_equal(ret, ENOENT);
+
+ ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 1, &result);
+ assert_int_equal(ret, EOK);
+ assert_ptr_equal(result, usr_attrs[0]);
+
+ usr_attrs[1] = sysdb_new_attrs(test_ctx);
+ assert_non_null(usr_attrs[1]);
+
+ ret = sysdb_attrs_add_string(usr_attrs[1], SYSDB_ORIG_DN,
+ "uid=user1,cn=abc,dc=child2,dc=test_sysdb_subdomains_2");
+ assert_int_equal(ret, EOK);
+
+ usr_attrs[2] = sysdb_new_attrs(test_ctx);
+ assert_non_null(usr_attrs[2]);
+
+ ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN,
+ "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
+ assert_int_equal(ret, EOK);
+
+ ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result);
+ assert_int_equal(ret, EOK);
+ assert_ptr_equal(result, usr_attrs[1]);
+
+ ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 3, &result);
+ assert_int_equal(ret, EINVAL);
+
+ /* Make sure cn=users match is preferred */
+ talloc_free(usr_attrs[2]);
+ usr_attrs[2] = sysdb_new_attrs(test_ctx);
+ assert_non_null(usr_attrs[2]);
+
+ ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN,
+ "uid=user2,cn=abc,cn=users,dc=child2,dc=test_sysdb_subdomains_2");
+ assert_int_equal(ret, EOK);
+
+ ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result);
+ assert_int_equal(ret, EOK);
+ assert_ptr_equal(result, usr_attrs[2]);
+
+
+ talloc_free(usr_attrs[0]);
+ talloc_free(usr_attrs[1]);
+ talloc_free(usr_attrs[2]);
+}
+
int main(int argc, const char *argv[])
{
int rv;
@@ -542,6 +612,9 @@ int main(int argc, const char *argv[])
cmocka_unit_test_setup_teardown(test_sysdb_link_ad_multidom,
test_sysdb_subdom_setup,
test_sysdb_subdom_teardown),
+ cmocka_unit_test_setup_teardown(test_try_to_find_expected_dn,
+ test_sysdb_subdom_setup,
+ test_sysdb_subdom_teardown),
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */
--
2.7.3

View File

@ -1,30 +0,0 @@
From ba9819a93951e0a38874c6d06abcba700b07d41d Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Sun, 11 Oct 2015 18:08:46 +0200
Subject: [PATCH 089/108] FO: Don't free rc-allocated structure
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 63af9215ea9114062fd87003161e6b5982bf9b1f)
(cherry picked from commit 5d485ce42a4d56581d44c7224e78083a4ff1e81b)
---
src/providers/fail_over.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
index b51a6c99ce031a1566f5d021fcf41843891a2d1c..3e6f1c2a24aaf713288146cc25d9cc462f243160 100644
--- a/src/providers/fail_over.c
+++ b/src/providers/fail_over.c
@@ -507,7 +507,6 @@ create_server_common(TALLOC_CTX *mem_ctx, struct fo_ctx *ctx, const char *name)
common->name = talloc_strdup(common, name);
if (common->name == NULL) {
- talloc_free(common);
return NULL;
}
--
2.7.3

View File

@ -1,163 +0,0 @@
From 386984d350c841d9fcb7d002015a4bf174aaa51e Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Sun, 11 Oct 2015 15:31:44 +0200
Subject: [PATCH 090/108] tests: Reduce failover code duplication
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 4a4af8e1b6a9bab7c7a34d86055a400376e3829e)
(cherry picked from commit 383bdbe8d40cba2d0848b2256716358c7f8e8f2d)
---
src/tests/cmocka/test_fo_srv.c | 88 +++++++++++++++++-------------------------
1 file changed, 35 insertions(+), 53 deletions(-)
diff --git a/src/tests/cmocka/test_fo_srv.c b/src/tests/cmocka/test_fo_srv.c
index e892bab0a261779363ea78a10038b15acefc49b7..109f664c84238cf9c1055a1cbc1a8c8870f2dc39 100644
--- a/src/tests/cmocka/test_fo_srv.c
+++ b/src/tests/cmocka/test_fo_srv.c
@@ -319,34 +319,50 @@ static void test_fo_srv_done3(struct tevent_req *req);
static void test_fo_srv_done4(struct tevent_req *req);
static void test_fo_srv_done5(struct tevent_req *req);
-static void test_fo_srv_mock_dns(struct test_fo_ctx *test_ctx)
+
+struct ares_srv_reply *
+mock_ares_reply(TALLOC_CTX *mem_ctx, const char *hostname,
+ int weight, int priority, int port)
+{
+ struct ares_srv_reply *s;
+
+ s = talloc_zero(mem_ctx, struct ares_srv_reply);
+ if (s == NULL) {
+ return NULL;
+ }
+
+ s->host = talloc_strdup(s, hostname);
+ if (s->host == NULL) {
+ talloc_free(s);
+ return NULL;
+ }
+
+ s->weight = weight;
+ s->priority = priority;
+ s->port = port;
+
+ return s;
+}
+
+static void test_fo_srv_mock_dns(struct test_fo_ctx *test_ctx,
+ int ttl)
{
struct ares_srv_reply *s1;
struct ares_srv_reply *s2;
char *dns_domain;
- s1 = talloc_zero(test_ctx, struct ares_srv_reply);
+ s1 = mock_ares_reply(test_ctx, "ldap1.sssd.com", 100, 1, 389);
assert_non_null(s1);
- s1->host = talloc_strdup(s1, "ldap1.sssd.com");
- assert_non_null(s1->host);
- s1->weight = 100;
- s1->priority = 1;
- s1->port = 389;
- s2 = talloc_zero(test_ctx, struct ares_srv_reply);
+ s2 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 2, 389);
assert_non_null(s2);
- s2->host = talloc_strdup(s2, "ldap2.sssd.com");
- assert_non_null(s2->host);
- s2->weight = 100;
- s2->priority = 2;
- s2->port = 389;
s1->next = s2;
dns_domain = talloc_strdup(test_ctx, "sssd.com");
assert_non_null(dns_domain);
- mock_srv_results(s1, TEST_SRV_TTL, dns_domain);
+ mock_srv_results(s1, ttl, dns_domain);
}
static void test_fo_srv(void **state)
@@ -355,7 +371,7 @@ static void test_fo_srv(void **state)
struct test_fo_ctx *test_ctx =
talloc_get_type(*state, struct test_fo_ctx);
- test_fo_srv_mock_dns(test_ctx);
+ test_fo_srv_mock_dns(test_ctx, TEST_SRV_TTL);
ret = fo_add_srv_server(test_ctx->fo_svc, "_ldap", "sssd.com",
"sssd.local", "tcp", test_ctx);
@@ -466,7 +482,7 @@ static void test_fo_srv_done4(struct tevent_req *req)
/* reset the server status and try again.. */
fo_reset_servers(test_ctx->fo_svc);
if (test_ctx->srv_ctx) {
- test_fo_srv_mock_dns(test_ctx);
+ test_fo_srv_mock_dns(test_ctx, TEST_SRV_TTL);
}
req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
@@ -516,32 +532,8 @@ static void test_fo_srv_ttl_change_step(struct test_fo_ctx *test_ctx)
{
errno_t ret;
struct tevent_req *req;
- struct ares_srv_reply *s1;
- struct ares_srv_reply *s2;
- char *dns_domain;
- s1 = talloc_zero(test_ctx, struct ares_srv_reply);
- assert_non_null(s1);
- s1->host = talloc_strdup(s1, "ldap1.sssd.com");
- assert_non_null(s1->host);
- s1->weight = 100;
- s1->priority = 1;
- s1->port = 389;
-
- s2 = talloc_zero(test_ctx, struct ares_srv_reply);
- assert_non_null(s2);
- s2->host = talloc_strdup(s2, "ldap2.sssd.com");
- assert_non_null(s2->host);
- s2->weight = 100;
- s2->priority = 2;
- s2->port = 389;
-
- s1->next = s2;
-
- dns_domain = talloc_strdup(test_ctx, "sssd.com");
- assert_non_null(dns_domain);
-
- mock_srv_results(s1, test_ctx->ttl, dns_domain);
+ test_fo_srv_mock_dns(test_ctx, test_ctx->ttl);
ret = fo_add_srv_server(test_ctx->fo_svc, "_ldap", "sssd.com",
"sssd.local", "tcp", test_ctx);
@@ -582,21 +574,11 @@ static void test_fo_srv_before(struct tevent_req *req)
fo_set_server_status(srv, SERVER_WORKING);
/* Simulate changing the DNS environment. Change the host names */
- s1 = talloc_zero(test_ctx, struct ares_srv_reply);
+ s1 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 2, 389);
assert_non_null(s1);
- s1->host = talloc_strdup(s1, "ldap2.sssd.com");
- assert_non_null(s1->host);
- s1->weight = 100;
- s1->priority = 2;
- s1->port = 389;
- s2 = talloc_zero(test_ctx, struct ares_srv_reply);
+ s2 = mock_ares_reply(test_ctx, "ldap3.sssd.com", 100, 1, 389);
assert_non_null(s2);
- s2->host = talloc_strdup(s2, "ldap3.sssd.com");
- assert_non_null(s2->host);
- s2->weight = 100;
- s2->priority = 1;
- s2->port = 389;
s1->next = s2;
--
2.7.3

View File

@ -1,489 +0,0 @@
From 54d7922d287368fe419cafaa754aaf43b3ff1c93 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Sun, 11 Oct 2015 15:34:44 +0200
Subject: [PATCH 091/108] FO: Use refcount to keep track of servers returned to
callers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Resolves:
https://fedorahosted.org/sssd/ticket/2829
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 10c07e188323a2f9824b5e34379f3b1a9b37759e)
(cherry picked from commit c532290fb1a85a63c3bc9ef95ba7d6248f0e94c1)
---
src/providers/data_provider_fo.c | 7 ++-
src/providers/dp_backend.h | 4 +-
src/providers/fail_over.c | 95 ++++++++++++++++++++++++------
src/providers/fail_over.h | 10 +++-
src/providers/krb5/krb5_auth.c | 4 +-
src/providers/ldap/ldap_auth.c | 2 +-
src/providers/ldap/sdap_async_connection.c | 4 +-
src/tests/cmocka/test_fo_srv.c | 26 ++++----
src/tests/fail_over-tests.c | 2 +-
9 files changed, 115 insertions(+), 39 deletions(-)
diff --git a/src/providers/data_provider_fo.c b/src/providers/data_provider_fo.c
index d1d8c4c5c94811ce73b550dc99166d3c913b95aa..39f57255af220b608d333da7c0bd1697788ea8f6 100644
--- a/src/providers/data_provider_fo.c
+++ b/src/providers/data_provider_fo.c
@@ -606,7 +606,7 @@ errno_t be_resolve_server_process(struct tevent_req *subreq,
time_t srv_status_change;
struct be_svc_callback *callback;
- ret = fo_resolve_service_recv(subreq, &state->srv);
+ ret = fo_resolve_service_recv(subreq, state, &state->srv);
switch (ret) {
case EOK:
if (!state->srv) {
@@ -699,7 +699,9 @@ errno_t be_resolve_server_process(struct tevent_req *subreq,
return EOK;
}
-int be_resolve_server_recv(struct tevent_req *req, struct fo_server **srv)
+int be_resolve_server_recv(struct tevent_req *req,
+ TALLOC_CTX *ref_ctx,
+ struct fo_server **srv)
{
struct be_resolve_server_state *state = tevent_req_data(req,
struct be_resolve_server_state);
@@ -707,6 +709,7 @@ int be_resolve_server_recv(struct tevent_req *req, struct fo_server **srv)
TEVENT_REQ_RETURN_ON_ERROR(req);
if (srv) {
+ fo_ref_server(ref_ctx, state->srv);
*srv = state->srv;
}
diff --git a/src/providers/dp_backend.h b/src/providers/dp_backend.h
index ffeeca4a6bad976ae8922bc4964b839242290259..bc5f716ffb8b85244604e3830141d390b7979a7c 100644
--- a/src/providers/dp_backend.h
+++ b/src/providers/dp_backend.h
@@ -258,7 +258,9 @@ struct tevent_req *be_resolve_server_send(TALLOC_CTX *memctx,
struct be_ctx *ctx,
const char *service_name,
bool first_try);
-int be_resolve_server_recv(struct tevent_req *req, struct fo_server **srv);
+int be_resolve_server_recv(struct tevent_req *req,
+ TALLOC_CTX *ref_ctx,
+ struct fo_server **srv);
#define be_fo_set_port_status(ctx, service_name, server, status) \
_be_fo_set_port_status(ctx, service_name, server, status, \
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
index 3e6f1c2a24aaf713288146cc25d9cc462f243160..65d4fb690d270fa04a0e22f7db37bd8521ad3ba1 100644
--- a/src/providers/fail_over.c
+++ b/src/providers/fail_over.c
@@ -79,6 +79,8 @@ struct fo_service {
};
struct fo_server {
+ REFCOUNT_COMMON;
+
struct fo_server *prev;
struct fo_server *next;
@@ -90,6 +92,8 @@ struct fo_server {
struct fo_service *service;
struct timeval last_status_change;
struct server_common *common;
+
+ TALLOC_CTX *fo_internal_owner;
};
struct server_common {
@@ -217,6 +221,15 @@ int fo_is_srv_lookup(struct fo_server *s)
return s && s->srv_data;
}
+static void fo_server_free(struct fo_server *server)
+{
+ if (server == NULL) {
+ return;
+ }
+
+ talloc_free(server->fo_internal_owner);
+}
+
static struct fo_server *
collapse_srv_lookup(struct fo_server **_server)
{
@@ -231,12 +244,12 @@ collapse_srv_lookup(struct fo_server **_server)
while (server->prev && server->prev->srv_data == meta->srv_data) {
tmp = server->prev;
DLIST_REMOVE(server->service->server_list, tmp);
- talloc_zfree(tmp);
+ fo_server_free(tmp);
}
while (server->next && server->next->srv_data == meta->srv_data) {
tmp = server->next;
DLIST_REMOVE(server->service->server_list, tmp);
- talloc_zfree(tmp);
+ fo_server_free(tmp);
}
if (server == server->service->active_server) {
@@ -249,7 +262,7 @@ collapse_srv_lookup(struct fo_server **_server)
/* add back the meta server to denote SRV lookup */
DLIST_ADD_AFTER(server->service->server_list, meta, server);
DLIST_REMOVE(server->service->server_list, server);
- talloc_zfree(server);
+ fo_server_free(server);
}
meta->srv_data->srv_lookup_status = SRV_NEUTRAL;
@@ -502,8 +515,9 @@ create_server_common(TALLOC_CTX *mem_ctx, struct fo_ctx *ctx, const char *name)
struct server_common *common;
common = rc_alloc(mem_ctx, struct server_common);
- if (common == NULL)
+ if (common == NULL) {
return NULL;
+ }
common->name = talloc_strdup(common, name);
if (common->name == NULL) {
@@ -524,6 +538,41 @@ create_server_common(TALLOC_CTX *mem_ctx, struct fo_ctx *ctx, const char *name)
return common;
}
+static struct fo_server *
+fo_server_alloc(struct fo_service *service, int port,
+ void *user_data, bool primary)
+{
+ static struct fo_server *server;
+ TALLOC_CTX *server_owner;
+
+ server_owner = talloc_new(service);
+ if (server_owner == NULL) {
+ return NULL;
+ }
+
+ server = rc_alloc(server_owner, struct fo_server);
+ if (server == NULL) {
+ return NULL;
+ }
+
+ server->fo_internal_owner = server_owner;
+
+ server->common = NULL;
+ server->next = NULL;
+ server->prev = NULL;
+ server->srv_data = NULL;
+ server->last_status_change.tv_sec = 0;
+ server->last_status_change.tv_usec = 0;
+
+ server->port = port;
+ server->user_data = user_data;
+ server->service = service;
+ server->port_status = DEFAULT_PORT_STATUS;
+ server->primary = primary;
+
+ return server;
+}
+
int
fo_add_srv_server(struct fo_service *service, const char *srv,
const char *discovery_domain, const char *sssd_domain,
@@ -557,14 +606,11 @@ fo_add_srv_server(struct fo_service *service, const char *srv,
}
}
- server = talloc_zero(service, struct fo_server);
- if (server == NULL)
+ /* SRV servers are always primary */
+ server = fo_server_alloc(service, 0, user_data, true);
+ if (server == NULL) {
return ENOMEM;
-
- server->user_data = user_data;
- server->service = service;
- server->port_status = DEFAULT_PORT_STATUS;
- server->primary = true; /* SRV servers are never back up */
+ }
/* add the SRV-specific data */
server->srv_data = talloc_zero(service, struct srv_data);
@@ -608,7 +654,7 @@ create_fo_server(struct fo_service *service, const char *name,
struct fo_server *server;
int ret;
- server = talloc_zero(service, struct fo_server);
+ server = fo_server_alloc(service, port, user_data, primary);
if (server == NULL)
return NULL;
@@ -623,11 +669,11 @@ create_fo_server(struct fo_service *service, const char *name,
if (ret == ENOENT) {
server->common = create_server_common(server, service->ctx, name);
if (server->common == NULL) {
- talloc_free(server);
+ fo_server_free(server);
return NULL;
}
} else if (ret != EOK) {
- talloc_free(server);
+ fo_server_free(server);
return NULL;
}
}
@@ -760,7 +806,6 @@ static errno_t fo_add_server_list(struct fo_service *service,
server = create_fo_server(service, servers[i].host, servers[i].port,
user_data, primary);
if (server == NULL) {
- talloc_free(srv_list);
return ENOMEM;
}
@@ -769,7 +814,7 @@ static errno_t fo_add_server_list(struct fo_service *service,
ret = fo_add_server_to_list(&srv_list, service->server_list,
server, service->name);
if (ret != EOK) {
- talloc_zfree(server);
+ fo_server_free(server);
continue;
}
@@ -803,12 +848,20 @@ fo_add_server(struct fo_service *service, const char *name, int port,
ret = fo_add_server_to_list(&service->server_list, service->server_list,
server, service->name);
if (ret != EOK) {
- talloc_free(server);
+ fo_server_free(server);
}
return ret;
}
+void fo_ref_server(TALLOC_CTX *ref_ctx,
+ struct fo_server *server)
+{
+ if (server) {
+ rc_reference(ref_ctx, struct fo_server, server);
+ }
+}
+
static int
get_first_server_entity(struct fo_service *service, struct fo_server **_server)
{
@@ -1150,7 +1203,9 @@ fo_resolve_service_done(struct tevent_req *subreq)
}
int
-fo_resolve_service_recv(struct tevent_req *req, struct fo_server **server)
+fo_resolve_service_recv(struct tevent_req *req,
+ TALLOC_CTX *ref_ctx,
+ struct fo_server **server)
{
struct resolve_service_state *state;
@@ -1158,8 +1213,10 @@ fo_resolve_service_recv(struct tevent_req *req, struct fo_server **server)
/* always return the server if asked for, otherwise the caller
* cannot mark it as faulty in case we return an error */
- if (server)
+ if (server != NULL) {
+ fo_ref_server(ref_ctx, state->server);
*server = state->server;
+ }
TEVENT_REQ_RETURN_ON_ERROR(req);
diff --git a/src/providers/fail_over.h b/src/providers/fail_over.h
index b8272a0a16015ff6b5d287b775c33a77e23eba67..f24b5715f13931965400c20562a1578aaf756908 100644
--- a/src/providers/fail_over.h
+++ b/src/providers/fail_over.h
@@ -128,7 +128,6 @@ int fo_add_server(struct fo_service *service,
const char *name, int port,
void *user_data, bool primary);
-
int fo_add_srv_server(struct fo_service *service,
const char *srv,
const char *discovery_domain,
@@ -148,8 +147,17 @@ struct tevent_req *fo_resolve_service_send(TALLOC_CTX *mem_ctx,
struct fo_service *service);
int fo_resolve_service_recv(struct tevent_req *req,
+ TALLOC_CTX *ref_ctx,
struct fo_server **server);
+
+/* To be used by async consumers of fo_resolve_service. If a server should be returned
+ * to an outer request, it should be referenced by a memory from that outer request,
+ * because the failover's server list might change with a subsequent call (see upstream
+ * bug #2829)
+ */
+void fo_ref_server(TALLOC_CTX *ref_ctx, struct fo_server *server);
+
/*
* Set feedback about 'server'. Caller should use this to indicate a problem
* with the server itself, not only with the service on that server. This
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
index e3e9601b356efd72e50ab86e8b7cdd048e4e70d4..7b7a16a612332639aa474a7ebea6b966df18f08f 100644
--- a/src/providers/krb5/krb5_auth.c
+++ b/src/providers/krb5/krb5_auth.c
@@ -695,9 +695,9 @@ static void krb5_auth_resolve_done(struct tevent_req *subreq)
int ret;
if (!state->search_kpasswd) {
- ret = be_resolve_server_recv(subreq, &kr->srv);
+ ret = be_resolve_server_recv(subreq, kr, &kr->srv);
} else {
- ret = be_resolve_server_recv(subreq, &kr->kpasswd_srv);
+ ret = be_resolve_server_recv(subreq, kr, &kr->kpasswd_srv);
}
talloc_zfree(subreq);
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index 2fab92e5d22a4dae870c5e9dde7ef162fc36cbe2..8d6a37b2ceb3347cb8092858889d07e5615e5c77 100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -695,7 +695,7 @@ static void auth_resolve_done(struct tevent_req *subreq)
int ret;
bool use_tls;
- ret = be_resolve_server_recv(subreq, &state->srv);
+ ret = be_resolve_server_recv(subreq, state, &state->srv);
talloc_zfree(subreq);
if (ret) {
/* all servers have been tried and none
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 40256de99006815c97ee9390dfd2e997cf6fc072..f9074afb0c1340c7c2a50d4df0021eee4ae0d076 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -1160,7 +1160,7 @@ static void sdap_kinit_kdc_resolved(struct tevent_req *subreq)
struct tevent_req *tgtreq;
int ret;
- ret = be_resolve_server_recv(subreq, &state->kdc_srv);
+ ret = be_resolve_server_recv(subreq, state, &state->kdc_srv);
talloc_zfree(subreq);
if (ret != EOK) {
/* all servers have been tried and none
@@ -1520,7 +1520,7 @@ static void sdap_cli_resolve_done(struct tevent_req *subreq)
struct sdap_cli_connect_state);
int ret;
- ret = be_resolve_server_recv(subreq, &state->srv);
+ ret = be_resolve_server_recv(subreq, state, &state->srv);
talloc_zfree(subreq);
if (ret) {
state->srv = NULL;
diff --git a/src/tests/cmocka/test_fo_srv.c b/src/tests/cmocka/test_fo_srv.c
index 109f664c84238cf9c1055a1cbc1a8c8870f2dc39..67f86fb17753bf90b88d007a6a1b309df830c152 100644
--- a/src/tests/cmocka/test_fo_srv.c
+++ b/src/tests/cmocka/test_fo_srv.c
@@ -201,6 +201,8 @@ struct test_fo_ctx {
struct fo_service *fo_svc;
struct sss_test_ctx *ctx;
int ttl;
+
+ struct fo_server *srv;
};
int test_fo_srv_data_cmp(void *ud1, void *ud2)
@@ -401,7 +403,7 @@ static void test_fo_srv_done1(struct tevent_req *req)
struct fo_server *srv;
errno_t ret;
- ret = fo_resolve_service_recv(req, &srv);
+ ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
@@ -426,7 +428,7 @@ static void test_fo_srv_done2(struct tevent_req *req)
struct fo_server *srv;
errno_t ret;
- ret = fo_resolve_service_recv(req, &srv);
+ ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
@@ -450,7 +452,7 @@ static void test_fo_srv_done3(struct tevent_req *req)
struct fo_server *srv;
errno_t ret;
- ret = fo_resolve_service_recv(req, &srv);
+ ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
@@ -474,7 +476,7 @@ static void test_fo_srv_done4(struct tevent_req *req)
struct fo_server *srv;
errno_t ret;
- ret = fo_resolve_service_recv(req, &srv);
+ ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
/* No servers are left..*/
assert_int_equal(ret, ENOENT);
@@ -499,7 +501,7 @@ static void test_fo_srv_done5(struct tevent_req *req)
struct fo_server *srv;
errno_t ret;
- ret = fo_resolve_service_recv(req, &srv);
+ ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
@@ -558,20 +560,19 @@ static void test_fo_srv_before(struct tevent_req *req)
{
struct test_fo_ctx *test_ctx = \
tevent_req_callback_data(req, struct test_fo_ctx);
- struct fo_server *srv;
struct ares_srv_reply *s1;
struct ares_srv_reply *s2;
char *dns_domain;
errno_t ret;
- ret = fo_resolve_service_recv(req, &srv);
+ ret = fo_resolve_service_recv(req, test_ctx, &test_ctx->srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
DEBUG(SSSDBG_TRACE_FUNC, "Before TTL change\n");
- check_server(test_ctx, srv, 389, "ldap1.sssd.com");
- fo_set_server_status(srv, SERVER_WORKING);
+ check_server(test_ctx, test_ctx->srv, 389, "ldap1.sssd.com");
+ fo_set_server_status(test_ctx->srv, SERVER_WORKING);
/* Simulate changing the DNS environment. Change the host names */
s1 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 2, 389);
@@ -602,10 +603,15 @@ static void test_fo_srv_after(struct tevent_req *req)
struct fo_server *srv;
errno_t ret;
- ret = fo_resolve_service_recv(req, &srv);
+ ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
assert_int_equal(ret, ERR_OK);
+ /* Try accessing server from a previous iteration. The
+ * server should be collapsed, but at least we shouldn't crash
+ */
+ fo_set_server_status(test_ctx->srv, SERVER_WORKING);
+
/* Must be a different server now */
check_server(test_ctx, srv, 389, "ldap3.sssd.com");
diff --git a/src/tests/fail_over-tests.c b/src/tests/fail_over-tests.c
index c9bac68711cfcf624064b5881f5226d4f8449e39..020f9d474b6bc8cee4fe80098f9631c4e343cec6 100644
--- a/src/tests/fail_over-tests.c
+++ b/src/tests/fail_over-tests.c
@@ -156,7 +156,7 @@ test_resolve_service_callback(struct tevent_req *req)
task->test_ctx->tasks--;
- recv_status = fo_resolve_service_recv(req, &server);
+ recv_status = fo_resolve_service_recv(req, req, &server);
talloc_free(req);
fail_if(recv_status != task->recv, "%s: Expected return of %d, got %d",
task->location, task->recv, recv_status);
--
2.7.3

View File

@ -1,34 +0,0 @@
From 2e4795b1b93ee740692491c8c4010e9103a0ecca Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn@redhat.com>
Date: Tue, 10 Nov 2015 07:41:10 +0000
Subject: [PATCH 092/108] FAIL_OVER: Fix warning value computed is not used
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
src/providers/fail_over.c: In function fo_ref_server:
src/providers/fail_over.c:861: warning: value computed is not used
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit acd615cffd144b69e2558a0fc45c6966423f2d02)
(cherry picked from commit d0baabaa4e86ef2cf899be5f1369e294688c4b8a)
---
src/providers/fail_over.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
index 65d4fb690d270fa04a0e22f7db37bd8521ad3ba1..b6f29a2a3e1d389560475ae05a4c9a846d817fdb 100644
--- a/src/providers/fail_over.c
+++ b/src/providers/fail_over.c
@@ -858,7 +858,7 @@ void fo_ref_server(TALLOC_CTX *ref_ctx,
struct fo_server *server)
{
if (server) {
- rc_reference(ref_ctx, struct fo_server, server);
+ server = rc_reference(ref_ctx, struct fo_server, server);
}
}
--
2.7.3

View File

@ -1,167 +0,0 @@
From 34db150dae50363dd0f551175e160e9c238a251f Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Wed, 18 Nov 2015 20:48:51 +0100
Subject: [PATCH 093/108] FO: Use tevent_req_defer_callback() when notifying
callers
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
If a fo_resolve_service callback would modify the server->common member
in any way, for example by dereferencing the server and lowering the
refcount to 0, which would free the common structure, then the next
iteration of fo_resolve_service_done would access memory that was
already gone.
Please see
https://tevent.samba.org/group__tevent__request.html#ga09373077d0b39e321a196a86bfebf280
for more details.
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit a92f68763a57b211a1bf6b80b6dd80c4a1aa2738)
(cherry picked from commit bbfc3a4294c6a70426171e080c27c15d9706bec7)
---
src/providers/fail_over.c | 15 +++++++++++--
src/tests/cmocka/test_fo_srv.c | 49 +++++++++++++++++++++++++++++++++++++++---
2 files changed, 59 insertions(+), 5 deletions(-)
diff --git a/src/providers/fail_over.c b/src/providers/fail_over.c
index b6f29a2a3e1d389560475ae05a4c9a846d817fdb..e945c9924597c7addeeb11090e1c1aee5596cb71 100644
--- a/src/providers/fail_over.c
+++ b/src/providers/fail_over.c
@@ -131,6 +131,7 @@ struct resolve_service_request {
struct server_common *server_common;
struct tevent_req *req;
+ struct tevent_context *ev;
};
struct status {
@@ -940,7 +941,9 @@ resolve_service_request_destructor(struct resolve_service_request *request)
}
static int
-set_lookup_hook(struct fo_server *server, struct tevent_req *req)
+set_lookup_hook(struct tevent_context *ev,
+ struct fo_server *server,
+ struct tevent_req *req)
{
struct resolve_service_request *request;
@@ -956,6 +959,7 @@ set_lookup_hook(struct fo_server *server, struct tevent_req *req)
talloc_free(request);
return ENOMEM;
}
+ request->ev = ev;
request->req = req;
DLIST_ADD(server->common->request_list, request);
talloc_set_destructor(request, resolve_service_request_destructor);
@@ -1142,7 +1146,7 @@ fo_resolve_service_server(struct tevent_req *req)
case SERVER_RESOLVING_NAME:
/* Name resolution is already under way. Just add ourselves into the
* waiting queue so we get notified after the operation is finished. */
- ret = set_lookup_hook(state->server, req);
+ ret = set_lookup_hook(state->ev, state->server, req);
if (ret != EOK) {
tevent_req_error(req, ret);
return true;
@@ -1194,6 +1198,13 @@ fo_resolve_service_done(struct tevent_req *subreq)
/* Take care of all requests for this server. */
while ((request = common->request_list) != NULL) {
DLIST_REMOVE(common->request_list, request);
+
+ /* If the request callback decresed refcount on the returned
+ * server, we would have crashed as common would not be valid
+ * anymore. Rather schedule the notify for next tev iteration
+ */
+ tevent_req_defer_callback(request->req, request->ev);
+
if (ret) {
tevent_req_error(request->req, ret);
} else {
diff --git a/src/tests/cmocka/test_fo_srv.c b/src/tests/cmocka/test_fo_srv.c
index 67f86fb17753bf90b88d007a6a1b309df830c152..a84ce4348d2e59aaab4fc9ac1bd4cfd853ff491d 100644
--- a/src/tests/cmocka/test_fo_srv.c
+++ b/src/tests/cmocka/test_fo_srv.c
@@ -575,10 +575,10 @@ static void test_fo_srv_before(struct tevent_req *req)
fo_set_server_status(test_ctx->srv, SERVER_WORKING);
/* Simulate changing the DNS environment. Change the host names */
- s1 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 2, 389);
+ s1 = mock_ares_reply(test_ctx, "ldap1.sssd.com", 100, 2, 389);
assert_non_null(s1);
- s2 = mock_ares_reply(test_ctx, "ldap3.sssd.com", 100, 1, 389);
+ s2 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 1, 389);
assert_non_null(s2);
s1->next = s2;
@@ -596,12 +596,17 @@ static void test_fo_srv_before(struct tevent_req *req)
tevent_req_set_callback(req, test_fo_srv_after, test_ctx);
}
+static void test_fo_srv_after2(struct tevent_req *req);
+
static void test_fo_srv_after(struct tevent_req *req)
{
struct test_fo_ctx *test_ctx = \
tevent_req_callback_data(req, struct test_fo_ctx);
struct fo_server *srv;
errno_t ret;
+ struct ares_srv_reply *s1;
+ struct ares_srv_reply *s2;
+ char *dns_domain;
ret = fo_resolve_service_recv(req, req, &srv);
talloc_zfree(req);
@@ -612,8 +617,46 @@ static void test_fo_srv_after(struct tevent_req *req)
*/
fo_set_server_status(test_ctx->srv, SERVER_WORKING);
+ sleep(test_ctx->ttl + 1);
+
/* Must be a different server now */
- check_server(test_ctx, srv, 389, "ldap3.sssd.com");
+ check_server(test_ctx, srv, 389, "ldap2.sssd.com");
+
+ /* Simulate changing the DNS environment. Change the host names */
+ s1 = mock_ares_reply(test_ctx, "ldap1.sssd.com", 100, 1, 389);
+ assert_non_null(s1);
+
+ s2 = mock_ares_reply(test_ctx, "ldap2.sssd.com", 100, 2, 389);
+ assert_non_null(s2);
+
+ s1->next = s2;
+
+ dns_domain = talloc_strdup(test_ctx, "sssd.com");
+ assert_non_null(dns_domain);
+
+ mock_srv_results(s1, test_ctx->ttl, dns_domain);
+ sleep(test_ctx->ttl + 1);
+
+ req = fo_resolve_service_send(test_ctx, test_ctx->ctx->ev,
+ test_ctx->resolv, test_ctx->fo_ctx,
+ test_ctx->fo_svc);
+ assert_non_null(req);
+ tevent_req_set_callback(req, test_fo_srv_after2, test_ctx);
+}
+
+static void test_fo_srv_after2(struct tevent_req *req)
+{
+ struct test_fo_ctx *test_ctx = \
+ tevent_req_callback_data(req, struct test_fo_ctx);
+ struct fo_server *srv;
+ errno_t ret;
+
+ ret = fo_resolve_service_recv(req, req, &srv);
+ talloc_zfree(req);
+ assert_int_equal(ret, ERR_OK);
+
+ /* Must be a different server now */
+ check_server(test_ctx, srv, 389, "ldap1.sssd.com");
test_ctx->ctx->error = ERR_OK;
test_ctx->ctx->done = true;
--
2.7.3

View File

@ -1,58 +0,0 @@
From 1e596a5b6e72cfca67a3eeb7d9098d015a295545 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Mon, 19 Oct 2015 15:38:08 +0200
Subject: [PATCH 094/108] util: Continue if setlocale fails
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
setlocale needs some environment variables
to be set in order to work. These variables
are not present in some special cases. We
should not fail completely in these cases
but continue with the compatible C locale.
Resolves:
https://fedorahosted.org/sssd/ticket/2785
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit 43e06ff39584570817949dc5de118d2b7ca854c1)
(cherry picked from commit 4815471669a25566f6772c228c104a206ffa37f7)
---
src/sss_client/ssh/sss_ssh_client.c | 4 +++-
src/tools/tools_util.c | 4 +++-
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/sss_client/ssh/sss_ssh_client.c b/src/sss_client/ssh/sss_ssh_client.c
index 0d206ef58f3a1353a8e066c272df0cf4e22ec4db..a198039ec4e2820ad388be41400411753459ecc9 100644
--- a/src/sss_client/ssh/sss_ssh_client.c
+++ b/src/sss_client/ssh/sss_ssh_client.c
@@ -50,7 +50,9 @@ int set_locale(void)
c = setlocale(LC_ALL, "");
if (c == NULL) {
- return EIO;
+ /* If setlocale fails, continue with the default
+ * locale. */
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to set locale\n");
}
errno = 0;
diff --git a/src/tools/tools_util.c b/src/tools/tools_util.c
index 3112171a6c06a50b7099f1c1b58ea1ad581c7cb3..82462f30690e4f695477eb5cc1aa4039c05109f9 100644
--- a/src/tools/tools_util.c
+++ b/src/tools/tools_util.c
@@ -259,7 +259,9 @@ int set_locale(void)
c = setlocale(LC_ALL, "");
if (c == NULL) {
- return EIO;
+ /* If setlocale fails, continue with the default
+ * locale. */
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to set locale\n");
}
errno = 0;
--
2.7.3

View File

@ -1,48 +0,0 @@
From 74c322cbc35889057af2e06b3941bb9cbde864a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Mon, 19 Oct 2015 15:49:02 +0200
Subject: [PATCH 095/108] server_setup: Log failed attempt to set locale
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Failed setlocale call could cause unexpected
behaviour. It is better to generate DEBUG
message if this happens.
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit a0c8aae6b31867f29e83e4f8a2a7ef037a82569e)
(cherry picked from commit 76ab3eb947f4d6fe6555d8ea0ae97dc3966f02ac)
---
src/util/server.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/util/server.c b/src/util/server.c
index 7e9b76f74ee5e76d2481eb425eff4811cc2e780e..7aa8d809663fe562a6ac25fc0f0ce7eddfcb4166 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -458,6 +458,7 @@ int server_setup(const char *name, int flags,
bool dm;
struct tevent_signal *tes;
struct logrotate_ctx *lctx;
+ char *locale;
ret = chown_debug_file(NULL, uid, gid);
if (ret != EOK) {
@@ -509,7 +510,12 @@ int server_setup(const char *name, int flags,
}
/* Set up locale */
- setlocale(LC_ALL, "");
+ locale = setlocale(LC_ALL, "");
+ if (locale == NULL) {
+ /* Just print debug message and continue */
+ DEBUG(SSSDBG_TRACE_FUNC, "Unable to set locale\n");
+ }
+
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
--
2.7.3

View File

@ -1,35 +0,0 @@
From d2752b748ab490438214fdb5b6e7d3ce476f4999 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Tue, 20 Oct 2015 18:18:01 +0200
Subject: [PATCH 096/108] tests: Run intgcheck without libsemanage
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
For now the libsemanage can not be used inside
intgcheck tests. See the tracking ticket
for this issue:
https://fedorahosted.org/sssd/ticket/2859
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit f1b9f9370b50a3d001722737f2538f5d3bb40e9c)
(cherry picked from commit 46a4ce2c853af464f24de63283fb8aa8a8460540)
---
Makefile.am | 1 +
1 file changed, 1 insertion(+)
diff --git a/Makefile.am b/Makefile.am
index 9bd5d0ba895bf699c0b9a46f86419adbd266aece..8eb19ac2765d95747809d28d2625b5b8860e7449 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2709,6 +2709,7 @@ intgcheck:
--prefix="$$prefix" \
--with-ldb-lib-dir="$$prefix"/lib/ldb \
--enable-intgcheck-reqs \
+ --without-semanage \
$(INTGCHECK_CONFIGURE_FLAGS); \
$(MAKE) $(AM_MAKEFLAGS); \
: Force single-thread install to workaround concurrency issues; \
--
2.7.3

View File

@ -1,165 +0,0 @@
From 30bb28a7d8bea694fda7b745607eb1aacfa0af90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michal=20=C5=BDidek?= <mzidek@redhat.com>
Date: Tue, 20 Oct 2015 15:03:22 +0200
Subject: [PATCH 097/108] tests: Regression test with wrong LC_ALL
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Ticket:
https://fedorahosted.org/sssd/ticket/2785
Test local domain tool with wrong LC_ALL
environment variable value.
NOTE: The memory cache files are not deleted
properly in the test teardown to work around the
problem described in ticket
https://fedorahosted.org/sssd/ticket/2726
Once the ticket above is solved, the teardown
will be updated to remove the memory cache
files.
Reviewed-by: Michal Židek <mzidek@redhat.com>
(cherry picked from commit 586f512ab8b6e5a03349598846141f43c1d505b8)
(cherry picked from commit 03f6667741bf111f0e50c8f2c4323e45ce53f707)
---
src/tests/intg/Makefile.am | 1 +
src/tests/intg/test_local_domain.py | 112 ++++++++++++++++++++++++++++++++++++
2 files changed, 113 insertions(+)
create mode 100644 src/tests/intg/test_local_domain.py
diff --git a/src/tests/intg/Makefile.am b/src/tests/intg/Makefile.am
index f21880b61bfb07ac1dca65deda70fc50b4943586..7394997319142d581237ab8a37270bfd7bc974ca 100644
--- a/src/tests/intg/Makefile.am
+++ b/src/tests/intg/Makefile.am
@@ -8,6 +8,7 @@ dist_noinst_DATA = \
ldap_ent.py \
ldap_local_override_test.py \
ldap_test.py \
+ test_local_domain.py \
util.py \
test_memory_cache.py \
$(NULL)
diff --git a/src/tests/intg/test_local_domain.py b/src/tests/intg/test_local_domain.py
new file mode 100644
index 0000000000000000000000000000000000000000..c62de16ce04b640503250c926d6eb3d199ed0728
--- /dev/null
+++ b/src/tests/intg/test_local_domain.py
@@ -0,0 +1,112 @@
+#
+# SSSD LOCAL domain tests
+#
+# Copyright (c) 2015 Red Hat, Inc.
+# Author: Michal Zidek <mzidek@redhat.com>
+#
+# 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 pwd
+import time
+import config
+import signal
+import subprocess
+import pytest
+from util import unindent
+
+
+def stop_sssd():
+ pid_file = open(config.PIDFILE_PATH, "r")
+ pid = int(pid_file.read())
+ os.kill(pid, signal.SIGTERM)
+ while True:
+ try:
+ os.kill(pid, signal.SIGCONT)
+ except:
+ break
+ time.sleep(1)
+
+
+def create_conf_fixture(request, contents):
+ """Generate sssd.conf and add teardown for removing it"""
+ conf = open(config.CONF_PATH, "w")
+ conf.write(contents)
+ conf.close()
+ os.chmod(config.CONF_PATH, stat.S_IRUSR | stat.S_IWUSR)
+ request.addfinalizer(lambda: os.unlink(config.CONF_PATH))
+
+
+def create_sssd_fixture(request):
+ """Start sssd and add teardown for stopping it and removing state"""
+ if subprocess.call(["sssd", "-D", "-f"]) != 0:
+ raise Exception("sssd start failed")
+
+ def teardown():
+ try:
+ stop_sssd()
+ except:
+ pass
+ subprocess.call(["sss_cache", "-E"])
+ for path in os.listdir(config.DB_PATH):
+ os.unlink(config.DB_PATH + "/" + path)
+ # FIXME: Uncomment this when ticket #2726 is solved
+ # https://fedorahosted.org/sssd/ticket/2726
+ # for path in os.listdir(config.MCACHE_PATH):
+ # os.unlink(config.MCACHE_PATH + "/" + path)
+ request.addfinalizer(teardown)
+
+
+@pytest.fixture
+def local_domain_only(request):
+ conf = unindent("""\
+ [sssd]
+ domains = LOCAL
+ services = nss
+
+ [nss]
+ memcache_timeout = 0
+
+ [domain/LOCAL]
+ id_provider = local
+ min_id = 10000
+ max_id = 20000
+ """).format(**locals())
+ create_conf_fixture(request, conf)
+ create_sssd_fixture(request)
+ return None
+
+
+def assert_nonexistent_user(name):
+ with pytest.raises(KeyError):
+ pwd.getpwnam(name)
+
+
+def test_wrong_LC_ALL(local_domain_only):
+ """
+ Regression test for ticket
+ https://fedorahosted.org/sssd/ticket/2785
+
+ """
+ subprocess.check_call(["sss_useradd", "foo", "-M"])
+ pwd.getpwnam("foo")
+
+ # Change the LC_ALL variable to nonexistent locale
+ oldvalue = os.environ.get("LC_ALL", "")
+ os.environ["LC_ALL"] = "nonexistent_locale"
+
+ # sss_userdel must remove the user despite wrong LC_ALL
+ subprocess.check_call(["sss_userdel", "foo", "-R"])
+ assert_nonexistent_user("foo")
+ os.environ["LC_LOCAL"] = oldvalue
--
2.7.3

View File

@ -1,47 +0,0 @@
From 0f98c882b70a9011d488228b36df42cf320f62bf Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Fri, 19 Feb 2016 15:50:12 +0100
Subject: [PATCH 098/108] memberof: Don't allocate on a NULL context
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
https://fedorahosted.org/sssd/ticket/2959
In case no previous delete operation occured, the del_ctx->muops pointer we
allocate the diff structure was would be NULL, effectivelly leaking the
diff array during the memberof processing.
Allocating on del_ctx is safer as that pointer is always allocated and
prevents the leak.
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit cd7a272fb361626a45d54cd45daaab4bfe7ad93f)
---
src/ldb_modules/memberof.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/ldb_modules/memberof.c b/src/ldb_modules/memberof.c
index 83d93196c34854d75fcd8ac91ad056f64b26b659..54e4b3ee2c74b746e8871cb3bb211bfcb25752e0 100644
--- a/src/ldb_modules/memberof.c
+++ b/src/ldb_modules/memberof.c
@@ -2145,7 +2145,7 @@ static int mbof_del_mod_entry(struct mbof_del_operation *delop)
if (!el || !el->num_values) {
return LDB_ERR_OPERATIONS_ERROR;
}
- diff = talloc_array(del_ctx->muops, struct ldb_dn *,
+ diff = talloc_array(del_ctx, struct ldb_dn *,
el->num_values + 1);
if (!diff) {
return LDB_ERR_OPERATIONS_ERROR;
@@ -2241,6 +2241,7 @@ static int mbof_del_mod_entry(struct mbof_del_operation *delop)
if (ret != LDB_SUCCESS) {
return ret;
}
+ talloc_steal(del_ctx->muops, diff[i]);
}
}
--
2.7.3

View File

@ -1,85 +0,0 @@
From 8891e70a4ff58c271729523da59633744a6bcb54 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 1 Mar 2016 14:00:26 +0100
Subject: [PATCH 099/108] IPA SUDO: download externalUser attribute
This allows configuration with id_provider = proxy
and sudo_provider = ipa when someone needs to fetch
rules for local users.
https://fedorahosted.org/sssd/ticket/2972
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 991c9f47fcb24704b880f60ab8ee77cfda056e2c)
(cherry picked from commit d4d2ffa6cf967231ae725973ee2665dbd0e2391b)
---
src/config/etc/sssd.api.d/sssd-ipa.conf | 1 +
src/db/sysdb_sudo.h | 1 +
src/providers/ipa/ipa_common.h | 1 +
src/providers/ipa/ipa_opts.c | 1 +
src/providers/ipa/ipa_sudo_conversion.c | 1 +
5 files changed, 5 insertions(+)
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 8cd20c0c621a513ca7bc85be6908de41d024b148..67a46102b4e8dfff2b44b21ac18c0ad8822d7f3a 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -258,6 +258,7 @@ ipa_sudorule_runasgroupcategory = str, None, false
ipa_sudorule_runasextuser = str, None, false
ipa_sudorule_runasextgroup = str, None, false
ipa_sudorule_runasextusergroup = str, None, false
+ipa_sudorule_externaluser = str, None, false
ipa_sudorule_entry_usn = str, None, false
ipa_sudocmdgroup_object_class = str, None, false
ipa_sudocmdgroup_uuid = str, None, false
diff --git a/src/db/sysdb_sudo.h b/src/db/sysdb_sudo.h
index ba90a68512c6c29134ab2f746220db9533a93dda..515f45ab8b8f51cf7b1d27c1ba28ed8182bce6c0 100644
--- a/src/db/sysdb_sudo.h
+++ b/src/db/sysdb_sudo.h
@@ -68,6 +68,7 @@
#define SYSDB_IPA_SUDORULE_RUNASEXTUSER "ipaSudoRunAsExtUser"
#define SYSDB_IPA_SUDORULE_RUNASEXTGROUP "ipaSudoRunAsExtGroup"
#define SYSDB_IPA_SUDORULE_RUNASEXTUSERGROUP "ipaSudoRunAsExtUserGroup"
+#define SYSDB_IPA_SUDORULE_EXTUSER "externalUser"
#define SYSDB_IPA_SUDOCMDGROUP_OC "ipasudocmdgrp"
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index 24898ee3809b0bcb682321ba4cfa500acd7c795b..d1688bb6a226cd45318dd22380d0ff73d9b2ec47 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -156,6 +156,7 @@ enum ipa_sudorule_attrs {
IPA_AT_SUDORULE_RUNASEXTUSER,
IPA_AT_SUDORULE_RUNASEXTGROUP,
IPA_AT_SUDORULE_RUNASEXTUSERGROUP,
+ IPA_AT_SUDORULE_EXTUSER,
IPA_AT_SUDORULE_ENTRYUSN,
IPA_OPTS_SUDORULE
diff --git a/src/providers/ipa/ipa_opts.c b/src/providers/ipa/ipa_opts.c
index fe469852b527ad872502b3346c8c11ef9eea3bcd..5b0b44e2493ebba0f0cfdb63894a7c75533fc959 100644
--- a/src/providers/ipa/ipa_opts.c
+++ b/src/providers/ipa/ipa_opts.c
@@ -361,6 +361,7 @@ struct sdap_attr_map ipa_sudorule_map[] = {
{ "ipa_sudorule_runasextuser", "ipaSudoRunAsExtUser", SYSDB_IPA_SUDORULE_RUNASEXTUSER, NULL },
{ "ipa_sudorule_runasextgroup", "ipaSudoRunAsExtGroup", SYSDB_IPA_SUDORULE_RUNASEXTGROUP, NULL },
{ "ipa_sudorule_runasextusergroup", "ipaSudoRunAsExtUserGroup", SYSDB_IPA_SUDORULE_RUNASEXTUSERGROUP, NULL },
+ { "ipa_sudorule_externaluser", "externalUser", SYSDB_IPA_SUDORULE_EXTUSER, NULL },
{ "ipa_sudorule_entry_usn", "entryUSN", SYSDB_USN, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ipa/ipa_sudo_conversion.c b/src/providers/ipa/ipa_sudo_conversion.c
index 02d7ebd5dd819f54b6d97b2251eca294d95a224b..ff63551c045003bc81c440ee63aeb28f3fe06647 100644
--- a/src/providers/ipa/ipa_sudo_conversion.c
+++ b/src/providers/ipa/ipa_sudo_conversion.c
@@ -809,6 +809,7 @@ convert_attributes(struct ipa_sudo_conv *conv,
{SYSDB_IPA_SUDORULE_RUNASEXTUSER, SYSDB_SUDO_CACHE_AT_RUNASUSER , NULL},
{SYSDB_IPA_SUDORULE_RUNASEXTGROUP, SYSDB_SUDO_CACHE_AT_RUNASGROUP , NULL},
{SYSDB_IPA_SUDORULE_RUNASEXTUSERGROUP, SYSDB_SUDO_CACHE_AT_RUNASUSER , convert_runasextusergroup},
+ {SYSDB_IPA_SUDORULE_EXTUSER, SYSDB_SUDO_CACHE_AT_USER , NULL},
{SYSDB_IPA_SUDORULE_ALLOWCMD, SYSDB_IPA_SUDORULE_ORIGCMD , NULL},
{SYSDB_IPA_SUDORULE_DENYCMD, SYSDB_IPA_SUDORULE_ORIGCMD , NULL},
{NULL, NULL, NULL}};
--
2.7.3

Some files were not shown because too many files have changed in this diff Show More