On 09/23/2015 04:56 PM, Jan Cholasta wrote:
On 23.9.2015 16:52, Martin Babinsky wrote:
On 09/23/2015 01:39 PM, Tomas Babej wrote:
Hi,

this fixes https://fedorahosted.org/freeipa/ticket/5319.

Details in the commit messages.

Tomas



ACK


The patches need to be rebased on top of ipa-4-2.


Attaching rebased patches on Tomas's behalf.

--
Martin^3 Babinsky
From b09a852446309c794fadb2a300194bc57c4cbe8c Mon Sep 17 00:00:00 2001
From: Tomas Babej <tba...@redhat.com>
Date: Wed, 23 Sep 2015 13:28:33 +0200
Subject: [PATCH 2/2] 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 4dacde3f27ead341fd4d7d2a744d28f74d5c5b95..13c5ddef383204451cbc4bb662c8a1befc1d5f93 100644
--- a/ipaserver/install/ipa_winsync_migrate.py
+++ b/ipaserver/install/ipa_winsync_migrate.py
@@ -231,15 +231,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.4.3

From eb59d73f459775f0677fde20adecf2ec22aa0058 Mon Sep 17 00:00:00 2001
From: Tomas Babej <tba...@redhat.com>
Date: Wed, 23 Sep 2015 13:27:35 +0200
Subject: [PATCH 1/2] 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 88e89706b8e2aa6dea80809510d88bceaa836e85..64fe9bc27e58c8ecfcfabe69690db0493a10c3b1 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -1318,6 +1318,29 @@ def restore_hostname(statestore):
         except CalledProcessError, e:
             print >>sys.stderr, "Failed to set this machine hostname back to %s: %s" % (old_hostname, str(e))
 
+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 c327e502e6bfb6e402931e1962fe2410570b2bc2..4dacde3f27ead341fd4d7d2a744d28f74d5c5b95 100644
--- a/ipaserver/install/ipa_winsync_migrate.py
+++ b/ipaserver/install/ipa_winsync_migrate.py
@@ -24,7 +24,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
@@ -214,12 +214,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.4.3

-- 
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

Reply via email to