Resolves: rhbz#1256849 - SUDO: Support the IPA schema

This commit is contained in:
Lukas Slebodnik 2016-01-19 18:23:34 +01:00
parent 94f4c4dd6d
commit 9bfc8ef4de
45 changed files with 9923 additions and 1 deletions

View File

@ -0,0 +1,43 @@
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

@ -0,0 +1,32 @@
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

@ -0,0 +1,114 @@
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

@ -0,0 +1,69 @@
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

@ -0,0 +1,44 @@
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

@ -0,0 +1,89 @@
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

@ -0,0 +1,86 @@
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

@ -0,0 +1,37 @@
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

@ -0,0 +1,49 @@
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

@ -0,0 +1,35 @@
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

@ -0,0 +1,62 @@
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

@ -0,0 +1,383 @@
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

@ -0,0 +1,369 @@
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

@ -0,0 +1,37 @@
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

@ -0,0 +1,216 @@
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

@ -0,0 +1,988 @@
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

@ -0,0 +1,394 @@
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

@ -0,0 +1,68 @@
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

@ -0,0 +1,28 @@
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

@ -0,0 +1,510 @@
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

@ -0,0 +1,152 @@
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

@ -0,0 +1,208 @@
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

@ -0,0 +1,169 @@
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

@ -0,0 +1,93 @@
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

@ -0,0 +1,91 @@
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

@ -0,0 +1,191 @@
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

@ -0,0 +1,315 @@
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

@ -0,0 +1,138 @@
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

@ -0,0 +1,80 @@
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

@ -0,0 +1,610 @@
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

@ -0,0 +1,62 @@
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

@ -0,0 +1,87 @@
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

@ -0,0 +1,127 @@
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

@ -0,0 +1,31 @@
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

@ -0,0 +1,178 @@
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

@ -0,0 +1,66 @@
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

@ -0,0 +1,103 @@
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

@ -0,0 +1,240 @@
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

@ -0,0 +1,90 @@
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

@ -0,0 +1,575 @@
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

@ -0,0 +1,95 @@
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

@ -0,0 +1,57 @@
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

@ -0,0 +1,92 @@
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

