Re: [Freeipa-devel] [PATCH] Make the migration plugin more configurable

2010-12-07 Thread Rob Crittenden

Jakub Hrozek wrote:

On Wed, Nov 24, 2010 at 04:54:19PM -0500, Rob Crittenden wrote:

Jakub Hrozek wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 11/22/2010 04:21 PM, Jakub Hrozek wrote:

On 11/22/2010 04:16 PM, Jakub Hrozek wrote:

The code handles it (I just ran a quick test with --schema=RFC2307bis).



It just iterates through all members of a group -- be it user member of
group member, it's just a DN for the plugin.



Jakub


Sorry, I found another bug in the plugin. I'll send a new patch shortly,
so please don't waste time reviewing this one.


New patch is attached. It fixes two more bugs of the original plugin -
determines whether a group member is a user or a nested group by
checking the DN, not just the RDN attribute name and does not hardcode
primary keys.


Will this blow up in convert_members_rfc2307bis() if a member isn't
contained in the users and groups containers? Should there be a
failsafe to skip over things that don't match (along with
appropriate reporting)?


It wouldn't blow up but add the original DN into the member attribute
which is probably worse. Thanks for catching this. I modified the patch
to log all migrated users and groups with info() and skip those that
don't match any of the containers while logging these entries with
error().


Or if one of users or groups search bases
isn't provided?



If one of them isn't provided, a default would be used.


It definitely doesn't like this:
# ipa migrate-ds --user-container=''
--group-container='cn=groups,cn=accounts' ldap://ds.example.com:389

When passed the right set of options it does seem to do the right thing.



Sorry, but I don't quite understand the --user-container='' switch.
Does it mean the users are rooted at the Base DN? Can you post the error
or relevant log info? Please note that the default objectclass is
person.


The empty user-container isn't related to this patch so ACK, pushed to 
master.


The error I'm seeing in the Apache error log is:


[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] Traceback 
(most recent call last):
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/share/ipa/wsgi.py, line 27, in application
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] return 
api.Backend.session(environ, start_response)
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/lib/python2.6/site-packages/ipaserver/rpcserver.py, line 142, in 
__call__
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] return 
self.route(environ, start_response)
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/lib/python2.6/site-packages/ipaserver/rpcserver.py, line 154, in 
route
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] return 
app(environ, start_response)
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/lib/python2.6/site-packages/ipaserver/rpcserver.py, line 234, in 
__call__
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] response 
= self.wsgi_execute(environ)
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/lib/python2.6/site-packages/ipaserver/rpcserver.py, line 211, in 
wsgi_execute
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] result = 
self.Command[name](*args, **options)
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/lib/python2.6/site-packages/ipalib/frontend.py, line 417, in __call__
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] ret = 
self.run(*args, **options)
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/lib/python2.6/site-packages/ipalib/frontend.py, line 690, in run
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] return 
self.execute(*args, **options)
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/lib/python2.6/site-packages/ipalib/plugins/migration.py, line 
380, in execute
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] ldap, 
config, ds_ldap, ds_base_dn, options
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/lib/python2.6/site-packages/ipalib/plugins/migration.py, line 
300, in migrate
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] 
search_filter, ['*'], search_base, ds_ldap.SCOPE_ONELEVEL#,
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/lib/python2.6/site-packages/ipalib/encoder.py, line 188, in new_f
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] return 
f(*new_args, **kwargs)
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/lib/python2.6/site-packages/ipalib/encoder.py, line 199, in new_f
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32] return 
args[0].decode(f(*args, **kwargs))
[Tue Dec 07 10:38:10 2010] [error] [client 192.168.166.32]   File 
/usr/lib/python2.6/site-packages/ipaserver/plugins/ldap2.py, line 516, 
in find_entries
[Tue Dec 07 10:38:10 2010] [error] 

Re: [Freeipa-devel] [PATCH] Make the migration plugin more configurable

2010-12-01 Thread Jakub Hrozek
On Wed, Nov 24, 2010 at 04:54:19PM -0500, Rob Crittenden wrote:
 Jakub Hrozek wrote:
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 On 11/22/2010 04:21 PM, Jakub Hrozek wrote:
 On 11/22/2010 04:16 PM, Jakub Hrozek wrote:
 The code handles it (I just ran a quick test with --schema=RFC2307bis).
 
 It just iterates through all members of a group -- be it user member of
 group member, it's just a DN for the plugin.
 
