[Pkg-freeipa-devel] slapi-nis: Changes to 'master'
Timo Aaltonen
tjaalton at moszumanska.debian.org
Thu Dec 1 08:08:51 UTC 2016
configure.ac | 3
debian/changelog | 6 +
slapi-nis.spec | 13 +-
src/back-nis.c | 6 +
src/back-sch-nss.c | 14 ++
src/back-sch.c | 294 +++++++++++++++++++++++++++++++++++++++++++++++++----
src/back-sch.h | 20 +++
src/back-shr.c | 104 +++++++++++++++---
src/back-shr.h | 1
src/backend.h | 1
src/plug-nis.c | 34 ++++--
src/plug-sch.c | 58 +++++++++-
src/plugin.h | 3
src/wrap.c | 90 ++++++++++++++++
src/wrap.h | 6 +
15 files changed, 597 insertions(+), 56 deletions(-)
New commits:
commit 955099748bb1dc0b3fb58a5966e98e7d9f38f803
Author: Timo Aaltonen <tjaalton at debian.org>
Date: Thu Dec 1 10:07:01 2016 +0200
releasing package slapi-nis version 0.56.1-1
diff --git a/debian/changelog b/debian/changelog
index 88efa26..1e1850f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,8 @@
-slapi-nis (0.56.1-1) UNRELEASED; urgency=medium
+slapi-nis (0.56.1-1) unstable; urgency=medium
* New upstream release.
- -- Timo Aaltonen <tjaalton at debian.org> Thu, 01 Dec 2016 10:04:36 +0200
+ -- Timo Aaltonen <tjaalton at debian.org> Thu, 01 Dec 2016 10:06:52 +0200
slapi-nis (0.55-1) unstable; urgency=medium
commit 73f76bf8813214dcf1ce20cd556b5970246c31cd
Author: Timo Aaltonen <tjaalton at debian.org>
Date: Thu Dec 1 10:04:56 2016 +0200
update changelog
diff --git a/debian/changelog b/debian/changelog
index 776a765..88efa26 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+slapi-nis (0.56.1-1) UNRELEASED; urgency=medium
+
+ * New upstream release.
+
+ -- Timo Aaltonen <tjaalton at debian.org> Thu, 01 Dec 2016 10:04:36 +0200
+
slapi-nis (0.55-1) unstable; urgency=medium
* New upstream release.
commit 54b03fd9f5cf0e9d56bbeefd54adfb2f21c32974
Author: Alexander Bokovoy <abokovoy at redhat.com>
Date: Sun Aug 7 23:36:08 2016 +0300
Release 0.56.1
diff --git a/configure.ac b/configure.ac
index e5a4de7..f82a47e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT(slapi-nis,0.56)
+AC_INIT(slapi-nis,0.56.1)
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE(foreign)
LT_INIT([disable-static])
diff --git a/slapi-nis.spec b/slapi-nis.spec
index d945ad4..c50cd59 100644
--- a/slapi-nis.spec
+++ b/slapi-nis.spec
@@ -10,7 +10,7 @@
%endif
Name: slapi-nis
-Version: 0.56
+Version: 0.56.1
Release: 1%{?dist}
Summary: NIS Server and Schema Compatibility plugins for Directory Server
Group: System Environment/Daemons
@@ -85,6 +85,10 @@ rm -rf $RPM_BUILD_ROOT
%{_sbindir}/nisserver-plugin-defs
%changelog
+* Sun Aug 07 2016 Alexander Bokovoy <abokovoy at redhat.com> - 0.56.1-1
+- Support querying external users by UPN alias
+- Don't clobber target of the pblock for ID views
+
* Mon Jun 20 2016 Alexander Bokovoy <abokovoy at redhat.com> - 0.56-1
- Add priming thread to populate the map cache without blocking the DS
- Add support for changing passwords for users from a primary tree
commit e6f9e2c9282905fa41046379e0bc5c2ac82ae3a9
Author: Alexander Bokovoy <abokovoy at redhat.com>
Date: Wed Jul 27 17:37:14 2016 +0300
back-sch-nss: for users with aliases, return alias as uid
When SSSD resolves AD users on behalf of slapi-nis, it can accept
any user identifier, including user principal name (UPN) which
may be different than the canonical user name which SSSD returns.
As result, the entry created by slapi-nis will be using canonical user
name but the filter for search will refer to the original (aliased)
name. The search will not match the newly created entry.
Fix this issue by returning two values for 'uid' attribute: the
canonical one and the aliased one. This way search will match.
Verified that SSSD with id_provider=ldap happily consumes such entries.
By LDAP schema, 'uid' attribute can have multiple values.
Fixes https://fedorahosted.org/slapi-nis/ticket/12
diff --git a/src/back-sch-nss.c b/src/back-sch-nss.c
index 702590c..db63e59 100644
--- a/src/back-sch-nss.c
+++ b/src/back-sch-nss.c
@@ -230,6 +230,7 @@ backend_build_dn(const char *attribute, const char *value,
static Slapi_Entry *
backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd,
char *container_sdn,
+ char *user_name,
struct backend_search_cbdata *cbdata)
{
Slapi_Entry *entry;
@@ -272,6 +273,18 @@ backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd,
"objectClass", "posixAccount");
slapi_entry_add_string(entry,
"uid", name);
+ if (user_name != NULL) {
+ /* For non-NULL original user name check if it was
+ * an alias/UPN. If so, add it to the entry.
+ * Yes, LDAP schema allows multiple values of 'uid'
+ * attribute.
+ */
+ if (slapi_utf8casecmp((unsigned char*) user_name,
+ (unsigned char*) name) != 0) {
+ slapi_entry_add_string(entry, "uid", user_name);
+ }
+ }
+
slapi_entry_attr_set_uint(entry,
"uidNumber", pwd->pw_uid);
slapi_entry_attr_set_uint(entry,
@@ -510,6 +523,7 @@ repeat:
}
entry = backend_make_user_entry_from_nsswitch_passwd(&pwd, container_sdn,
+ is_uid ? NULL : user_name,
cbdata);
entries = malloc(sizeof(entries[0]) * 2);
if (entries != NULL) {
commit b59b9c87042cb8f4d99421e101349c5f48f91235
Author: Alexander Bokovoy <abokovoy at redhat.com>
Date: Tue Jul 26 18:11:53 2016 +0300
back-sch: do not clobber target of the pblock for idview
When extracting idview all we care is the DN of new target.
We don't really use the rewritten target as a string anymore,
so there is no need to rewrite the string in the pblock.
This fixes a bug when running with 389-ds 1.3.5.10+ which is more
strict about modification of the values in pblock.
Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1360245
diff --git a/src/back-sch.c b/src/back-sch.c
index 0745329..e15988f 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -1652,6 +1652,8 @@ backend_search_cb(Slapi_PBlock *pb)
struct backend_search_cbdata cbdata;
struct backend_staged_search *staged, *next;
int i, isroot, ret;
+ char *original_target = NULL;
+ char *target = NULL;
if (wrap_get_call_level() > 0) {
return 0;
@@ -1676,7 +1678,7 @@ backend_search_cb(Slapi_PBlock *pb)
return 0;
}
- slapi_pblock_get(pb, SLAPI_SEARCH_TARGET, &cbdata.target);
+ slapi_pblock_get(pb, SLAPI_SEARCH_TARGET, &original_target);
slapi_pblock_get(pb, SLAPI_SEARCH_SCOPE, &cbdata.scope);
slapi_pblock_get(pb, SLAPI_SEARCH_SIZELIMIT, &cbdata.sizelimit);
slapi_pblock_get(pb, SLAPI_SEARCH_TIMELIMIT, &cbdata.timelimit);
@@ -1697,15 +1699,15 @@ backend_search_cb(Slapi_PBlock *pb)
/* Okay, we can search. */
slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id,
"searching from \"%s\" for \"%s\" with scope %d%s\n",
- cbdata.target, cbdata.strfilter, cbdata.scope,
+ original_target, cbdata.strfilter, cbdata.scope,
backend_sch_scope_as_string(cbdata.scope));
- cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target);
+ cbdata.target_dn = slapi_sdn_new_dn_byval(original_target);
/* Check if there's a backend handling this search. */
if (!slapi_be_exist(cbdata.target_dn)) {
slapi_log_error(SLAPI_LOG_PLUGIN,
cbdata.state->plugin_desc->spd_id,
"slapi_be_exists(\"%s\") = 0, "
- "ignoring search\n", cbdata.target);
+ "ignoring search\n", original_target);
slapi_sdn_free(&cbdata.target_dn);
return 0;
}
@@ -1716,22 +1718,23 @@ backend_search_cb(Slapi_PBlock *pb)
* detect the ID view use. Unless the ID view is within the set we control, don't consider the override */
map_data_foreach_domain(cbdata.state, backend_search_find_set_dn_cb, &cbdata);
if (cbdata.answer == FALSE) {
- idview_replace_target_dn(&cbdata.target, &cbdata.idview);
+ target = slapi_ch_strdup(original_target);
+ idview_replace_target_dn(&target, &cbdata.idview);
if (cbdata.idview != NULL) {
slapi_sdn_free(&cbdata.target_dn);
/* Perform another check, now for rewritten DN */
- cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target);
+ cbdata.target_dn = slapi_sdn_new_dn_byval(target);
map_data_foreach_domain(cbdata.state, backend_search_find_set_dn_cb, &cbdata);
/* Rewritten DN might still be outside of our trees */
if (cbdata.answer == TRUE) {
slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id,
"Use of ID view '%s' is detected, searching from \"%s\" "
"for \"%s\" with scope %d%s. Filter may get overridden later.\n",
- cbdata.idview, cbdata.target, cbdata.strfilter, cbdata.scope,
+ cbdata.idview, target, cbdata.strfilter, cbdata.scope,
backend_sch_scope_as_string(cbdata.scope));
} else {
slapi_sdn_free(&cbdata.target_dn);
- slapi_ch_free_string(&cbdata.target);
+ slapi_ch_free_string(&target);
slapi_ch_free_string(&cbdata.idview);
slapi_log_error(SLAPI_LOG_PLUGIN,
cbdata.state->plugin_desc->spd_id,
@@ -1739,6 +1742,8 @@ backend_search_cb(Slapi_PBlock *pb)
"ignoring search\n");
return 0;
}
+ } else {
+ slapi_ch_free_string(&target);
}
}
cbdata.answer = FALSE;
@@ -1890,7 +1895,7 @@ backend_search_cb(Slapi_PBlock *pb)
}
slapi_sdn_free(&cbdata.target_dn);
if (cbdata.idview != NULL) {
- slapi_ch_free_string(&cbdata.target);
+ slapi_ch_free_string(&target);
}
slapi_ch_free_string(&cbdata.idview);
#ifdef USE_IPA_IDVIEWS
@@ -1904,7 +1909,6 @@ backend_search_cb(Slapi_PBlock *pb)
/* Locate the entry for a given DN. */
struct backend_locate_cbdata {
struct plugin_state *state;
- char *target;
Slapi_DN *target_dn;
struct backend_entry_data *entry_data;
@@ -1953,6 +1957,7 @@ static void
backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char **group, const char**set)
{
struct backend_locate_cbdata cbdata;
+ char *original_target = NULL;
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state);
if (cbdata.state->plugin_base == NULL) {
@@ -1960,9 +1965,9 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char **
*data = NULL;
return;
}
- slapi_pblock_get(pb, SLAPI_TARGET_DN, &cbdata.target);
+ slapi_pblock_get(pb, SLAPI_TARGET_DN, &original_target);
- cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target);
+ cbdata.target_dn = slapi_sdn_new_dn_byval(original_target);
cbdata.entry_data = NULL;
cbdata.entry_group = NULL;
cbdata.entry_set = NULL;
@@ -1972,12 +1977,9 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char **
* rebuild the target's RDN to use original attribute's value */
if (cbdata.entry_data == NULL) {
char *idview = NULL;
- char *target, *original_target;
- target = original_target = slapi_ch_strdup(cbdata.target);
+ char *target = NULL;
+ target = slapi_ch_strdup(original_target);
idview_replace_target_dn(&target, &idview);
- if (target != original_target) {
- slapi_ch_free_string(&original_target);
- }
if (idview != NULL) {
char *rdnstr;
char *val;
@@ -1992,7 +1994,6 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char **
bval.bv_val = slapi_ch_strdup(val);
memset(&scbdata, 0, sizeof(scbdata));
scbdata.idview = idview;
- scbdata.target = target;
scbdata.pb = pb;
scbdata.state = cbdata.state;
scbdata.target_dn = slapi_sdn_new_dn_byval(target);
@@ -2025,7 +2026,6 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char **
* insufficient-access error. */
struct backend_group_check_scope_cbdata {
struct plugin_state *state;
- const char *target;
Slapi_DN *target_dn;
bool_t ours;
};
@@ -2050,14 +2050,15 @@ static bool_t
backend_check_scope_pb(Slapi_PBlock *pb)
{
struct backend_group_check_scope_cbdata cbdata;
+ char *original_target = NULL;
slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state);
if (cbdata.state->plugin_base == NULL) {
/* The plugin was not actually started. */
return FALSE;
}
- slapi_pblock_get(pb, SLAPI_TARGET_DN, &cbdata.target);
- cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target);
+ slapi_pblock_get(pb, SLAPI_TARGET_DN, &original_target);
+ cbdata.target_dn = slapi_sdn_new_dn_byval(original_target);
cbdata.ours = FALSE;
map_data_foreach_domain(cbdata.state, backend_group_check_scope_cb,
&cbdata);
diff --git a/src/back-sch.h b/src/back-sch.h
index 1258ae0..9a9abc7 100644
--- a/src/back-sch.h
+++ b/src/back-sch.h
@@ -88,7 +88,7 @@ struct entries_to_send {
struct backend_search_cbdata {
Slapi_PBlock *pb;
struct plugin_state *state;
- char *target, *strfilter, **attrs;
+ char *strfilter, **attrs;
char *idview;
Slapi_Entry **overrides;
int scope, sizelimit, timelimit, attrsonly;
commit 66177cbab545374ccc0bcacdd7a8ffea1ca7be6d
Author: Thierry Bordaz <tbordaz at redhat.com>
Date: Tue Jul 12 11:43:28 2016 +0200
Double free on ldap entry during priming
During Schema-compat cache priming, If it exists an associated domain
the entry returned by the internal search is freed twice.
This was introduced in order for slapi-nis to resolve IPA groups with
fully qualified suffix. To support SSSD 1.14+ change of logic to handle
a default domain suffix.
diff --git a/src/back-sch.c b/src/back-sch.c
index cdd2b3c..0745329 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -284,15 +284,13 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
if (result == 0) {
slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
- slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, NULL);
for (j=0; entries[j] != NULL; j++) {
ret.associated_domain = slapi_entry_attr_get_charptr(entries[j], "associatedDomain");
- slapi_entry_free(entries[i]);
if (ret.associated_domain != NULL)
break;
}
- slapi_ch_free((void**)entries);
}
+ slapi_free_search_results_internal(pb);
}
slapi_pblock_destroy(pb);
pb = NULL;
commit 11df81960498e3e570e2ba46a2e80b7549fd16c1
Author: Alexander Bokovoy <abokovoy at redhat.com>
Date: Mon Jun 20 21:45:37 2016 +0300
Declare int backend_init_extop for reuse in plug-sch.c
diff --git a/src/back-sch.h b/src/back-sch.h
index c15d1ed..1258ae0 100644
--- a/src/back-sch.h
+++ b/src/back-sch.h
@@ -164,6 +164,7 @@ bool_t backend_retrieve_from_nsswitch(struct backend_staged_search *staged,
struct backend_search_cbdata *cbdata);
int backend_sch_do_pam_auth(Slapi_PBlock *pb, const char *username);
+int backend_init_extop(Slapi_PBlock *pb, struct plugin_state *state);
#ifdef USE_IPA_IDVIEWS
void idview_get_overrides(struct backend_search_cbdata *cbdata);
commit 0a5e61c042679679646f6f8f673028f8fbcf3ea7
Author: Alexander Bokovoy <abokovoy at redhat.com>
Date: Wed Jun 15 12:15:46 2016 +0300
slapi-nis: resolve IPA groups with fully qualified suffix
With SSSD 1.14+ there is a logic change to handling of a default domain
suffix.
SSSD has two different formats to handle: the input and output. The
input format is parsed into (name,domain) tuples with the re_expression
option and the output is formatted with the full_name_format option.
Because of the way SSSD used to store the usernames in sysdb, it was
tied to the full_name_format option, just changing the output format
changed the way the names are stored internally. SSSD changed the cache
to always store names in a unified format (foo at bar) and use the
full_name_format only for output, as it should be.
This changed a logic of use_fully_qualified_names=True. It now mandates
that the /input/ contains both the name and the domain part and then
SSSD formats the output using the full_name_format option. The
default_domain_suffix is a hack that just appends its value to an
unqualified input, making all queries for "foo" into "foo at bar".
In new SSSD if configuration contains:
default_domain_suffix = win.domain
full_name_format = $1 # only name
then a request for "foo" will internally turn into "foo at win.domain" but
return "foo" on the output. However, queries for IPA's foo will have to
be qualified by the admin manually like "foo at ipa.domain" otherwise sssd
doesn't know which foo you meant.
Support this logic by querying associatedDomain attribute of the
restricted bases of the data set. IPA stores this information in the
$SUFFIX base dn (dc=example,dc=com) and configures slapi-nis with
restricted base set to $SUFFIX (and the plugin config). While
associatedDomain attribute is multivalued, the $SUFFIX object always has
a single value corresponding to the IPA domain name that is the same as
SSSD domain suffix.
diff --git a/src/back-sch.c b/src/back-sch.c
index bb2aa74..cdd2b3c 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -98,6 +98,7 @@ backend_set_config_free_config_contents(void *data)
slapi_sdn_free(&set_data->container_sdn);
free(set_data->rdn_format);
backend_shr_free_strlist(set_data->attribute_format);
+ slapi_ch_free_string(&set_data->associated_domain);
}
}
void
@@ -149,6 +150,7 @@ backend_copy_set_config(const struct backend_set_data *data)
ret->check_access = data->check_access;
ret->check_nsswitch = data->check_nsswitch;
ret->nsswitch_min_id = data->nsswitch_min_id;
+ ret->associated_domain = data->associated_domain ? slapi_ch_strdup(data->associated_domain) : NULL;
if ((ret->common.group == NULL) ||
(ret->common.set == NULL) ||
@@ -266,6 +268,39 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
free(nsswitch_min_id);
}
+ ret.associated_domain = NULL;
+ if (ret.common.restrict_subtrees != NULL) {
+ Slapi_PBlock *pb = NULL;
+ int result = 0;
+ Slapi_Entry **entries = NULL;
+ int i,j;
+ for (i=0; ret.common.restrict_subtrees[i] != NULL; i++) {
+ pb = wrap_pblock_new(NULL);
+ if (pb != NULL) {
+ slapi_search_internal_set_pb_ext(pb, (Slapi_DN*) ret.common.restrict_subtrees[i], LDAP_SCOPE_BASE,
+ "(&(objectclass=domainRelatedObject)(associatedDomain=*))",
+ NULL, 0, NULL, NULL, state->plugin_identity, 0);
+ result = slapi_search_internal_pb(pb);
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
+ if (result == 0) {
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, NULL);
+ for (j=0; entries[j] != NULL; j++) {
+ ret.associated_domain = slapi_entry_attr_get_charptr(entries[j], "associatedDomain");
+ slapi_entry_free(entries[i]);
+ if (ret.associated_domain != NULL)
+ break;
+ }
+ slapi_ch_free((void**)entries);
+ }
+ }
+ slapi_pblock_destroy(pb);
+ pb = NULL;
+ if (ret.associated_domain != NULL)
+ break;
+ }
+ }
+
*pret = backend_copy_set_config(&ret);
if (*pret == NULL) {
if (strlen(container) > 0) {
@@ -437,6 +472,7 @@ backend_set_process_external_members(Slapi_PBlock *pb,
struct backend_staged_search staged = {0, };
struct backend_search_cbdata cbdata = {0, };
char *plugin_id = state->plugin_desc->spd_id;
+ char *gname = NULL;
is_attr_exists = slapi_entry_attr_find(e, IPA_ATTR_EXTERNAL_MEMBER, &attr) == 0;
@@ -448,6 +484,11 @@ backend_set_process_external_members(Slapi_PBlock *pb,
* and update entry's memberUid attribute */
staged.name = slapi_entry_attr_get_charptr(e, "cn");
+ if (data->associated_domain != NULL) {
+ gname = slapi_ch_smprintf("%s@%s", staged.name, data->associated_domain);
+ slapi_ch_free_string(&staged.name);
+ staged.name = gname;
+ }
staged.type = SCH_NSSWITCH_GROUP;
staged.search_members = FALSE;
staged.is_id = FALSE;
diff --git a/src/back-sch.h b/src/back-sch.h
index 72ba641..c15d1ed 100644
--- a/src/back-sch.h
+++ b/src/back-sch.h
@@ -38,6 +38,7 @@ struct backend_set_data {
bool_t check_access;
enum sch_search_nsswitch_t check_nsswitch;
unsigned long nsswitch_min_id;
+ char *associated_domain;
};
struct backend_entry_data {
commit 95cced2f956b56b076bc7a33f281d71a6002d935
Author: Alexander Bokovoy <abokovoy at redhat.com>
Date: Mon Jun 20 21:41:35 2016 +0300
Initialize ret before use
diff --git a/src/back-sch.c b/src/back-sch.c
index ff8e8a2..bb2aa74 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -2376,7 +2376,7 @@ static int
backend_extop_cb(Slapi_PBlock *pb)
{
struct plugin_state *state;
- int ret;
+ int ret = 0;
int i;
char *oid = NULL;
IFP fct = NULL;
commit 4a57f466a668d5a73436c3f13a17c8f2ca95628b
Author: Alexander Bokovoy <abokovoy at redhat.com>
Date: Mon Jun 20 21:41:12 2016 +0300
Move advance definition of backend_passwdmod_extop before use
diff --git a/src/back-sch.c b/src/back-sch.c
index 5ba04f4..ff8e8a2 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -54,6 +54,7 @@
#include "map.h"
#include "back-sch.h"
+static int backend_passwdmod_extop(Slapi_PBlock *pb);
backend_extop_handlers_t extop_handlers[] = {{EXTOP_PASSWD_OID, (IFP) backend_passwdmod_extop},
{NULL, NULL}};
static void
commit 1dbb78cfdb4f4f06ffa0e5255c2adce060a7c1bf
Author: Alexander Bokovoy <abokovoy at redhat.com>
Date: Mon Jun 20 17:35:58 2016 +0300
Release 0.56
diff --git a/configure.ac b/configure.ac
index 9ce6bcf..e5a4de7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT(slapi-nis,0.55)
+AC_INIT(slapi-nis,0.56)
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE(foreign)
LT_INIT([disable-static])
diff --git a/slapi-nis.spec b/slapi-nis.spec
index 2546509..d945ad4 100644
--- a/slapi-nis.spec
+++ b/slapi-nis.spec
@@ -10,7 +10,7 @@
%endif
Name: slapi-nis
-Version: 0.55
+Version: 0.56
Release: 1%{?dist}
Summary: NIS Server and Schema Compatibility plugins for Directory Server
Group: System Environment/Daemons
@@ -19,7 +19,7 @@ URL: http://slapi-nis.fedorahosted.org/
Source0: https://fedorahosted.org/releases/s/l/slapi-nis/slapi-nis-%{version}.tar.gz
#Source1: https://fedorahosted.org/releases/s/l/slapi-nis/slapi-nis-%{version}.tar.gz.sig
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
-BuildRequires: 389-ds-base-devel, %{ldap_impl}-devel
+BuildRequires: 389-ds-base-devel > 1.3.5.6, %{ldap_impl}-devel
BuildRequires: nspr-devel, nss-devel, /usr/bin/rpcgen
%if 0%{?fedora} > 18 || 0%{?rhel} > 6
BuildRequires: libsss_nss_idmap-devel
@@ -85,6 +85,11 @@ rm -rf $RPM_BUILD_ROOT
%{_sbindir}/nisserver-plugin-defs
%changelog
+* Mon Jun 20 2016 Alexander Bokovoy <abokovoy at redhat.com> - 0.56-1
+- Add priming thread to populate the map cache without blocking the DS
+- Add support for changing passwords for users from a primary tree
+ - requires DS 1.3.5.6 or later
+
* Tue Jan 26 2016 Alexander Bokovoy <abokovoy at redhat.com> - 0.55-1
- Support external members of IPA groups in schema compat
- Support bind over ID overrides when uid is not overridden
commit c129f8447fb8ca16189e05010e3f3d7def1f7a64
Author: Thierry Bordaz <tbordaz at redhat.com>
Date: Mon Jun 13 18:13:04 2016 +0200
slapi-nis should allow password update on a virtual entry
During password modification ext. op (1.3.6.1.4.1.4203.1.11.1),
if the target entry is in the compat tree, slapi-nis should
remap the entry to the real entry.
This needs to be done in a pre-op extop that calls the callback
function handling a given OID.
The password mod. callback does a reverse mapping of
extop USERID and set it in SLAPI_TARGET_SDN.
https://fedorahosted.org/freeipa/ticket/5955
diff --git a/configure.ac b/configure.ac
index 5b10376..9ce6bcf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -113,6 +113,7 @@ dirsrv)
SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN,
SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN,
SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN,
+ SLAPI_PLUGIN_PRE_EXTOP_FN,
NULL]
,,,
[AC_INCLUDES_DEFAULT
diff --git a/src/back-sch.c b/src/back-sch.c
index 32b1d9e..5ba04f4 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -54,6 +54,8 @@
#include "map.h"
#include "back-sch.h"
+backend_extop_handlers_t extop_handlers[] = {{EXTOP_PASSWD_OID, (IFP) backend_passwdmod_extop},
+ {NULL, NULL}};
static void
backend_entries_to_return_push(struct backend_search_cbdata *cbdata, Slapi_Entry *e);
@@ -2223,6 +2225,191 @@ done_with_lock:
return ret;
}
+/* This callback handles EXTOP_PASSWD_OID "1.3.6.1.4.1.4203.1.11.1"
+ * If the extop defines a USERID, it sets SLAPI_TARGET_SDN to
+ * the reverse mapping of the USERID.
+ *
+ * If it is not possible to retrieve USERID in the ber
+ * then value of SLAPI_TARGET_SDN is unchanged.
+ *
+ * Else the value of SLAPI_TARGET_SDN is freed and replaced
+ * either by the USERID or the reverse mapping of USERID (if it exists)
+ */
+static int
+backend_passwdmod_extop(Slapi_PBlock *pb)
+{
+ struct backend_entry_data *data;
+ struct plugin_state *state;
+ Slapi_DN *sdn = NULL;
+ char *extopdn;
+ char *ndn;
+ const char *entry_group = NULL;
+ const char *entry_set = NULL;
+ struct berval *extop_value = NULL;
+ BerElement *ber = NULL;
+ ber_tag_t tag = 0;
+ ber_len_t len = (ber_len_t) -1;
+
+ if (wrap_get_call_level() > 0) {
+ return 0;
+ }
+
+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
+ if (state->ready_to_serve == 0) {
+ /* No data to serve yet */
+ goto free_and_return;
+ }
+ /* Retrieve the original DN from the ber request */
+ /* Get the ber value of the extended operation */
+ slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value);
+ if (!BV_HAS_DATA(extop_value)) {
+ goto free_and_return;
+ }
+
+ if ((ber = ber_init(extop_value)) == NULL) {
+ goto free_and_return;
+ }
+
+ /* Format of request to parse
+ *
+ * PasswdModifyRequestValue ::= SEQUENCE {
+ * userIdentity [0] OCTET STRING OPTIONAL
+ * oldPasswd [1] OCTET STRING OPTIONAL
+ * newPasswd [2] OCTET STRING OPTIONAL }
+ *
+ * The request value field is optional. If it is
+ * provided, at least one field must be filled in.
+ */
+
+ /* ber parse code */
+ if ( ber_scanf( ber, "{") == LBER_ERROR ) {
+ /* The request field wasn't provided. We'll
+ * now try to determine the userid and verify
+ * knowledge of the old password via other
+ * means.
+ */
+ goto free_and_return;
+ } else {
+ tag = ber_peek_tag( ber, &len);
+ }
+
+ /* identify userID field by tags */
+ if (tag == LDAP_EXTOP_PASSMOD_TAG_USERID ) {
+
+ if ( ber_scanf( ber, "a", &extopdn) == LBER_ERROR ) {
+ slapi_ch_free_string(&extopdn);
+ goto free_and_return;
+ }
+
+ slapi_log_error(SLAPI_LOG_PLUGIN, "backend_passwdmod_extop",
+ "extopdn = %s\n", extopdn ? extopdn : "<unknown>" );
+
+ /* Free the current target_DN */
+ slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
+ if (sdn) {
+ const char *olddn;
+ olddn = slapi_sdn_get_ndn(sdn);
+ slapi_log_error(SLAPI_LOG_PLUGIN, "backend_passwdmod_extop",
+ "olddn = %s (unknown expected)\n", olddn ? olddn : "<unknown>" );
+ slapi_sdn_free(&sdn);
+ }
+
+ /* replace it with the one in the extop req*/
+ sdn = slapi_sdn_new_dn_byref(extopdn);
+ slapi_pblock_set(pb, SLAPI_TARGET_SDN, sdn);
+ } else {
+ /* we can not retrieve the USERID */
+ goto free_and_return;
+ }
+
+ wrap_inc_call_level();
+ if (map_rdlock() != 0) {
+ slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id,
+ "backend_passwdmod_extop unable to acquire read lock\n");
+ wrap_dec_call_level();
+ goto free_and_return;
+ }
+ backend_locate(pb, &data, &entry_group, &entry_set);
+ if (data != NULL) {
+ /* If there is a mapping to a real entry
+ * ndn will contains its DN
+ */
+ if (slapi_sdn_get_ndn(data->original_entry_dn)) {
+ ndn = slapi_ch_strdup(slapi_sdn_get_ndn(data->original_entry_dn));
+ } else {
+ ndn = NULL;
+ }
+ slapi_log_error(SLAPI_LOG_PLUGIN, "backend_passwdmod_extop",
+ "reverse mapped dn = %s\n", ndn ? ndn : "<unknown>" );
+
+ /* the rest does not require to hold the map lock */
+ map_unlock();
+ wrap_dec_call_level();
+
+ if (ndn) {
+ /* replace the TARGET_SDN by the one found in the map
+ * This is the responsibility of the extop to free it
+ */
+ slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
+ if (sdn != NULL) {
+ slapi_sdn_free(&sdn);
+ }
+ sdn = slapi_sdn_new_dn_byref(ndn);
+ slapi_pblock_set(pb, SLAPI_TARGET_SDN, (void*) sdn);
+ }
+ } else {
+ /* no mapping entry to real entry, this is fine */
+ map_unlock();
+ wrap_dec_call_level();
+ }
+
+free_and_return:
+
+ if ( ber != NULL ){
+ ber_free(ber, 1);
+ ber = NULL;
+ }
+ return 0;
+}
+static int
+backend_extop_cb(Slapi_PBlock *pb)
+{
+ struct plugin_state *state;
+ int ret;
+ int i;
+ char *oid = NULL;
+ IFP fct = NULL;
+
+ slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state);
+ if (state->ready_to_serve == 0) {
+ /* No data to serve yet */
+ return 0;
+ }
+
+ /* First check this is a supported OID (for slapi-nis) */
+ if ( slapi_pblock_get( pb, SLAPI_EXT_OP_REQ_OID, &oid ) != 0 )
+ {
+ slapi_log_error( SLAPI_LOG_FATAL, state->plugin_desc->spd_id, "Could not get OID from request\n" );
+ return 0;
+ }
+
+ for (i = 0; extop_handlers[i].oid != NULL; i++) {
+ if (strcmp( oid, extop_handlers[i].oid) == 0 ) {
+ fct = extop_handlers[i].extop_fct;
+ break;
+ }
+ }
+
+ if (fct) {
+ ret = fct(pb);
+ if (ret) {
+ slapi_log_error( SLAPI_LOG_FATAL, "backend_extop_cb",
+ "pre-extop for %s failed %d\n", oid, ret );
+ }
+ }
+ return (ret);
+}
+
static int
backend_compare_cb(Slapi_PBlock *pb)
{
@@ -2286,6 +2473,24 @@ backend_shutdown(struct plugin_state *state)
backend_shr_shutdown(state);
}
+#ifndef SLAPI_PLUGIN_PRE_EXTOP_FN
+#define SLAPI_PLUGIN_PRE_EXTOP_FN 413
+#endif
+int
+backend_init_extop(Slapi_PBlock *pb, struct plugin_state *state)
+{
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "hooking up extop callbacks\n");
+ /* Intercept extended operation requests */
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_EXTOP_FN,
+ backend_extop_cb) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error hooking up pre extop callback\n");
+ return -1;
+ }
+ return 0;
+}
+
int
backend_init_preop(Slapi_PBlock *pb, struct plugin_state *state)
{
diff --git a/src/back-sch.h b/src/back-sch.h
index e8ec400..72ba641 100644
--- a/src/back-sch.h
+++ b/src/back-sch.h
@@ -127,6 +127,22 @@ struct backend_search_filter_config {
void *callback_data;
};
+/* OIDs of the supported extended operation */
+#define EXTOP_PASSWD_OID "1.3.6.1.4.1.4203.1.11.1"
+
+/* ber tags for the PasswdModifyRequestValue sequence */
+#define LDAP_EXTOP_PASSMOD_TAG_USERID 0x80U
+#define LDAP_EXTOP_PASSMOD_TAG_OLDPWD 0x81U
+#define LDAP_EXTOP_PASSMOD_TAG_NEWPWD 0x82U
+
+typedef int (*IFP)();
+static int backend_passwdmod_extop(Slapi_PBlock *pb);
+typedef struct backend_extop_handlers {
+ char *oid;
+ IFP extop_fct;
+} backend_extop_handlers_t;
+
+
/* Analyzes the filter to decide what kind of NSS search is it
* Returns 0 on success, 1 on failure
* struct backend_search_filter_config is populated with information about the filter
diff --git a/src/plug-sch.c b/src/plug-sch.c
index 7af8480..00e7041 100644
--- a/src/plug-sch.c
+++ b/src/plug-sch.c
@@ -65,6 +65,7 @@
#define PLUGIN_BETXN_POSTOP_ID PLUGIN_ID "-betxn_postop"
#define PLUGIN_POSTOP_ID PLUGIN_ID "-postop"
#define PLUGIN_INTERNAL_POSTOP_ID PLUGIN_ID "-internal-postop"
+#define PLUGIN_PRE_EXTOP_ID PLUGIN_ID "-extop-preop"
/* the module initialization function */
static Slapi_PluginDesc
@@ -185,6 +186,20 @@ plugin_shutdown(Slapi_PBlock *pb)
"plugin shutdown completed\n");
return 0;
}
+static int
+schema_compat_plugin_init_extop(Slapi_PBlock *pb)
+{
+ slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_03);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, &plugin_description);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_PRIVATE, global_plugin_state);
+ if (backend_init_extop(pb, global_plugin_state) == -1) {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ global_plugin_state->plugin_desc->spd_id,
+ "error registering extop hooks\n");
+ return -1;
+ }
+ return 0;
+}
static int
schema_compat_plugin_init_preop(Slapi_PBlock *pb)
@@ -343,6 +358,15 @@ schema_compat_plugin_init(Slapi_PBlock *pb)
return -1;
}
#endif
+ if (slapi_register_plugin("preextendedop", TRUE,
+ "schema_compat_plugin_init_extop",
+ schema_compat_plugin_init_extop,
+ PLUGIN_PRE_EXTOP_ID, NULL,
+ state->plugin_identity) != 0) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
+ "error registering extop plugin\n");
+ return -1;
+ }
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"registered plugin hooks\n");
global_plugin_state = NULL;
commit c2dfe9836596565edea1fe7c2bffca3efc6839e2
Author: Thierry Bordaz <tbordaz at redhat.com>
Date: Tue Apr 26 13:17:46 2016 +0300
schema-compat: add backend shutdown support for priming thread
Resolves: rhbz#1327197
diff --git a/src/back-sch.c b/src/back-sch.c
index 9a0e96b..32b1d9e 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -2280,6 +2280,12 @@ backend_startup(Slapi_PBlock *pb, struct plugin_state *state)
backend_shr_startup(state, pb, SCH_CONTAINER_CONFIGURATION_FILTER);
}
+void
+backend_shutdown(struct plugin_state *state)
+{
+ backend_shr_shutdown(state);
+}
+
int
backend_init_preop(Slapi_PBlock *pb, struct plugin_state *state)
{
diff --git a/src/plug-sch.c b/src/plug-sch.c
index 95a4fd8..7af8480 100644
--- a/src/plug-sch.c
More information about the Pkg-freeipa-devel
mailing list