@ -24,7 +24,7 @@
Name: sssd Name: sssd
Version: 1.13.3 Version: 1.13.3
Release: 1%{?dist} Release: 2%{?dist}
Group: Applications/System Group: Applications/System
Summary: System Security Services Daemon Summary: System Security Services Daemon
License: GPLv3+ License: GPLv3+
@ -33,6 +33,50 @@ Source0: https://fedorahosted.org/released/sssd/%{name}-%{version}.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
### Patches ### ### Patches ###
Patch0001: 0001-nfs-idmap-fix-infinite-loop.patch
Patch0002: 0002-Use-right-domain-for-user-lookups.patch
Patch0003: 0003-sdap_save_grpmem-determine-domain-by-SID-if-possible.patch
Patch0004: 0004-ipa_s2n_save_objects-use-configured-user-and-group-t.patch
Patch0005: 0005-SPEC-Change-package-ownership-of-pubconfpath-krb5.in.patch
Patch0006: 0006-AD-SRV-prefer-site-local-DCs-in-LDAP-ping.patch
Patch0007: 0007-ldap-remove-originalMeberOf-if-there-is-no-memberOf.patch
Patch0008: 0008-KRB5-Adding-DNS-SRV-lookup-for-krb5-provider.patch
Patch0009: 0009-SDAP-do-not-fail-if-refs-are-found-but-not-processed.patch
Patch0010: 0010-sudo-remove-unused-param-name-in-sdap_sudo_get_usn.patch
Patch0011: 0011-sudo-remove-unused-param.-in-ldap_get_sudo_options.patch
Patch0012: 0012-SDAP-Add-request-that-iterates-over-all-search-bases.patch
Patch0013: 0013-SDAP-rename-sdap_get_id_specific_filter.patch
Patch0014: 0014-SDAP-support-empty-filters-in-sdap_combine_filters.patch
Patch0015: 0015-SUDO-use-sdap_search_bases-instead-custom-sb-iterato.patch
Patch0016: 0016-SUDO-make-sudo-sysdb-interface-more-reusable.patch
Patch0017: 0017-SUDO-move-code-shared-between-ldap-and-ipa-to-separa.patch
Patch0018: 0018-SUDO-allow-to-disable-ptask.patch
Patch0019: 0019-SUDO-fail-on-failed-request-that-cannot-be-retry.patch
Patch0020: 0020-IPA-add-ipa_get_rdn-and-ipa_check_rdn.patch
Patch0021: 0021-SDAP-use-ipa_get_rdn-in-nested-groups.patch
Patch0022: 0022-IPA-SUDO-choose-between-IPA-and-LDAP-schema.patch
Patch0023: 0023-IPA-SUDO-Add-ipasudorule-mapping.patch
Patch0024: 0024-IPA-SUDO-Add-ipasudocmdgrp-mapping.patch
Patch0025: 0025-IPA-SUDO-Add-ipasudocmd-mapping.patch
Patch0026: 0026-IPA-SUDO-Implement-sudo-handler.patch
Patch0027: 0027-IPA-SUDO-Implement-full-refresh.patch
Patch0028: 0028-IPA-SUDO-Implement-rules-refresh.patch
Patch0029: 0029-IPA-SUDO-Remember-USN.patch
Patch0030: 0030-SDAP-Add-sdap_or_filters.patch
Patch0031: 0031-IPA-SUDO-Implement-smart-refresh.patch
Patch0032: 0032-SUDO-sdap_sudo_set_usn-do-not-steal-usn.patch
Patch0033: 0033-SUDO-remove-full_refresh_in_progress.patch
Patch0034: 0034-SUDO-assume-zero-if-usn-is-unknown.patch
Patch0035: 0035-SUDO-allow-disabling-full-refresh.patch
Patch0036: 0036-SUDO-remember-usn-as-number-instead-of-string.patch
Patch0037: 0037-SUDO-simplify-usn-filter.patch
Patch0038: 0038-IPA-SUDO-Add-support-for-ipaSudoRunAsExt-attributes.patch
Patch0039: 0039-UTIL-allow-to-skip-default-options-for-child-process.patch
Patch0040: 0040-DP_TASK-add-be_ptask_get_timeout.patch
Patch0041: 0041-AD-add-task-to-renew-the-machine-account-password-if.patch
Patch0042: 0042-FO-add-fo_get_active_server.patch
Patch0043: 0043-FO-add-be_fo_get_active_server_name.patch
Patch0044: 0044-AD-try-to-use-current-server-in-the-renewal-task.patch
Patch0100: 0100-FO-Don-t-free-rc-allocated-structure.patch Patch0100: 0100-FO-Don-t-free-rc-allocated-structure.patch
Patch0101: 0101-tests-Reduce-failover-code-duplication.patch Patch0101: 0101-tests-Reduce-failover-code-duplication.patch
Patch0102: 0102-FO-Use-refcount-to-keep-track-of-servers-returned-to.patch Patch0102: 0102-FO-Use-refcount-to-keep-track-of-servers-returned-to.patch
@ -1019,6 +1063,9 @@ fi
%{_libdir}/%{name}/modules/libwbclient.so %{_libdir}/%{name}/modules/libwbclient.so
%changelog %changelog
* Tue Jan 19 2016 Lukas Slebodnik <lslebodn@redhat.com> - 1.13.3-2
- Resolves: rhbz#1256849 - SUDO: Support the IPA schema
* Wed Dec 16 2015 Lukas Slebodnik <lslebodn@redhat.com> - 1.13.3-1 * Wed Dec 16 2015 Lukas Slebodnik <lslebodn@redhat.com> - 1.13.3-1
- New upstream release 1.13.3 - New upstream release 1.13.3
- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.13.3 - https://fedorahosted.org/sssd/wiki/Releases/Notes-1.13.3