Jakub
 
 Sorry, I found another bug in the plugin. I'll send a new patch shortly,
 so please don't waste time reviewing this one.
 
 New patch is attached. It fixes two more bugs of the original plugin -
 determines whether a group member is a user or a nested group by
 checking the DN, not just the RDN attribute name and does not hardcode
 primary keys.
 
 Will this blow up in convert_members_rfc2307bis() if a member isn't
 contained in the users and groups containers? Should there be a
 failsafe to skip over things that don't match (along with
 appropriate reporting)?

It wouldn't blow up but add the original DN into the member attribute
which is probably worse. Thanks for catching this. I modified the patch
to log all migrated users and groups with info() and skip those that
don't match any of the containers while logging these entries with
error().

 Or if one of users or groups search bases
 isn't provided?
 

If one of them isn't provided, a default would be used.

 It definitely doesn't like this:
 # ipa migrate-ds --user-container=''
 --group-container='cn=groups,cn=accounts' ldap://ds.example.com:389
 
 When passed the right set of options it does seem to do the right thing.
 

Sorry, but I don't quite understand the --user-container='' switch.
Does it mean the users are rooted at the Base DN? Can you post the error
or relevant log info? Please note that the default objectclass is
person.
From 1b0f43c4449bd26ffe6c57a594f3eaf367cda2c4 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek jhro...@redhat.com
Date: Tue, 26 Oct 2010 16:10:42 -0400
Subject: [PATCH] Make the migration plugin more configurable

This patch adds new options to the migration plugin:
 * the option to fine-tune the objectclass of users or groups being imported
 * the option to select the LDAP schema (RFC2307 or RFC2307bis)

Also makes the logic that decides whether an entry is a nested group or user
(for RFC2307bis) smarter by looking at the DNS. Does not hardcode primary keys
for migrated entries.

https://fedorahosted.org/freeipa/ticket/429
---
 ipalib/plugins/migration.py |  136 ++-
 1 files changed, 108 insertions(+), 28 deletions(-)

diff --git a/ipalib/plugins/migration.py b/ipalib/plugins/migration.py
index 6dc9934..213c0ee 100644
--- a/ipalib/plugins/migration.py
+++ b/ipalib/plugins/migration.py
@@ -26,9 +26,10 @@ Example: Migrate users and groups from DS to IPA
 
 import logging
 import re
+import ldap as _ldap
 
 from ipalib import api, errors, output
-from ipalib import Command, List, Password, Str, Flag
+from ipalib import Command, List, Password, Str, Flag, StrEnum
 from ipalib.cli import to_cli
 if api.env.in_server and api.env.context in ['lite', 'server']:
 try:
@@ -44,8 +45,10 @@ from ipalib.text import Gettext # FIXME: remove once the 
other Gettext FIXME is
 _krb_err_msg = _('Kerberos principal %s already exists. Use \'ipa user-mod\' 
to set it manually.')
 _grp_err_msg = _('Failed to add user to the default group. Use \'ipa 
group-add-member\' to add manually.')
 
+_supported_schemas = (u'RFC2307bis', u'RFC2307')
 
-def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx):
+
+def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, 
**kwargs):
 # get default primary group for new users
 if 'def_group_dn' not in ctx:
 def_group = config.get('ipadefaultprimarygroup')
@@ -90,37 +93,80 @@ def _post_migrate_user(ldap, pkey, dn, entry_attrs, failed, 
config, ctx):
 
 # GROUP MIGRATION CALLBACKS AND VARS
 
-def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx):
-def convert_members(member_attr, overwrite=False):
+def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx, 
**kwargs):
+def convert_members_rfc2307bis(member_attr, search_bases, overwrite=False):
 
 Convert DNs in member attributes to work in IPA.
 
 new_members = []
 entry_attrs.setdefault(member_attr, [])
 for m in entry_attrs[member_attr]:
-col = m.find(',')
-if col == -1:
+try:
+# what str2dn returns looks like [[('cn', 'foo', 4)], [('dc', 
'example', 1)], [('dc', 'com', 1)]]
+rdn = _ldap.dn.str2dn(m ,flags=_ldap.DN_FORMAT_LDAPV3)[0]
+rdnval = rdn[0][1]
+except IndexError:
+api.log.error('Malformed DN %s has no RDN?' % m)
+continue
+
+if m.lower().endswith(search_bases['user']):
+api.log.info('migrating user 

Re: [Freeipa-devel] [PATCH] Make the migration plugin more configurable

2010-11-24 Thread Jakub Hrozek
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 11/22/2010 04:21 PM, Jakub Hrozek wrote:
 On 11/22/2010 04:16 PM, Jakub Hrozek wrote:
 The code handles it (I just ran a quick test with --schema=RFC2307bis).
 
 It just iterates through all members of a group -- be it user member of
 group member, it's just a DN for the plugin.
 
  Jakub
 
 Sorry, I found another bug in the plugin. I'll send a new patch shortly,
 so please don't waste time reviewing this one.

New patch is attached. It fixes two more bugs of the original plugin -
determines whether a group member is a user or a nested group by
checking the DN, not just the RDN attribute name and does not hardcode
primary keys.
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAkztK7sACgkQHsardTLnvCUdewCdECJneAALtFoe80bWgZqMUHJ2
FjIAn05ld9VSNwe8Xmhi7Y8R3g3Af/av
=ZInN
-END PGP SIGNATURE-
From 7a12a608e5fee82713af6c9c318dbf6b3e98ef83 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek jhro...@redhat.com
Date: Tue, 26 Oct 2010 16:10:42 -0400
Subject: [PATCH] Make the migration plugin more configurable

This patch adds new options to the migration plugin:
 * the option to fine-tune the objectclass of users or groups being imported
 * the option to select the LDAP schema (RFC2307 or RFC2307bis)

Also makes the logic that decides whether an entry is a nested group or user
(for RFC2307bis) smarter by looking at the DNS. Does not hardcode primary keys
for migrated entries.

https://fedorahosted.org/freeipa/ticket/429
---
 ipalib/plugins/migration.py |  131 +--
 1 files changed, 102 insertions(+), 29 deletions(-)

diff --git a/ipalib/plugins/migration.py b/ipalib/plugins/migration.py
index 6dc9934..48c8fa2 100644
--- a/ipalib/plugins/migration.py
+++ b/ipalib/plugins/migration.py
@@ -26,9 +26,10 @@ Example: Migrate users and groups from DS to IPA
 
 import logging
 import re
+import ldap as _ldap
 
 from ipalib import api, errors, output
-from ipalib import Command, List, Password, Str, Flag
+from ipalib import Command, List, Password, Str, Flag, StrEnum
 from ipalib.cli import to_cli
 if api.env.in_server and api.env.context in ['lite', 'server']:
 try:
@@ -44,8 +45,10 @@ from ipalib.text import Gettext # FIXME: remove once the other Gettext FIXME is
 _krb_err_msg = _('Kerberos principal %s already exists. Use \'ipa user-mod\' to set it manually.')
 _grp_err_msg = _('Failed to add user to the default group. Use \'ipa group-add-member\' to add manually.')
 
+_supported_schemas = (u'RFC2307bis', u'RFC2307')
 
-def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx):
+
+def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs):
 # get default primary group for new users
 if 'def_group_dn' not in ctx:
 def_group = config.get('ipadefaultprimarygroup')
@@ -90,21 +93,30 @@ def _post_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx):
 
 # GROUP MIGRATION CALLBACKS AND VARS
 
-def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx):
-def convert_members(member_attr, overwrite=False):
+def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx, **kwargs):
+def convert_members_rfc2307bis(member_attr, search_bases, overwrite=False):
 
 Convert DNs in member attributes to work in IPA.
 
 new_members = []
 entry_attrs.setdefault(member_attr, [])
 for m in entry_attrs[member_attr]:
-col = m.find(',')
-if col == -1:
-continue
-if m.startswith('uid'):
-m = '%s,%s' % (m[0:col], api.env.container_user)
-elif m.startswith('cn'):
-m = '%s,%s' % (m[0:col], api.env.container_group)
+try:
+# what str2dn returns looks like [[('cn', 'foo', 4)], [('dc', 'example', 1)], [('dc', 'com', 1)]]
+rdn = _ldap.dn.str2dn(m ,flags=_ldap.DN_FORMAT_LDAPV3)[0]
+rdnval = rdn[0][1]
+except IndexError:
+raise ValueError('Malformed DN %s has no RDN?' % m)
+
+if m.lower().endswith(search_bases['user']):
+m = '%s=%s,%s' % (api.Object.user.primary_key.name,
+  rdnval,
+  api.env.container_user)
+elif m.lower().endswith(search_bases['group']):
+m = '%s=%s,%s' % (api.Object.group.primary_key.name,
+  rdnval,
+  api.env.container_group)
+
 m = ldap.normalize_dn(m)
 new_members.append(m)
 del entry_attrs[member_attr]
