diff options
author | Rob Crittenden <rcritten@redhat.com> | 2012-11-15 21:38:26 -0500 |
---|---|---|
committer | Martin Kosek <mkosek@redhat.com> | 2012-11-21 14:55:12 +0100 |
commit | f1f1b4e7f2e9c1838ad7ec76002b78ca0c2a3c46 (patch) | |
tree | 7c563571ef9e8ac8599cd81a5b17422d79eb2f59 | |
parent | 2093007d4d2b3183b65a07d421954b3e8a12e93b (diff) | |
download | freeipa.git-f1f1b4e7f2e9c1838ad7ec76002b78ca0c2a3c46.tar.gz freeipa.git-f1f1b4e7f2e9c1838ad7ec76002b78ca0c2a3c46.tar.xz freeipa.git-f1f1b4e7f2e9c1838ad7ec76002b78ca0c2a3c46.zip |
Enable transactions by default, make password and modrdn TXN-aware
The password and modrdn plugins needed to be made transaction aware
for the pre and post operations.
Remove the reverse member hoop jumping. Just fetch the entry once
and all the memberof data is there (plus objectclass).
Fix some unit tests that are failing because we actually get the data
now due to transactions.
Add small bit of code in user plugin to retrieve the user again
ala wait_for_attr but in the case of transactions we need do it only
once.
Deprecate wait_for_attr code.
Add a memberof fixup task for roles.
https://fedorahosted.org/freeipa/ticket/1263
https://fedorahosted.org/freeipa/ticket/1891
https://fedorahosted.org/freeipa/ticket/2056
https://fedorahosted.org/freeipa/ticket/3043
https://fedorahosted.org/freeipa/ticket/3191
https://fedorahosted.org/freeipa/ticket/3046
27 files changed, 186 insertions, 116 deletions
diff --git a/daemons/ipa-slapi-plugins/ipa-modrdn/ipa_modrdn.c b/daemons/ipa-slapi-plugins/ipa-modrdn/ipa_modrdn.c index 70a4ea82..6cec5f24 100644 --- a/daemons/ipa-slapi-plugins/ipa-modrdn/ipa_modrdn.c +++ b/daemons/ipa-slapi-plugins/ipa-modrdn/ipa_modrdn.c @@ -201,6 +201,12 @@ ipamodrdn_init(Slapi_PBlock *pb) { int status = EOK; char *plugin_identity = NULL; + Slapi_Entry *plugin_entry = NULL; + char *plugin_type = NULL; + int delfn = SLAPI_PLUGIN_POST_DELETE_FN; + int mdnfn = SLAPI_PLUGIN_POST_MODRDN_FN; + int modfn = SLAPI_PLUGIN_POST_MODIFY_FN; + int addfn = SLAPI_PLUGIN_POST_ADD_FN; LOG_TRACE("--in-->\n"); @@ -213,6 +219,18 @@ ipamodrdn_init(Slapi_PBlock *pb) PR_ASSERT(plugin_identity); setPluginID(plugin_identity); + if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) && + plugin_entry && + (plugin_type = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-plugintype")) && + plugin_type && strstr(plugin_type, "betxn")) + { + addfn = SLAPI_PLUGIN_BE_TXN_POST_ADD_FN; + mdnfn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN; + delfn = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN; + modfn = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN; + } + slapi_ch_free_string(&plugin_type); + if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01) != 0 || slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, @@ -221,13 +239,13 @@ ipamodrdn_init(Slapi_PBlock *pb) (void *) ipamodrdn_start) != 0 || slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, (void *) ipamodrdn_close) != 0 || - slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN, + slapi_pblock_set(pb, addfn, (void *) ipamodrdn_config_check_post_op) != 0 || - slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN, + slapi_pblock_set(pb, mdnfn, (void *) ipamodrdn_post_op) != 0 || - slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN, + slapi_pblock_set(pb, delfn, (void *) ipamodrdn_config_check_post_op) != 0 || - slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN, + slapi_pblock_set(pb, modfn, (void *) ipamodrdn_config_check_post_op) != 0) { LOG_FATAL("failed to register plugin\n"); status = EFAIL; diff --git a/daemons/ipa-slapi-plugins/ipa-modrdn/modrdn-conf.ldif b/daemons/ipa-slapi-plugins/ipa-modrdn/modrdn-conf.ldif index 176f8bec..3ae1ee2f 100644 --- a/daemons/ipa-slapi-plugins/ipa-modrdn/modrdn-conf.ldif +++ b/daemons/ipa-slapi-plugins/ipa-modrdn/modrdn-conf.ldif @@ -6,7 +6,7 @@ objectclass: extensibleObject cn: IPA MODRDN nsslapd-pluginpath: libipa_modrdn nsslapd-plugininitfunc: ipamodrdn_init -nsslapd-plugintype: postoperation +nsslapd-plugintype: betxnpostoperation nsslapd-pluginenabled: on nsslapd-pluginid: ipamodrdn_version nsslapd-pluginversion: 1.0 diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c index f9cff70c..425b1c07 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipa_pwd_extop.c @@ -1270,6 +1270,15 @@ static char *ipapwd_name_list[] = { int ipapwd_init( Slapi_PBlock *pb ) { int ret; + Slapi_Entry *plugin_entry = NULL; + int is_betxn = 0; + + /* get args */ + if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) && + plugin_entry) { + is_betxn = slapi_entry_attr_get_bool(plugin_entry, + "nsslapd-pluginbetxn"); + } /* Get the arguments appended to the plugin extendedop directive. The first argument * (after the standard arguments for the directive) should contain the OID of the @@ -1301,6 +1310,18 @@ int ipapwd_init( Slapi_PBlock *pb ) return -1; } + if (is_betxn) { + slapi_register_plugin("betxnpreoperation", 1, + "ipapwd_pre_init_betxn", ipapwd_pre_init_betxn, + "IPA pwd pre ops betxn", NULL, + ipapwd_plugin_id); + + slapi_register_plugin("betxnpostoperation", 1, + "ipapwd_post_init_betxn", ipapwd_post_init_betxn, + "IPA pwd post ops betxn", NULL, + ipapwd_plugin_id); + } + slapi_register_plugin("preoperation", 1, "ipapwd_pre_init", ipapwd_pre_init, "IPA pwd pre ops", NULL, diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h index 0edd2dca..3689783c 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd.h @@ -152,4 +152,6 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg, int ipapwd_ext_init(void); int ipapwd_pre_init(Slapi_PBlock *pb); int ipapwd_post_init(Slapi_PBlock *pb); +int ipapwd_pre_init_betxn(Slapi_PBlock *pb); +int ipapwd_post_init_betxn(Slapi_PBlock *pb); diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c index e4909c94..0e4a63b4 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_prepost.c @@ -1307,6 +1307,19 @@ int ipapwd_pre_init(Slapi_PBlock *pb) return ret; } +int ipapwd_pre_init_betxn(Slapi_PBlock *pb) +{ + int ret; + + ret = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01); + if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&ipapwd_plugin_desc); + if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_BIND_FN, (void *)ipapwd_pre_bind); + if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN, (void *)ipapwd_pre_add); + if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN, (void *)ipapwd_pre_mod); + + return ret; +} + /* Init post ops */ int ipapwd_post_init(Slapi_PBlock *pb) { @@ -1320,3 +1333,14 @@ int ipapwd_post_init(Slapi_PBlock *pb) return ret; } +int ipapwd_post_init_betxn(Slapi_PBlock *pb) +{ + int ret; + + ret = slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01); + if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&ipapwd_plugin_desc); + if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_BE_TXN_POST_ADD_FN, (void *)ipapwd_post_op); + if (!ret) ret = slapi_pblock_set(pb, SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN, (void *)ipapwd_post_op); + + return ret; +} diff --git a/daemons/ipa-slapi-plugins/ipa-pwd-extop/pwd-extop-conf.ldif b/daemons/ipa-slapi-plugins/ipa-pwd-extop/pwd-extop-conf.ldif index e31a8e79..4d4e6e6b 100644 --- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/pwd-extop-conf.ldif +++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/pwd-extop-conf.ldif @@ -7,6 +7,7 @@ cn: ipa_pwd_extop nsslapd-pluginpath: libipa_pwd_extop nsslapd-plugininitfunc: ipapwd_init nsslapd-plugintype: extendedop +nsslapd-pluginbetxn: on nsslapd-pluginenabled: on nsslapd-pluginid: ipa_pwd_extop nsslapd-pluginversion: 1.0 diff --git a/freeipa.spec.in b/freeipa.spec.in index 3ab0e3d4..50e743d8 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -113,7 +113,7 @@ Requires(pre): systemd-units Requires(post): systemd-units Requires: selinux-policy >= 3.10.0-110 Requires(post): selinux-policy-base -Requires: slapi-nis >= 0.40 +Requires: slapi-nis >= 0.44 %if 0%{?fedora} >= 18 Requires: pki-ca >= 10.0.0-0.52.b3 Requires: dogtag-pki-server-theme @@ -733,6 +733,9 @@ fi %ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/ca.crt %changelog +* Fri Nov 16 2012 Rob Crittenden <rcritten@redhat.com> - 3.0.99-5 +- Bump minimum version of slapi-nis to 0.44 + * Wed Nov 14 2012 Martin Kosek <mkosek@redhat.com> - 3.0.99-4 - Remove compatibility definitions for unsupported Fedora versions (Fedora 16 and lower) - Do not require specific package version when the package was available in Fedora 17 diff --git a/install/share/nis.uldif b/install/share/nis.uldif index 1e548289..1735fb55 100644 --- a/install/share/nis.uldif +++ b/install/share/nis.uldif @@ -6,6 +6,7 @@ default:cn: NIS Server default:nsslapd-pluginpath: /usr/lib$LIBARCH/dirsrv/plugins/nisserver-plugin.so default:nsslapd-plugininitfunc: nis_plugin_init default:nsslapd-plugintype: object +default:nsslapd-pluginbetxn: on default:nsslapd-pluginenabled: on default:nsslapd-pluginid: nis-server default:nsslapd-pluginversion: 0.10 diff --git a/install/share/schema_compat.uldif b/install/share/schema_compat.uldif index deca1bb4..a93b3277 100644 --- a/install/share/schema_compat.uldif +++ b/install/share/schema_compat.uldif @@ -14,6 +14,7 @@ default:nsslapd-plugintype: object default:nsslapd-pluginenabled: on default:nsslapd-pluginid: schema-compat-plugin default:nsslapd-pluginversion: 0.8 +default:nsslapd-pluginbetxn: on default:nsslapd-pluginvendor: redhat.com default:nsslapd-plugindescription: Schema Compatibility Plugin diff --git a/install/tools/man/ipa-ldap-updater.1 b/install/tools/man/ipa-ldap-updater.1 index df8dfe65..37e200f5 100644 --- a/install/tools/man/ipa-ldap-updater.1 +++ b/install/tools/man/ipa-ldap-updater.1 @@ -37,6 +37,7 @@ There are 7 keywords: * add: add a value (or values) to an attribute * remove: remove a value (or values) from an attribute * only: set an attribute to this + * onlyifexist: set an attribute to this only if the entry exists * deleteentry: remove the entry * replace: replace an existing value, format is old: new * addifnew: add a new attribute and value only if the attribute doesn't already exist. Only works with single\-value attributes. diff --git a/install/ui/test/data/ipa_init.json b/install/ui/test/data/ipa_init.json index 41f2c627..44484a9a 100644 --- a/install/ui/test/data/ipa_init.json +++ b/install/ui/test/data/ipa_init.json @@ -738,7 +738,6 @@ "startup_traceback": false, "validate_api": false, "verbose": 0, - "wait_for_attr": false, "webui_assets_dir": null, "webui_prod": true, "xmlrpc_uri": "https://dev.example.com/ipa/xml" diff --git a/install/updates/10-disable-betxn.update b/install/updates/10-disable-betxn.update deleted file mode 100644 index 8fca4a5e..00000000 --- a/install/updates/10-disable-betxn.update +++ /dev/null @@ -1,37 +0,0 @@ -# Disable transactions in 389-ds-base - -dn: cn=7-bit check,cn=plugins,cn=config -only: nsslapd-pluginType: preoperation - -dn: cn=attribute uniqueness,cn=plugins,cn=config -only: nsslapd-pluginType: preoperation - -dn: cn=Auto Membership Plugin,cn=plugins,cn=config -only: nsslapd-pluginType: preoperation - -dn: cn=Linked Attributes,cn=plugins,cn=config -only: nsslapd-pluginType: preoperation - -dn: cn=Managed Entries,cn=plugins,cn=config -only: nsslapd-pluginType: preoperation - -dn: cn=MemberOf Plugin,cn=plugins,cn=config -only: nsslapd-pluginType: postoperation - -dn: cn=Multimaster Replication Plugin,cn=plugins,cn=config -only: nsslapd-pluginbetxn: off - -dn: cn=PAM Pass Through Auth,cn=plugins,cn=config -only: nsslapd-pluginType: preoperation - -dn: cn=referential integrity postoperation,cn=plugins,cn=config -only: nsslapd-pluginType: postoperation - -dn: cn=Roles Plugin,cn=plugins,cn=config -only: nsslapd-pluginbetxn: off - -dn: cn=State Change Plugin,cn=plugins,cn=config -only: nsslapd-pluginType: postoperation - -dn: cn=USN,cn=plugins,cn=config -only: nsslapd-pluginbetxn: off diff --git a/install/updates/10-enable-betxn.update b/install/updates/10-enable-betxn.update new file mode 100644 index 00000000..88f584cb --- /dev/null +++ b/install/updates/10-enable-betxn.update @@ -0,0 +1,49 @@ +# Enable transactions in 389-ds-base + +dn: cn=7-bit check,cn=plugins,cn=config +only: nsslapd-pluginType: betxnpreoperation + +dn: cn=attribute uniqueness,cn=plugins,cn=config +only: nsslapd-pluginType: betxnpreoperation + +dn: cn=Auto Membership Plugin,cn=plugins,cn=config +only: nsslapd-pluginType: betxnpreoperation + +dn: cn=Linked Attributes,cn=plugins,cn=config +only: nsslapd-pluginType: betxnpreoperation + +dn: cn=Managed Entries,cn=plugins,cn=config +only: nsslapd-pluginType: betxnpreoperation + +dn: cn=MemberOf Plugin,cn=plugins,cn=config +only: nsslapd-pluginType: betxnpostoperation + +dn: cn=Multimaster Replication Plugin,cn=plugins,cn=config +only: nsslapd-pluginbetxn: on + +dn: cn=PAM Pass Through Auth,cn=plugins,cn=config +only: nsslapd-pluginType: betxnpreoperation + +dn: cn=referential integrity postoperation,cn=plugins,cn=config +only: nsslapd-pluginType: betxnpostoperation + +dn: cn=Roles Plugin,cn=plugins,cn=config +only: nsslapd-pluginbetxn: on + +dn: cn=State Change Plugin,cn=plugins,cn=config +only: nsslapd-pluginType: betxnpostoperation + +dn: cn=USN,cn=plugins,cn=config +only: nsslapd-pluginbetxn: on + +dn: cn=IPA MODRDN,cn=plugins,cn=config +only: nsslapd-plugintype: betxnpostoperation + +dn: cn=ipa_pwd_extop,cn=plugins,cn=config +only: nsslapd-pluginbetxn: on + +dn: cn=Schema Compatibility, cn=plugins, cn=config +onlyifexist: nsslapd-pluginbetxn: on + +dn: cn=NIS Server, cn=plugins, cn=config +onlyifexist: nsslapd-pluginbetxn: on diff --git a/install/updates/55-pbacmemberof.update b/install/updates/55-pbacmemberof.update index bc17f566..f02b4f84 100644 --- a/install/updates/55-pbacmemberof.update +++ b/install/updates/55-pbacmemberof.update @@ -8,3 +8,11 @@ add: cn: IPA PBAC memberOf $TIME add: basedn: 'cn=privileges,cn=pbac,$SUFFIX' add: filter: (objectclass=*) add: ttl: 10 + +dn: cn=Update Role memberOf $TIME, cn=memberof task, cn=tasks, cn=config +add: objectClass: top +add: objectClass: extensibleObject +add: cn: Update Role memberOf $TIME +add: basedn: 'cn=roles,cn=accounts,$SUFFIX' +add: filter: (objectclass=*) +add: ttl: 10 diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am index a675af8b..2e4f0a26 100644 --- a/install/updates/Makefile.am +++ b/install/updates/Makefile.am @@ -7,7 +7,7 @@ app_DATA = \ 10-RFC2307bis.update \ 10-RFC4876.update \ 10-config.update \ - 10-disable-betxn.update \ + 10-enable-betxn.update \ 10-selinuxusermap.update \ 10-sudo.update \ 10-ssh.update \ diff --git a/ipa-client/man/default.conf.5 b/ipa-client/man/default.conf.5 index f779b51f..a0804e39 100644 --- a/ipa-client/man/default.conf.5 +++ b/ipa-client/man/default.conf.5 @@ -178,9 +178,6 @@ Used internally in the IPA source package to verify that the API has not changed .B verbose <boolean> When True provides more information. Specifically this sets the global log level to "info". .TP -.B wait_for_attr <boolean> -Debug option. Waits for asynchronous execution of 389-ds postoperation plugins before returning data to the client, therefore data added by postoperation plugins is included in the result. Increases execution time. -.TP .B xmlrpc_uri <URI> Specifies the URI of the XML\-RPC server for a client. This is used by IPA and some external tools as well, such as ipa\-getcert. e.g. https://ipa.example.com/ipa/xml .TP diff --git a/ipalib/constants.py b/ipalib/constants.py index 81db0202..bf49375c 100644 --- a/ipalib/constants.py +++ b/ipalib/constants.py @@ -157,7 +157,6 @@ DEFAULT_CONFIG = ( # Enable certain optional plugins: ('enable_ra', False), ('ra_plugin', 'selfsign'), - ('wait_for_attr', False), ('dogtag_version', 9), # Used when verifying that the API hasn't changed. Not for production. diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py index a55a2324..85e2bec3 100644 --- a/ipalib/plugins/baseldap.py +++ b/ipalib/plugins/baseldap.py @@ -231,50 +231,6 @@ def entry_from_entry(entry, newentry): for e in newentry: entry[e] = newentry[e] -def wait_for_memberof(keys, entry_start, completed, show_command, adding=True): - """ - When adding or removing reverse members we are faking an update to - object A by updating the member attribute in object B. The memberof - plugin makes this work by adding or removing the memberof attribute - to/from object A, it just takes a little bit of time. - - This will loop for 6+ seconds, retrieving object A so we can see - if all the memberof attributes have been updated. - """ - if completed == 0: - # nothing to do - return api.Command[show_command](keys[-1])['result'] - - if 'memberof' in entry_start: - starting_memberof = len(entry_start['memberof']) - else: - starting_memberof = 0 - - # Loop a few times to give the memberof plugin a chance to add the - # entries. Don't sleep for more than 6 seconds. - memberof = 0 - x = 0 - while x < 20: - # sleep first because the first search, even on a quiet system, - # almost always fails to have memberof set. - time.sleep(.3) - x = x + 1 - - # FIXME: put a try/except around here? I think it is probably better - # to just let the exception filter up to the caller. - entry_attrs = api.Command[show_command](keys[-1])['result'] - if 'memberof' in entry_attrs: - memberof = len(entry_attrs['memberof']) - - if adding: - if starting_memberof + completed >= memberof: - break - else: - if starting_memberof + completed <= memberof: - break - - return entry_attrs - def wait_for_value(ldap, dn, attr, value): """ 389-ds postoperation plugins are executed after the data has been @@ -2029,11 +1985,9 @@ class LDAPAddReverseMember(LDAPModReverseMember): except errors.PublicError, e: failed['member'][self.reverse_attr].append((attr, unicode(msg))) - # Wait for the memberof plugin to update the entry - try: - entry_attrs = wait_for_memberof(keys, entry_start, completed, self.show_command, adding=True) - except Exception, e: - raise errors.ReverseMemberError(verb=_('added'), exc=str(e)) + # Update the member data. + (dn, entry_attrs) = ldap.get_entry(dn, ['*']) + self.obj.convert_attribute_members(entry_attrs, *keys, **options) for callback in self.get_callbacks('post'): (completed, dn) = callback( @@ -2131,11 +2085,9 @@ class LDAPRemoveReverseMember(LDAPModReverseMember): except errors.PublicError, e: failed['member'][self.reverse_attr].append((attr, unicode(msg))) - # Wait for the memberof plugin to update the entry - try: - entry_attrs = wait_for_memberof(keys, entry_start, completed, self.show_command, adding=False) - except Exception, e: - raise errors.ReverseMemberError(verb=_('removed'), exc=str(e)) + # Update the member data. + (dn, entry_attrs) = ldap.get_entry(dn, ['*']) + self.obj.convert_attribute_members(entry_attrs, *keys, **options) for callback in self.get_callbacks('post'): (completed, dn) = callback( diff --git a/ipalib/plugins/permission.py b/ipalib/plugins/permission.py index 80c6bc06..1fbf9e01 100644 --- a/ipalib/plugins/permission.py +++ b/ipalib/plugins/permission.py @@ -115,6 +115,7 @@ class permission(LDAPObject): ] attribute_members = { 'member': ['privilege'], + 'memberindirect': ['role'], } rdn_is_primary_key = True diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py index 5d667dc9..80bdc39e 100644 --- a/ipalib/plugins/user.py +++ b/ipalib/plugins/user.py @@ -547,9 +547,6 @@ class user_add(LDAPCreate): except errors.AlreadyGroupMember: pass - if self.api.env.wait_for_attr: - newentry = wait_for_value(ldap, dn, 'memberOf', def_primary_group) - entry_from_entry(entry_attrs, newentry) self.obj._convert_manager(entry_attrs, **options) # delete description attribute NO_UPG_MAGIC if present if options.get('noprivate', False): @@ -563,10 +560,11 @@ class user_add(LDAPCreate): self.api.Command['user_mod'](keys[-1], **kw) except (errors.EmptyModlist, errors.NotFound): pass - else: - if self.api.env.wait_for_attr: - newentry = wait_for_value(ldap, dn, 'objectclass', 'mepOriginEntry') - entry_from_entry(entry_attrs, newentry) + + # Fetch the entry again to update memberof, mep data, etc updated + # at the end of the transaction. + (newdn, newentry) = ldap.get_entry(dn, ['*']) + entry_attrs.update(newentry) if options.get('random', False): try: diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index b48e7d76..fe42282d 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -202,7 +202,6 @@ class DsInstance(service.Service): self.step("configuring replication version plugin", self.__config_version_module) self.step("enabling IPA enrollment plugin", self.__add_enrollment_module) self.step("enabling ldapi", self.__enable_ldapi) - self.step("disabling betxn plugins", self.__disable_betxn) self.step("configuring uniqueness plugin", self.__set_unique_attrs) self.step("configuring uuid plugin", self.__config_uuid_module) self.step("configuring modrdn plugin", self.__config_modrdn_module) @@ -476,9 +475,6 @@ class DsInstance(service.Service): def __add_referint_module(self): self._ldap_mod("referint-conf.ldif") - def __disable_betxn(self): - self._ldap_mod("disable-betxn.ldif", self.sub_dict) - def __set_unique_attrs(self): self._ldap_mod("unique-attributes.ldif", self.sub_dict) diff --git a/ipaserver/install/ldapupdate.py b/ipaserver/install/ldapupdate.py index eb95858f..f7261adc 100644 --- a/ipaserver/install/ldapupdate.py +++ b/ipaserver/install/ldapupdate.py @@ -59,7 +59,7 @@ class BadSyntax(installutils.ScriptError): return repr(self.value) class LDAPUpdate: - action_keywords = ["default", "add", "remove", "only", "deleteentry", "replace", "addifnew", "addifexist"] + action_keywords = ["default", "add", "remove", "only", "onlyifexist", "deleteentry", "replace", "addifnew", "addifexist"] def __init__(self, dm_password, sub_dict={}, live_run=True, online=True, ldapi=False, plugins=False): @@ -623,6 +623,18 @@ class LDAPUpdate: only[attr] = True entry.setValues(attr, entry_values) self.debug('only: updated value %s', entry_values) + elif action == 'onlyifexist': + self.debug("onlyifexist: '%s' to %s, current value %s", update_value, attr, entry_values) + # Only set the attribute if the entry exist's. We + # determine this based on whether it has an objectclass + if entry.getValues('objectclass'): + if only.get(attr): + entry_values.append(update_value) + else: + entry_values = [update_value] + only[attr] = True + self.debug('onlyifexist: set %s to %s', attr, entry_values) + entry.setValues(attr, entry_values) elif action == 'deleteentry': # skip this update type, it occurs in __delete_entries() return None diff --git a/tests/test_xmlrpc/test_automember_plugin.py b/tests/test_xmlrpc/test_automember_plugin.py index fcd9facb..fdf3c73a 100644 --- a/tests/test_xmlrpc/test_automember_plugin.py +++ b/tests/test_xmlrpc/test_automember_plugin.py @@ -886,6 +886,8 @@ class test_automember(Declarative): objectclass=objectclasses.host, ipauniqueid=[fuzzy_uuid], managedby_host=[fqdn1], + memberof_hostgroup=[hostgroup1], + memberofindirect_netgroup=[hostgroup1], ), ), ), @@ -914,6 +916,8 @@ class test_automember(Declarative): objectclass=objectclasses.host, ipauniqueid=[fuzzy_uuid], managedby_host=[fqdn2], + memberof_hostgroup=[defaulthostgroup1], + memberofindirect_netgroup=[defaulthostgroup1], ), ), ), @@ -942,6 +946,8 @@ class test_automember(Declarative): objectclass=objectclasses.host, ipauniqueid=[fuzzy_uuid], managedby_host=[fqdn3], + memberof_hostgroup=[hostgroup2], + memberofindirect_netgroup=[hostgroup2], ), ), ), @@ -970,6 +976,8 @@ class test_automember(Declarative): objectclass=objectclasses.host, ipauniqueid=[fuzzy_uuid], managedby_host=[fqdn4], + memberof_hostgroup=[hostgroup3], + memberofindirect_netgroup=[hostgroup3], ), ), ), @@ -998,6 +1006,8 @@ class test_automember(Declarative): objectclass=objectclasses.host, ipauniqueid=[fuzzy_uuid], managedby_host=[fqdn5], + memberof_hostgroup=[hostgroup4], + memberofindirect_netgroup=[hostgroup4], ), ), ), diff --git a/tests/test_xmlrpc/test_nesting.py b/tests/test_xmlrpc/test_nesting.py index 6af9c9d2..a09a7989 100644 --- a/tests/test_xmlrpc/test_nesting.py +++ b/tests/test_xmlrpc/test_nesting.py @@ -750,6 +750,7 @@ class test_nesting(Declarative): 'cn': [hostgroup1], 'description': [u'Test hostgroup 1'], 'member_hostgroup': [hostgroup2], + 'memberindirect_host': [fqdn1], }, ), ), diff --git a/tests/test_xmlrpc/test_permission_plugin.py b/tests/test_xmlrpc/test_permission_plugin.py index eda96d0e..4fe1eef4 100644 --- a/tests/test_xmlrpc/test_permission_plugin.py +++ b/tests/test_xmlrpc/test_permission_plugin.py @@ -194,6 +194,7 @@ class test_permission(Declarative): 'cn': [privilege1], 'description': [u'privilege desc. 1'], 'memberof_permission': [permission1], + 'objectclass': objectclasses.privilege, } ), ), @@ -501,10 +502,10 @@ class test_permission(Declarative): api.env.container_permission, api.env.basedn), 'cn': [u'Modify HBAC rule'], 'member_privilege': [u'HBAC Administrator'], + 'memberindirect_role': [u'IT Security Specialist'], 'permissions' : [u'write'], 'attrs': [u'servicecategory', u'sourcehostcategory', u'cn', u'description', u'ipaenabledflag', u'accesstime', u'usercategory', u'hostcategory', u'accessruletype', u'sourcehost'], 'subtree' : u'ldap:///%s' % DN(('ipauniqueid', '*'), ('cn', 'hbac'), api.env.basedn), - 'memberindirect': [DN(('cn', 'it security specialist'), ('cn', 'roles'), ('cn', 'accounts'), api.env.basedn)], }, ], ), diff --git a/tests/test_xmlrpc/test_privilege_plugin.py b/tests/test_xmlrpc/test_privilege_plugin.py index d4784af8..81e51d5e 100644 --- a/tests/test_xmlrpc/test_privilege_plugin.py +++ b/tests/test_xmlrpc/test_privilege_plugin.py @@ -142,6 +142,7 @@ class test_privilege(Declarative): 'cn': [privilege1], 'description': [u'privilege desc. 1'], 'memberof_permission': [permission1], + 'objectclass': objectclasses.privilege, } ), ), @@ -240,6 +241,7 @@ class test_privilege(Declarative): 'cn': [privilege1], 'description': [u'privilege desc. 1'], 'memberof_permission': [permission1, permission2], + 'objectclass': objectclasses.privilege, } ), ), @@ -262,6 +264,7 @@ class test_privilege(Declarative): 'cn': [privilege1], 'description': [u'privilege desc. 1'], 'memberof_permission': [permission1, permission2], + 'objectclass': objectclasses.privilege, } ), ), @@ -320,6 +323,7 @@ class test_privilege(Declarative): 'cn': [privilege1], 'description': [u'New desc 1'], 'memberof_permission': [permission2], + 'objectclass': objectclasses.privilege, } ), ), @@ -342,6 +346,7 @@ class test_privilege(Declarative): 'cn': [privilege1], 'description': [u'New desc 1'], 'memberof_permission': [permission2], + 'objectclass': objectclasses.privilege, } ), ), @@ -364,6 +369,7 @@ class test_privilege(Declarative): 'cn': [privilege1], 'description': [u'New desc 1'], 'memberof_permission': [permission2], + 'objectclass': objectclasses.privilege, } ), ), @@ -386,6 +392,7 @@ class test_privilege(Declarative): 'cn': [privilege1], 'description': [u'New desc 1'], 'memberof_permission': [permission2], + 'objectclass': objectclasses.privilege, } ), ), diff --git a/tests/test_xmlrpc/test_role_plugin.py b/tests/test_xmlrpc/test_role_plugin.py index b847ca9e..be3feceb 100644 --- a/tests/test_xmlrpc/test_role_plugin.py +++ b/tests/test_xmlrpc/test_role_plugin.py @@ -196,6 +196,7 @@ class test_role(Declarative): 'cn': [role1], 'description': [u'role desc 1'], 'memberof_privilege': [privilege1], + 'objectclass': objectclasses.role, } ), ), @@ -217,6 +218,7 @@ class test_role(Declarative): 'cn': [role1], 'description': [u'role desc 1'], 'memberof_privilege': [privilege1], + 'objectclass': objectclasses.role, } ), ), @@ -238,6 +240,7 @@ class test_role(Declarative): 'cn': [role1], 'description': [u'role desc 1'], 'memberof_privilege': [privilege1], + 'objectclass': objectclasses.role, } ), ), @@ -518,6 +521,7 @@ class test_role(Declarative): 'dn': role1_dn, 'cn': [role1], 'description': [u'New desc 1'], + 'objectclass': objectclasses.role, } ), ), @@ -539,6 +543,7 @@ class test_role(Declarative): 'dn': role1_dn, 'cn': [role1], 'description': [u'New desc 1'], + 'objectclass': objectclasses.role, } ), ), |