On 04/04/2011 03:47 PM, Simo Sorce wrote:
On Mon, 28 Mar 2011 15:27:46 -0700
Nathan Kinder<nkin...@redhat.com>  wrote:

On 03/28/2011 03:20 PM, Dmitri Pal wrote:
On 03/28/2011 04:38 PM, Pavel Zůna wrote:
This patch handles the issue in a kind of stupid way, but I
couldn't think of anything better.

It adds a new flag parameter to user-add (--noprivate). With this
flag, the command marks the private group about to be created for
deletion and is deleted after the user is created. The only
exception is when there is a group, that is named the same way as
the user, but isn't a private group - then the group is left there.

Private groups are created automatically by the managed entry DS
plugin and I didn't find a way to disable its creation for a
specific user.

The idea that comes to mind is to define some magical attribute
that the DS plugin would recognize and skip the creation of the
managed entry as well as strip the entry of this magic
attribute/value. I remember that other plugins might take advantage
of the similar approach.

Is something like this possible?
You are probably thinking of the DNA plug-in and it's use of a magic
value used to tell the plug-in to allocate a value from a range.  I
would not like to use this approach here, as it requires additional
coding and complexity that I don't think is needed.

I would prefer that we use the originFilter to deal with this.  We
could have an auxiliary objectclass that IPA usually adds when
creating an IPA user.  The originFilter can key off of this
objectclass to create managed groups.  When a user is added with the
--noprivate option, this objectclass is not included in the user
entry that is added.  Rob and I discussed this approach on IRC
earlier today.

Ack, this sounds like a better approach, although it doesn't
necessarily need to be an objectclass it can also be an attribute with
a specific value that is checked in the filter as (!(attrib=value))


New patch with new approach attached.

It sets the checked filter to:

If a user entry is created with the description attribute equal to the string "__no_upg__", the DS plugin will not trigger and no UPG is going to be created.

After this patch, the user-add plugin adds this description attribute (NO_UPG_MAGIC = "__no_upg__") in the pre_callback and deletes it in the post_callback if necessary.

I think the description attribute is the best choice, because it's part of the posixAccount objectClass and we don't use it for anything on user entries.

>From 57f3b82bc4b3180a8b0a27733cc0632b813a7736 Mon Sep 17 00:00:00 2001
From: Pavel Zuna <pz...@redhat.com>
Date: Mon, 28 Mar 2011 15:10:57 -0400
Subject: [PATCH] Add a new user-add flag param to disable the creation of UPG.

Ticket #1131
 install/share/user_private_groups.ldif |    2 +-
 ipalib/plugins/user.py                 |   53 ++++++++++++++++++++++++-------
 2 files changed, 42 insertions(+), 13 deletions(-)

diff --git a/install/share/user_private_groups.ldif b/install/share/user_private_groups.ldif
index 9df729a..41a78ba 100644
--- a/install/share/user_private_groups.ldif
+++ b/install/share/user_private_groups.ldif
@@ -15,7 +15,7 @@ changetype: add
 objectclass: extensibleObject
 cn: UPG Definition
 originScope: cn=users,cn=accounts,$SUFFIX
-originFilter: objectclass=posixAccount
+originFilter: (&(objectclass=posixAccount)(!(description=__no_upg__)))
 managedBase: cn=groups,cn=accounts,$SUFFIX
 managedTemplate: cn=UPG Template,cn=etc,$SUFFIX
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index 9015144..9a658a9 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -63,6 +63,9 @@ from ipalib import _, ngettext
 from ipalib.request import context
 from time import gmtime, strftime
+NO_UPG_MAGIC = '__no_upg__'
 def validate_nsaccountlock(entry_attrs):
     if 'nsaccountlock' in entry_attrs:
         if not isinstance(entry_attrs['nsaccountlock'], basestring):
@@ -70,6 +73,7 @@ def validate_nsaccountlock(entry_attrs):
         if entry_attrs['nsaccountlock'].lower() not in ('true','false'):
             raise errors.ValidationError(name='nsaccountlock', error='must be TRUE or FALSE')
 class user(LDAPObject):
     User object.
@@ -250,22 +254,35 @@ class user_add(LDAPCreate):
     Add a new user.
     msg_summary = _('Added user "%(value)s"')
+    takes_options = LDAPCreate.takes_args + (
+        Flag('noprivate',
+            cli_name='noprivate',
+            doc=_('don\'t create user private group'),
+        ),
+    )
     def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
-        try:
-            # The Managed Entries plugin will allow a user to be created
-            # even if a group has a duplicate name. This would leave a user
-            # without a private group. Check for both the group and the user.
-            self.api.Command['group_show'](keys[-1])
+        if not options.get('noprivate', False):
-                self.api.Command['user_show'](keys[-1])
-                self.obj.handle_duplicate_entry(*keys)
+                # The Managed Entries plugin will allow a user to be created
+                # even if a group has a duplicate name. This would leave a user
+                # without a private group. Check for both the group and the user.
+                self.api.Command['group_show'](keys[-1])
+                try:
+                    self.api.Command['user_show'](keys[-1])
+                    self.obj.handle_duplicate_entry(*keys)
+                except errors.NotFound:
+                    raise errors.ManagedGroupExistsError(group=keys[-1])
             except errors.NotFound:
-                raise errors.ManagedGroupExistsError(group=keys[-1])
-        except errors.NotFound:
-            pass
+                pass
+        else:
+            # we don't want an user private group to be created for this user
+            # add NO_UPG_MAGIC description attribute to let the DS plugin know
+            entry_attrs.setdefault('description', [])
+            entry_attrs['description'].append(NO_UPG_MAGIC)
         config = ldap.get_ipa_config()[1]
         if 'ipamaxusernamelength' in config:
@@ -291,7 +308,7 @@ class user_add(LDAPCreate):
         if 'gidnumber' not in entry_attrs:
             # gidNumber wasn't specified explicity, find out what it should be
-            if ldap.has_upg():
+            if not options.get('noprivate', False) and ldap.has_upg():
                 # User Private Groups - uidNumber == gidNumber
                 entry_attrs['gidnumber'] = entry_attrs['uidnumber']
@@ -317,6 +334,18 @@ class user_add(LDAPCreate):
         def_primary_group = config.get('ipadefaultprimarygroup')
         group_dn = self.api.Object['group'].get_dn(def_primary_group)
         ldap.add_entry_to_group(dn, group_dn)
+        # delete description attribute NO_UPG_MAGIC if present
+        if options.get('noprivate', False):
+            if options.get('all', False):
+                (dn, desc_attr) = ldap.get_entry(dn, ['description'])
+                entry_attrs.update(desc_attr)
+            if 'description' in entry_attrs and NO_UPG_MAGIC in entry_attrs['description']:
+                entry_attrs['description'].remove(NO_UPG_MAGIC)
+                kw = {'setattr': '=%s' % ','.join(entry_attrs['description'])}
+                try:
+                    self.api.Command['user_mod'](keys[-1], **kw)
+                except (errors.EmptyModlist, errors.NotFound):
+                    pass
         return dn

Freeipa-devel mailing list

Reply via email to