Resolves: rhbz#1139962 - Fedora 21, FreeIPA 4.0.2: sssd does not find user private group from server

This commit is contained in:
Jakub Hrozek 2014-09-15 10:27:34 +02:00
parent 788fd7f1d8
commit f5fb14a9ce
3 changed files with 464 additions and 1 deletions

View File

@ -0,0 +1,91 @@
From 6f91c61426c8cfbfec52d5e77ae4650007694e69 Mon Sep 17 00:00:00 2001
From: Michal Zidek <mzidek@redhat.com>
Date: Wed, 10 Sep 2014 12:41:16 +0200
Subject: [PATCH 1/2] Add alternative objectClass to group attribute maps
In IPA we sometimes need to use posixGroup and
sometimes groupOfNames objectclass to query the
groups. This patch adds the possibility to specify
alternative objectclass in group maps. By
default it is only set for IPA.
Fixes:
https://fedorahosted.org/sssd/ticket/2436
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
src/providers/ad/ad_opts.h | 1 +
src/providers/ipa/ipa_opts.h | 3 ++-
src/providers/ldap/ldap_opts.h | 3 +++
src/providers/ldap/sdap.h | 1 +
4 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h
index 1429b990ef91f2e469d93f031f1fa4f3454b4009..452516cd24aba4dfbf74376767deb8f5f487253d 100644
--- a/src/providers/ad/ad_opts.h
+++ b/src/providers/ad/ad_opts.h
@@ -215,6 +215,7 @@ struct sdap_attr_map ad_2008r2_user_map[] = {
struct sdap_attr_map ad_2008r2_group_map[] = {
{ "ldap_group_object_class", "group", SYSDB_GROUP_CLASS, NULL },
+ { "ldap_group_object_class_alt", NULL, SYSDB_GROUP_CLASS, NULL },
{ "ldap_group_name", "name", SYSDB_NAME, NULL },
{ "ldap_group_pwd", NULL, SYSDB_PWD, NULL },
{ "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 73decc75a361c1b83eaf42b777c118d793596f8f..30cb96b3d183e66bddba0614690fde2076a3b8f8 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -204,7 +204,8 @@ struct sdap_attr_map ipa_user_map[] = {
};
struct sdap_attr_map ipa_group_map[] = {
- { "ldap_group_object_class", "groupofnames", SYSDB_GROUP_CLASS, NULL },
+ { "ldap_group_object_class", "groupOfNames", SYSDB_GROUP_CLASS, NULL },
+ { "ldap_group_object_class_alt", "posixGroup", SYSDB_GROUP_CLASS, NULL },
{ "ldap_group_name", "cn", SYSDB_NAME, NULL },
{ "ldap_group_pwd", "userPassword", SYSDB_PWD, NULL },
{ "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h
index 7c3b4e019d0fad80b4ddebea69fec5532d725535..0a33289f2d1ad618b8745975f1f91a795009768e 100644
--- a/src/providers/ldap/ldap_opts.h
+++ b/src/providers/ldap/ldap_opts.h
@@ -183,6 +183,7 @@ struct sdap_attr_map rfc2307_user_map[] = {
struct sdap_attr_map rfc2307_group_map[] = {
{ "ldap_group_object_class", "posixGroup", SYSDB_GROUP_CLASS, NULL },
+ { "ldap_group_object_class_alt", NULL, SYSDB_GROUP_CLASS, NULL },
{ "ldap_group_name", "cn", SYSDB_NAME, NULL },
{ "ldap_group_pwd", "userPassword", SYSDB_PWD, NULL },
{ "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
@@ -234,6 +235,7 @@ struct sdap_attr_map rfc2307bis_user_map[] = {
struct sdap_attr_map rfc2307bis_group_map[] = {
{ "ldap_group_object_class", "posixGroup", SYSDB_GROUP_CLASS, NULL },
+ { "ldap_group_object_class_alt", NULL, SYSDB_GROUP_CLASS, NULL },
{ "ldap_group_name", "cn", SYSDB_NAME, NULL },
{ "ldap_group_pwd", "userPassword", SYSDB_PWD, NULL },
{ "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
@@ -285,6 +287,7 @@ struct sdap_attr_map gen_ad2008r2_user_map[] = {
struct sdap_attr_map gen_ad2008r2_group_map[] = {
{ "ldap_group_object_class", "group", SYSDB_GROUP_CLASS, NULL },
+ { "ldap_group_object_class_alt", NULL, SYSDB_GROUP_CLASS, NULL },
{ "ldap_group_name", "name", SYSDB_NAME, NULL },
{ "ldap_group_pwd", NULL, SYSDB_PWD, NULL },
{ "ldap_group_gid_number", "gidNumber", SYSDB_GIDNUM, NULL },
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 41063149f65ca1035731d14563b9ff953ae5ac63..937869d1a218ecb2c171f423ee6917dde30eab9a 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -291,6 +291,7 @@ enum sdap_user_attrs {
* Functions depend on this */
enum sdap_group_attrs {
SDAP_OC_GROUP = 0,
+ SDAP_OC_GROUP_ALT,
SDAP_AT_GROUP_NAME,
SDAP_AT_GROUP_PWD,
SDAP_AT_GROUP_GID,
--
1.9.3

View File

@ -0,0 +1,366 @@
From 7ba70236daccb48432350147d0560b3302518cee Mon Sep 17 00:00:00 2001
From: Michal Zidek <mzidek@redhat.com>
Date: Wed, 10 Sep 2014 12:56:54 +0200
Subject: [PATCH 2/2] Use the alternative objectclass in group maps.
Use the alternative group objectclass in queries.
Fixes:
https://fedorahosted.org/sssd/ticket/2436
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
---
src/providers/ldap/ldap_id.c | 18 ++++++----
src/providers/ldap/sdap.c | 40 ++++++++++++++++++---
src/providers/ldap/sdap.h | 2 ++
src/providers/ldap/sdap_async_enum.c | 12 +++++--
src/providers/ldap/sdap_async_initgroups.c | 50 +++++++++++++++++++++------
src/providers/ldap/sdap_async_initgroups_ad.c | 13 +++++--
src/providers/ldap/sdap_async_nested_groups.c | 11 ++++--
7 files changed, 117 insertions(+), 29 deletions(-)
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index eb349f3cc22ba0ef8c43f9a3b6010cbf792cfdc2..e8b3a0e1e1dce6e0c8a9b21aa7c6299108dad24d 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -540,6 +540,7 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
enum idmap_error_code err;
char *sid;
const char *member_filter[2];
+ char *oc_list;
req = tevent_req_create(memctx, &state, struct groups_get_state);
if (!req) return NULL;
@@ -645,21 +646,26 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx,
goto done;
}
+ oc_list = sdap_make_oc_list(state, ctx->opts->group_map);
+ if (oc_list == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
if (state->use_id_mapping || filter_type == BE_FILTER_SECID) {
/* When mapping IDs or looking for SIDs, we don't want to limit
* ourselves to groups with a GID value
*/
state->filter = talloc_asprintf(state,
- "(&(%s=%s)(objectclass=%s)(%s=*))",
- attr_name, clean_name,
- ctx->opts->group_map[SDAP_OC_GROUP].name,
+ "(&(%s=%s)(%s)(%s=*))",
+ attr_name, clean_name, oc_list,
ctx->opts->group_map[SDAP_AT_GROUP_NAME].name);
} else {
state->filter = talloc_asprintf(state,
- "(&(%s=%s)(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",
- attr_name, clean_name,
- ctx->opts->group_map[SDAP_OC_GROUP].name,
+ "(&(%s=%s)(%s)(%s=*)(&(%s=*)(!(%s=0))))",
+ attr_name, clean_name, oc_list,
ctx->opts->group_map[SDAP_AT_GROUP_NAME].name,
ctx->opts->group_map[SDAP_AT_GROUP_GID].name,
ctx->opts->group_map[SDAP_AT_GROUP_GID].name);
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index ff50f8b5daf25d31c2eb57014a1a096833c628fa..7034b11ed8e3aabdcff94462079484dd3ca53ef9 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -290,6 +290,8 @@ int sdap_get_map(TALLOC_CTX *memctx,
/* =Parse-msg============================================================= */
+static bool objectclass_matched(struct sdap_attr_map *map,
+ const char *objcl, int len);
int sdap_parse_entry(TALLOC_CTX *memctx,
struct sdap_handle *sh, struct sdap_msg *sm,
struct sdap_attr_map *map, int attrs_num,
@@ -348,9 +350,7 @@ int sdap_parse_entry(TALLOC_CTX *memctx,
}
for (i = 0; vals[i]; i++) {
- /* the objectclass is always the first name in the map */
- if (strncasecmp(map[0].name,
- vals[i]->bv_val, vals[i]->bv_len) == 0) {
+ if (objectclass_matched(map, vals[i]->bv_val, vals[i]->bv_len)) {
/* ok it's an entry of the right type */
break;
}
@@ -530,6 +530,25 @@ done:
return ret;
}
+static bool objectclass_matched(struct sdap_attr_map *map,
+ const char *objcl, int len)
+{
+ if (len == 0) {
+ len = strlen(objcl) + 1;
+ }
+
+ if (strncasecmp(map[SDAP_OC_GROUP].name, objcl, len) == 0) {
+ return true;
+ }
+
+ if (map[SDAP_OC_GROUP_ALT].name != NULL
+ && strncasecmp(map[SDAP_OC_GROUP_ALT].name, objcl, len) == 0) {
+ return true;
+ }
+
+ return false;
+}
+
/* Parses an LDAPDerefRes into sdap_deref_attrs structure */
errno_t sdap_parse_deref(TALLOC_CTX *mem_ctx,
struct sdap_attr_map_info *minfo,
@@ -630,7 +649,7 @@ errno_t sdap_parse_deref(TALLOC_CTX *mem_ctx,
for (i=0; ocs[i]; i++) {
/* the objectclass is always the first name in the map */
- if (strcasecmp(minfo[mi].map[0].name, ocs[i]) == 0) {
+ if (objectclass_matched(minfo[mi].map, ocs[i], 0)) {
DEBUG(SSSDBG_TRACE_ALL,
"Found map for objectclass '%s'\n", ocs[i]);
map = minfo[mi].map;
@@ -1449,3 +1468,16 @@ errno_t sdap_get_netgroup_primary_name(TALLOC_CTX *memctx,
opts->netgroup_map[SDAP_AT_NETGROUP_NAME].name,
attrs, dom, _netgroup_name);
}
+
+char *sdap_make_oc_list(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map)
+{
+ if (map[SDAP_OC_GROUP_ALT].name == NULL) {
+ return talloc_asprintf(mem_ctx, "objectClass=%s",
+ map[SDAP_OC_GROUP].name);
+ } else {
+ return talloc_asprintf(mem_ctx,
+ "|(objectClass=%s)(objectClass=%s)",
+ map[SDAP_OC_GROUP].name,
+ map[SDAP_OC_GROUP_ALT].name);
+ }
+}
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 937869d1a218ecb2c171f423ee6917dde30eab9a..7eb7cffd8427cbc47c7d2de4fa72e4e87698a661 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -560,4 +560,6 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx,
struct sdap_server_opts **srv_opts);
void sdap_steal_server_opts(struct sdap_id_ctx *id_ctx,
struct sdap_server_opts **srv_opts);
+
+char *sdap_make_oc_list(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map);
#endif /* _SDAP_H_ */
diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c
index 1c69c07f814e3f791dcd4f98edfaa9457ab8ae47..242b3172f367b0b35738bd2e86ea927a4409d2d6 100644
--- a/src/providers/ldap/sdap_async_enum.c
+++ b/src/providers/ldap/sdap_async_enum.c
@@ -717,6 +717,7 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
struct enum_groups_state *state;
int ret;
bool use_mapping;
+ char *oc_list;
req = tevent_req_create(memctx, &state, struct enum_groups_state);
if (!req) return NULL;
@@ -732,9 +733,14 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
sdom->dom->domain_id);
/* We always want to filter on objectclass and an available name */
- state->filter = talloc_asprintf(state,
- "(&(objectclass=%s)(%s=*)",
- ctx->opts->group_map[SDAP_OC_GROUP].name,
+ oc_list = sdap_make_oc_list(state, ctx->opts->group_map);
+ if (oc_list == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n");
+ ret = ENOMEM;
+ goto fail;
+ }
+
+ state->filter = talloc_asprintf(state, "(&(%s)(%s=*)", oc_list,
ctx->opts->group_map[SDAP_AT_GROUP_NAME].name);
if (!state->filter) {
DEBUG(SSSDBG_MINOR_FAILURE,
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 9f45fde39a3cd9f0f950ba5f3dd67e791621273f..d3e080013ec99c18648c6a57e478d50eb3b666f1 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -368,6 +368,7 @@ struct tevent_req *sdap_initgr_rfc2307_send(TALLOC_CTX *memctx,
const char **attr_filter;
char *clean_name;
errno_t ret;
+ char *oc_list;
req = tevent_req_create(memctx, &state, struct sdap_initgr_rfc2307_state);
if (!req) return NULL;
@@ -419,11 +420,17 @@ struct tevent_req *sdap_initgr_rfc2307_send(TALLOC_CTX *memctx,
return NULL;
}
+ oc_list = sdap_make_oc_list(state, opts->group_map);
+ if (oc_list == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
state->base_filter = talloc_asprintf(state,
- "(&(%s=%s)(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",
+ "(&(%s=%s)(%s)(%s=*)(&(%s=*)(!(%s=0))))",
opts->group_map[SDAP_AT_GROUP_MEMBER].name,
- clean_name,
- opts->group_map[SDAP_OC_GROUP].name,
+ clean_name, oc_list,
opts->group_map[SDAP_AT_GROUP_NAME].name,
opts->group_map[SDAP_AT_GROUP_GID].name,
opts->group_map[SDAP_AT_GROUP_GID].name);
@@ -805,6 +812,7 @@ static errno_t sdap_initgr_nested_noderef_search(struct tevent_req *req)
int i;
struct tevent_req *subreq;
struct sdap_initgr_nested_state *state;
+ char *oc_list;
state = tevent_req_data(req, struct sdap_initgr_nested_state);
@@ -823,8 +831,13 @@ static errno_t sdap_initgr_nested_noderef_search(struct tevent_req *req)
state->group_dns[i] = NULL; /* terminate */
state->cur = 0;
- state->filter = talloc_asprintf(state, "(&(objectclass=%s)(%s=*))",
- state->opts->group_map[SDAP_OC_GROUP].name,
+ oc_list = sdap_make_oc_list(state, state->opts->group_map);
+ if (oc_list == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n");
+ return ENOMEM;
+ }
+
+ state->filter = talloc_asprintf(state, "(&(%s)(%s=*))", oc_list,
state->opts->group_map[SDAP_AT_GROUP_NAME].name);
if (!state->filter) {
return ENOMEM;
@@ -1513,6 +1526,7 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
const char **attr_filter;
char *clean_orig_dn;
bool use_id_mapping;
+ char *oc_list;
req = tevent_req_create(memctx, &state, struct sdap_initgr_rfc2307bis_state);
if (!req) return NULL;
@@ -1565,11 +1579,18 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send(
sdom->dom->name,
sdom->dom->domain_id);
+ oc_list = sdap_make_oc_list(state, opts->group_map);
+ if (oc_list == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
state->base_filter =
- talloc_asprintf(state, "(&(%s=%s)(objectclass=%s)(%s=*)",
+ talloc_asprintf(state,
+ "(&(%s=%s)(%s)(%s=*)",
opts->group_map[SDAP_AT_GROUP_MEMBER].name,
- clean_orig_dn,
- opts->group_map[SDAP_OC_GROUP].name,
+ clean_orig_dn, oc_list,
opts->group_map[SDAP_AT_GROUP_NAME].name);
if (!state->base_filter) {
ret = ENOMEM;
@@ -2263,6 +2284,7 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req)
hash_value_t value;
struct sdap_rfc2307bis_nested_ctx *state =
tevent_req_data(req, struct sdap_rfc2307bis_nested_ctx);
+ char *oc_list;
tmp_ctx = talloc_new(state);
if (!tmp_ctx) {
@@ -2339,11 +2361,17 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req)
goto done;
}
+ oc_list = sdap_make_oc_list(state, state->opts->group_map);
+ if (oc_list == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
state->base_filter = talloc_asprintf(
- state, "(&(%s=%s)(objectclass=%s)(%s=*))",
+ state, "(&(%s=%s)(%s)(%s=*))",
state->opts->group_map[SDAP_AT_GROUP_MEMBER].name,
- clean_orig_dn,
- state->opts->group_map[SDAP_OC_GROUP].name,
+ clean_orig_dn, oc_list,
state->opts->group_map[SDAP_AT_GROUP_NAME].name);
if (!state->base_filter) {
ret = ENOMEM;
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index 82d8c8af76c5d7c7a007eab6b1b81d37ecd2f2da..9923958b887138dd33b877005b2d27a7c2de86b3 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -70,6 +70,7 @@ sdap_get_ad_match_rule_initgroups_send(TALLOC_CTX *mem_ctx,
struct sdap_ad_match_rule_initgr_state *state;
const char **filter_members;
char *sanitized_user_dn;
+ char *oc_list;
req = tevent_req_create(mem_ctx, &state,
struct sdap_ad_match_rule_initgr_state);
@@ -122,13 +123,19 @@ sdap_get_ad_match_rule_initgroups_send(TALLOC_CTX *mem_ctx,
/* Craft a special filter according to
* http://msdn.microsoft.com/en-us/library/windows/desktop/aa746475%28v=vs.85%29.aspx
*/
+ oc_list = sdap_make_oc_list(state, state->opts->group_map);
+ if (oc_list == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n");
+ ret = ENOMEM;
+ goto immediate;
+ }
+
state->base_filter =
talloc_asprintf(state,
- "(&(%s:%s:=%s)(objectClass=%s))",
+ "(&(%s:%s:=%s)(%s))",
state->opts->group_map[SDAP_AT_GROUP_MEMBER].name,
SDAP_MATCHING_RULE_IN_CHAIN,
- sanitized_user_dn,
- state->opts->group_map[SDAP_OC_GROUP].name);
+ sanitized_user_dn, oc_list);
talloc_zfree(sanitized_user_dn);
if (!state->base_filter) {
ret = ENOMEM;
diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c
index b07616a93da9a5b2007a706958c4c69de4471342..ad5667e59a9f75e1a564d7505d7e5cd7f2e013f2 100644
--- a/src/providers/ldap/sdap_async_nested_groups.c
+++ b/src/providers/ldap/sdap_async_nested_groups.c
@@ -1712,6 +1712,7 @@ sdap_nested_group_lookup_group_send(TALLOC_CTX *mem_ctx,
const char **attrs = NULL;
const char *base_filter = NULL;
const char *filter = NULL;
+ char *oc_list;
errno_t ret;
req = tevent_req_create(mem_ctx, &state,
@@ -1728,8 +1729,14 @@ sdap_nested_group_lookup_group_send(TALLOC_CTX *mem_ctx,
}
/* create filter */
- base_filter = talloc_asprintf(attrs, "(&(objectclass=%s)(%s=*))",
- map[SDAP_OC_GROUP].name,
+ oc_list = sdap_make_oc_list(state, map);
+ if (oc_list == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Failed to create objectClass list.\n");
+ ret = ENOMEM;
+ goto immediately;
+ }
+
+ base_filter = talloc_asprintf(attrs, "(&(%s)(%s=*))", oc_list,
map[SDAP_AT_GROUP_NAME].name);
if (base_filter == NULL) {
ret = ENOMEM;
--
1.9.3

View File

@ -20,7 +20,7 @@
Name: sssd
Version: 1.12.1
Release: 1%{?dist}
Release: 2%{?dist}
Group: Applications/System
Summary: System Security Services Daemon
License: GPLv3+
@ -29,6 +29,8 @@ Source0: https://fedorahosted.org/released/sssd/%{name}-%{version}.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
### Patches ###
Patch0001: 0001-Add-alternative-objectClass-to-group-attribute-maps.patch
Patch0002: 0002-Use-the-alternative-objectclass-in-group-maps.patch
### Dependencies ###
Requires: sssd-common = %{version}-%{release}
@ -841,6 +843,10 @@ fi
%postun -n libsss_idmap -p /sbin/ldconfig
%changelog
* Mon Sep 15 2014 Jakub Hrozek <jhrozek@redhat.com> - 1.12.1-2
- Resolves: rhbz#1139962 - Fedora 21, FreeIPA 4.0.2: sssd does not find user
private group from server
* Mon Sep 8 2014 Jakub Hrozek <jhrozek@redhat.com> - 1.12.1-1
- New upstream release 1.12.1
- https://fedorahosted.org/sssd/wiki/Releases/Notes-1.12.1