@@ -112,15 +124,42 @@ def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx):
 entry_attrs['member'] = []
 entry_attrs['member'] += new_members
 
+def 

Re: [Freeipa-devel] [PATCH] Make the migration plugin more configurable

2010-11-24 Thread Rob Crittenden

Jakub Hrozek wrote:

-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 11/22/2010 04:21 PM, Jakub Hrozek wrote:

On 11/22/2010 04:16 PM, Jakub Hrozek wrote:

The code handles it (I just ran a quick test with --schema=RFC2307bis).



It just iterates through all members of a group -- be it user member of
group member, it's just a DN for the plugin.



Jakub


Sorry, I found another bug in the plugin. I'll send a new patch shortly,
so please don't waste time reviewing this one.


New patch is attached. It fixes two more bugs of the original plugin -
determines whether a group member is a user or a nested group by
checking the DN, not just the RDN attribute name and does not hardcode
primary keys.


Will this blow up in convert_members_rfc2307bis() if a member isn't 
contained in the users and groups containers? Should there be a failsafe 
to skip over things that don't match (along with appropriate reporting)? 
Or if one of users or groups search bases isn't provided?


It definitely doesn't like this:
# ipa migrate-ds --user-container='' 
--group-container='cn=groups,cn=accounts' ldap://ds.example.com:389


When passed the right set of options it does seem to do the right thing.

rob

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


Re: [Freeipa-devel] [PATCH] Make the migration plugin more configurable

2010-11-22 Thread Jakub Hrozek
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 11/19/2010 08:17 PM, Rob Crittenden wrote:
 Jakub Hrozek wrote:
 This patch adds new options to the migration plugin:
   * the option to fine-tune the objectclass of users or groups being
   * imported
   * the option to select the LDAP schema (RFC2307 or RFC2307bis)

 https://fedorahosted.org/freeipa/ticket/429
 
 I don't see where the RFC 2307bis case handles nested groups. This
 should be supported, right?
 
 rob
 

The code handles it (I just ran a quick test with --schema=RFC2307bis).

It just iterates through all members of a group -- be it user member of
group member, it's just a DN for the plugin.

Jakub
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAkzqiVMACgkQHsardTLnvCWLFwCcD4GUp4RVUVoTzElVuHqayJOw
Vq8An0tRSltlWh3Y2V92eWhyLsQwVwip
=RITJ
-END PGP SIGNATURE-

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


Re: [Freeipa-devel] [PATCH] Make the migration plugin more configurable

2010-11-19 Thread Dmitri Pal
Rob Crittenden wrote:
 Jakub Hrozek wrote:
 This patch adds new options to the migration plugin:
   * the option to fine-tune the objectclass of users or groups being
   * imported
   * the option to select the LDAP schema (RFC2307 or RFC2307bis)

 https://fedorahosted.org/freeipa/ticket/429

 I don't see where the RFC 2307bis case handles nested groups. This
 should be supported, right?


I think Jakub refers to memberUid vs. member attribute.

 rob

 ___
 Freeipa-devel mailing list
 Freeipa-devel@redhat.com
 https://www.redhat.com/mailman/listinfo/freeipa-devel




-- 
Thank you,
Dmitri Pal

Sr. Engineering Manager IPA project,
Red Hat Inc.


---
Looking to carve out IT costs?
www.redhat.com/carveoutcosts/

___
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel


[Freeipa-devel] [PATCH] Make the migration plugin more configurable

2010-11-15 Thread Jakub Hrozek
This patch adds new options to the migration plugin:
 * the option to fine-tune the objectclass of users or groups being
 * imported
 * the option to select the LDAP schema (RFC2307 or RFC2307bis)

https://fedorahosted.org/freeipa/ticket/429
From 88165ff6ea2d889150e8bdc882a7b6bec1ab0519 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek jhro...@redhat.com
Date: Tue, 26 Oct 2010 16:10:42 -0400
Subject: [PATCH] Make the migration plugin more configurable

This patch adds new options to the migration plugin:
 * the option to fine-tune the objectclass of users or groups being imported
 * the option to select the LDAP schema (RFC2307 or RFC2307bis)

https://fedorahosted.org/freeipa/ticket/429
---
 ipalib/plugins/migration.py |   86 ++-
 1 files changed, 68 insertions(+), 18 deletions(-)

