Hi, this fixes https://fedorahosted.org/freeipa/ticket/5319.
Details in the commit messages. Tomas
From 7daf849d776696575f9ce7a374995845616341b8 Mon Sep 17 00:00:00 2001 From: Tomas Babej <tba...@redhat.com> Date: Wed, 23 Sep 2015 13:27:35 +0200 Subject: [PATCH] winsync-migrate: Convert entity names to posix friendly strings During the migration from winsync replicated users to their trusted identities, memberships are being preserved. However, trusted users are external and as such cannot be added as direct members to the IPA entities. External groups which encapsulate the migrated users are added as members to those entities instead. The name of the external group is generated from the type of the entity and its name. However, the entity's name can contain characters which are invalid for use in the group name. Adds a helper function to convert a given string to a string which would be valid for such use and leverages it in the winsync-migrate tool. https://fedorahosted.org/freeipa/ticket/5319 --- ipapython/ipautil.py | 23 +++++++++++++++++++++++ ipaserver/install/ipa_winsync_migrate.py | 15 ++++++++++++--- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py index 2402689ccc1980117166969944e09e1ab5063ec2..573e6040c167ab8e10290cf3924d27cb102aa623 100644 --- a/ipapython/ipautil.py +++ b/ipapython/ipautil.py @@ -1330,6 +1330,29 @@ def restore_hostname(statestore): except CalledProcessError as e: print("Failed to set this machine hostname back to %s: %s" % (old_hostname, str(e)), file=sys.stderr) +def posixify(string): + """ + Convert a string to a more strict alpha-numeric representation. + + - Alpha-numeric, underscore, dot and dash characters are accepted + - Space is converted to underscore + - Other characters are omitted + - Leading dash is stripped + + Note: This mapping is not one-to-one and may map different input to the + same result. When using posixify, make sure the you do not map two different + entities to one unintentionally. + """ + + def valid_char(char): + return char.isalnum() or char in ('_', '.', '-') + + # First replace space characters + replaced = string.replace(' ','_') + omitted = ''.join(filter(valid_char, replaced)) + + # Leading dash is not allowed + return omitted.lstrip('-') @contextmanager def private_ccache(path=None): diff --git a/ipaserver/install/ipa_winsync_migrate.py b/ipaserver/install/ipa_winsync_migrate.py index cafec9d188dbf2f1be07edea031d76f5e88dccbf..d0c6cc80c6e5c4455afe506a568cd5bf68975215 100644 --- a/ipaserver/install/ipa_winsync_migrate.py +++ b/ipaserver/install/ipa_winsync_migrate.py @@ -26,7 +26,7 @@ from ipalib import api from ipalib import errors from ipapython import admintool from ipapython.dn import DN -from ipapython.ipautil import realm_to_suffix +from ipapython.ipautil import realm_to_suffix, posixify from ipapython.ipa_log_manager import log_mgr from ipaserver.plugins.ldap2 import ldap2 from ipaserver.install import replication @@ -219,12 +219,21 @@ class WinsyncMigrate(admintool.AdminTool): def winsync_group_name(object_entry): """ - Returns the generated name of group containing migrated external users + Returns the generated name of group containing migrated external + users. + + The group name is of the form: + "<prefix>_<object name>_winsync_external" + + Object name is converted to posix-friendly string by omitting + and/or replacing characters. This may lead to collisions, i.e. + if both 'trust_admins' and 'trust admin' groups have winsync + users being migrated. """ return u"{0}_{1}_winsync_external".format( winsync_group_prefix, - object_entry['cn'][0] + posixify(object_entry['cn'][0]) ) def create_winsync_group(object_entry): -- 2.1.0
From 058723703ccf39e32c187d920b8d4e5f0c02e785 Mon Sep 17 00:00:00 2001 From: Tomas Babej <tba...@redhat.com> Date: Wed, 23 Sep 2015 13:28:33 +0200 Subject: [PATCH] winsync-migrate: Properly handle collisions in the names of external groups Since the names of the external groups containing the migrated users must be stripped of characters which are not valid for use in group names, two different groups might be mapped to one during this process. Properly handle collisions in the names by adding an incremental numeric suffix. https://fedorahosted.org/freeipa/ticket/5319 --- ipaserver/install/ipa_winsync_migrate.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/ipaserver/install/ipa_winsync_migrate.py b/ipaserver/install/ipa_winsync_migrate.py index d0c6cc80c6e5c4455afe506a568cd5bf68975215..87e23fb3698bac0a0371a198d95994ed921ee011 100644 --- a/ipaserver/install/ipa_winsync_migrate.py +++ b/ipaserver/install/ipa_winsync_migrate.py @@ -236,15 +236,26 @@ class WinsyncMigrate(admintool.AdminTool): posixify(object_entry['cn'][0]) ) - def create_winsync_group(object_entry): + def create_winsync_group(object_entry, suffix=0): """ Creates the group containing migrated external users that were previously available via winsync. """ name = winsync_group_name(object_entry) - api.Command['group_add'](name, external=True) - api.Command[object_membership_command](object_entry['cn'][0], group=[name]) + + # Only non-trivial suffix is appended at the end + if suffix != 0: + name += str(suffix) + + try: + api.Command['group_add'](name, external=True) + except errors.DuplicateEntry: + # If there is a collision, let's try again with a higher suffix + create_winsync_group(object_entry, suffix=suffix+1) + else: + # In case of no collision, add the membership + api.Command[object_membership_command](object_entry['cn'][0], group=[name]) # Search for all objects containing the given user as a direct member member_filter = self.ldap.make_filter_from_attr(user_dn_attribute, -- 2.1.0
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code