diff --git a/ipalib/plugins/migration.py b/ipalib/plugins/migration.py
index 6dc9934..81e35e2 100644
--- a/ipalib/plugins/migration.py
+++ b/ipalib/plugins/migration.py
@@ -28,7 +28,7 @@ import logging
 import re
 
 from ipalib import api, errors, output
-from ipalib import Command, List, Password, Str, Flag
+from ipalib import Command, List, Password, Str, Flag, StrEnum
 from ipalib.cli import to_cli
 if api.env.in_server and api.env.context in ['lite', 'server']:
 try:
@@ -44,8 +44,10 @@ from ipalib.text import Gettext # FIXME: remove once the 
other Gettext FIXME is
 _krb_err_msg = _('Kerberos principal %s already exists. Use \'ipa user-mod\' 
to set it manually.')
 _grp_err_msg = _('Failed to add user to the default group. Use \'ipa 
group-add-member\' to add manually.')
 
+_supported_schemas = (u'RFC2307bis', u'RFC2307')
 
-def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx):
+
+def _pre_migrate_user(ldap, pkey, dn, entry_attrs, failed, config, ctx, 
**kwargs):
 # get default primary group for new users
 if 'def_group_dn' not in ctx:
 def_group = config.get('ipadefaultprimarygroup')
@@ -90,8 +92,8 @@ def _post_migrate_user(ldap, pkey, dn, entry_attrs, failed, 
config, ctx):
 
 # GROUP MIGRATION CALLBACKS AND VARS
 
-def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx):
-def convert_members(member_attr, overwrite=False):
+def _pre_migrate_group(ldap, pkey, dn, entry_attrs, failed, config, ctx, 
**kwargs):
+def convert_members_rfc2307bis(member_attr, overwrite=False):
 
 Convert DNs in member attributes to work in IPA.
 
@@ -112,15 +114,36 @@ def _pre_migrate_group(ldap, pkey, dn, entry_attrs, 
failed, config, ctx):
 entry_attrs['member'] = []
 entry_attrs['member'] += new_members
 
+def convert_members_rfc2307(member_attr):
+
+Convert usernames in member attributes to work in IPA.
+
+new_members = []
+entry_attrs.setdefault(member_attr, [])
+for m in entry_attrs[member_attr]:
+memberdn = 'uid=%s,%s' % (m, api.env.container_user)
+new_members.append(ldap.normalize_dn(memberdn))
+entry_attrs['member'] = new_members
+
+schema = kwargs.get('schema', None)
 entry_attrs['ipauniqueid'] = 'autogenerate'
-convert_members('member', overwrite=True)
-convert_members('uniquemember')
+if schema == 'RFC2307bis':
+convert_members_rfc2307bis('member', overwrite=True)
+convert_members_rfc2307bis('uniquemember')
+elif schema == 'RFC2307':
+convert_members_rfc2307('memberuid')
+else:
+raise ValueError('Schema %s not supported' % schema)
 
 return dn
 
 
 # DS MIGRATION PLUGIN
 
+def construct_filter(template, oc_list):
+oc_subfilter = ''.join([ '(objectclass=%s)' % oc for oc in oc_list])
+return template % oc_subfilter
+
 def validate_ldapuri(ugettext, ldapuri):
 m = re.match('^ldaps?://[-\w\.]+(:\d+)?$', ldapuri)
 if not m:
@@ -152,14 +175,18 @@ class migrate_ds(Command):
 #
 # If pre_callback return value evaluates to False, migration
 # of the current object is aborted.
-'user': (
-'((objectClass=person)(uid=*))',
-_pre_migrate_user, _post_migrate_user
-),
-'group': (
-
'((|(objectClass=groupOfUniqueNames)(objectClass=groupOfNames))(cn=*))',
-_pre_migrate_group, None
-),
+'user': {
+'filter_template' : '((|%s)(uid=*))',
+'oc_option' : 'userobjectclass',
+'pre_callback' : _pre_migrate_user,
+'post_callback' : _post_migrate_user
+},
+'group': {
+'filter_template' : '((|%s)(cn=*))',
+'oc_option' : 'groupobjectclass',
+'pre_callback' : _pre_migrate_group,
+'post_callback' : None
+},
 }
 migrate_order = ('user', 'group')
 
@@ -196,6 +223,28 @@ class migrate_ds(Command):
 default=u'ou=groups',
 autofill=True,
 ),
+List('userobjectclass?',
+