[Freeipa-devel] [PATCH] 0159-0162 ID views in compat tree: ACIs, support for shell, gidNumber, and SSH keys

Alexander Bokovoy abokovoy at redhat.com
Fri Oct 10 14:08:11 UTC 2014


On Fri, 10 Oct 2014, Alexander Bokovoy wrote:
>On Fri, 10 Oct 2014, Petr Vobornik wrote:
>>On 10.10.2014 10:39, Alexander Bokovoy wrote:
>>>Hi!
>>>
>>>I'm resending patches 0159 and 0160, and adding two more:
>>>
>>>0161 -- support user SSH public keys in ID view user overrides
>>>0162 -- support gidNumber in ID view user override
>>>
>>>SSH public keys to work require support from SSSD and that one is
>>>currently missing. At least, one add/remove the keys to/from the
>>>override objects.
>>>
>>>Compat tree does not support exporting SSH keys. When accessing the tree
>>>anonymously, the entry will be filtered out by ACIs but for
>>>authenticated users we need to explicitly ignore ipaSshPubKey attribute
>>>in the override, so I'm resending updated slapi-nis patch that only
>>>adds one more attribute to filter out.
>>>
>>
>>I'm going to prepare Web UI for, 160, 161, 162.
>>
>>Q: ipaUserOverride object class contains also 'gecos' attribute. 
>>Will it be handled be CLI and Web UI as well?
>I'll add another patch for that.
>
>>
>>Comments for these 3 patches:
>>
>>1. VERSION was not bumped
>>
>>Patch 160:
>>Apart form #1, is OK (not sure if #1 is needed for ACK)
>I wonder if I should bump it in a separate patch that would be the last
>one in the series, to avoid proliferation of API version numbers? :)
>
>>Patch 161:
>>
>>2. idoverrideuser_show and _find should have post_callback with 
>>convert_sshpubkey_post as well - to be consistent.
>>
>>3. Add blank line before new methods - both post_callbacks
>>
>>4. I have created a helper method for adding object classes in patch 
>>761 (currently on review) - add_missing_object_class. Would be nice 
>>fit, but also I don't want to block this patch with mine.
>>
>>Patch 162:
>>
>>Is it good to have different CLI option name in this and user plugin 
>>for the same attribute: --gid vs --gidnumber ? That said, it's sad 
>>that --gid was not used in user plugin since the beginning.
>I'll fix these.
Fixed patches attached, with three more:

patch 0163 -- support GECOS
patch 0164 -- increase API
patch 0165 -- require slapi-nis 0.54
-- 
/ Alexander Bokovoy
-------------- next part --------------
From f28587d5c736600682f4b7dcf3e1158940fd5797 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Tue, 30 Sep 2014 14:54:50 +0300
Subject: [PATCH 2/6] Support idviews in compat tree

---
 ACI.txt                                                 |  6 ++++++
 install/share/71idviews.ldif                            |  1 +
 install/share/schema_compat.uldif                       |  8 ++++++++
 install/updates/10-schema_compat.update                 | 12 ++++++++++++
 ipalib/plugins/group.py                                 | 10 ++++++++++
 ipalib/plugins/user.py                                  | 11 +++++++++++
 ipaserver/install/plugins/update_managed_permissions.py | 11 +++++++++++
 7 files changed, 59 insertions(+)

diff --git a/ACI.txt b/ACI.txt
index cebdc2c..87c057e 100644
--- a/ACI.txt
+++ b/ACI.txt
@@ -54,6 +54,8 @@ dn: dc=ipa,dc=example
 aci: (targetattr = "cn || createtimestamp || entryusn || gidnumber || memberuid || modifytimestamp || objectclass")(target = "ldap:///cn=groups,cn=compat,dc=ipa,dc=example")(version 3.0;acl "permission:System: Read Group Compat Tree";allow (compare,read,search) userdn = "ldap:///anyone";)
 dn: cn=groups,cn=accounts,dc=ipa,dc=example
 aci: (targetattr = "member || memberhost || memberof || memberuid || memberuser")(targetfilter = "(|(objectclass=ipausergroup)(objectclass=posixgroup))")(version 3.0;acl "permission:System: Read Group Membership";allow (compare,read,search) userdn = "ldap:///all";)
+dn: dc=ipa,dc=example
+aci: (targetattr = "cn || createtimestamp || entryusn || gidnumber || memberuid || modifytimestamp || objectclass")(target = "ldap:///cn=groups,cn=*,cn=views,cn=compat,dc=ipa,dc=example")(version 3.0;acl "permission:System: Read Group Views Compat Tree";allow (compare,read,search) userdn = "ldap:///anyone";)
 dn: cn=groups,cn=accounts,dc=ipa,dc=example
 aci: (targetattr = "businesscategory || cn || createtimestamp || description || entryusn || gidnumber || ipaexternalmember || ipantsecurityidentifier || ipauniqueid || mepmanagedby || modifytimestamp || o || objectclass || ou || owner || seealso")(targetfilter = "(|(objectclass=ipausergroup)(objectclass=posixgroup))")(version 3.0;acl "permission:System: Read Groups";allow (compare,read,search) userdn = "ldap:///anyone";)
 dn: cn=groups,cn=accounts,dc=ipa,dc=example
@@ -256,6 +258,8 @@ dn: cn=users,cn=accounts,dc=ipa,dc=example
 aci: (targetattr = "memberof")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Read User Membership";allow (compare,read,search) userdn = "ldap:///all";)
 dn: cn=users,cn=accounts,dc=ipa,dc=example
 aci: (targetattr = "cn || createtimestamp || description || displayname || entryusn || gecos || gidnumber || givenname || homedirectory || initials || ipantsecurityidentifier || loginshell || manager || modifytimestamp || objectclass || sn || title || uid || uidnumber")(targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Read User Standard Attributes";allow (compare,read,search) userdn = "ldap:///anyone";)
+dn: dc=ipa,dc=example
+aci: (targetattr = "cn || createtimestamp || entryusn || gecos || gidnumber || homedirectory || loginshell || modifytimestamp || objectclass || uid || uidnumber")(target = "ldap:///cn=users,cn=*,cn=views,cn=compat,dc=ipa,dc=example")(version 3.0;acl "permission:System: Read User Views Compat Tree";allow (compare,read,search) userdn = "ldap:///anyone";)
 dn: cn=users,cn=accounts,dc=ipa,dc=example
 aci: (targetfilter = "(objectclass=posixaccount)")(version 3.0;acl "permission:System: Remove Users";allow (delete) groupdn = "ldap:///cn=System: Remove Users,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=users,cn=accounts,dc=ipa,dc=example
@@ -264,6 +268,8 @@ dn: cn=ca_renewal,cn=ipa,cn=etc,dc=ipa,dc=example
 aci: (target = "ldap:///cn=caSigningCert cert-pki-ca,cn=ca_renewal,cn=ipa,cn=etc,dc=ipa,dc=example")(targetfilter = "(objectclass=pkiuser)")(version 3.0;acl "permission:System: Add CA Certificate For Renewal";allow (add) groupdn = "ldap:///cn=System: Add CA Certificate For Renewal,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=certificates,cn=ipa,cn=etc,dc=ipa,dc=example
 aci: (targetfilter = "(objectclass=ipacertificate)")(version 3.0;acl "permission:System: Add Certificate Store Entry";allow (add) groupdn = "ldap:///cn=System: Add Certificate Store Entry,cn=permissions,cn=pbac,dc=ipa,dc=example";)
+dn: dc=ipa,dc=example
+aci: (targetattr = "ipaanchoruuid")(target = "ldap:///cn=*,cn=compat,dc=ipa,dc=example")(targetfilter = "(objectclass=ipaOverrideTarget)")(version 3.0;acl "permission:System: Compat Tree ID View targets";allow (compare,read,search) userdn = "ldap:///anyone";)
 dn: cn=CAcert,cn=ipa,cn=etc,dc=ipa,dc=example
 aci: (targetattr = "cacertificate")(targetfilter = "(objectclass=pkica)")(version 3.0;acl "permission:System: Modify CA Certificate";allow (write) groupdn = "ldap:///cn=System: Modify CA Certificate,cn=permissions,cn=pbac,dc=ipa,dc=example";)
 dn: cn=ca_renewal,cn=ipa,cn=etc,dc=ipa,dc=example
diff --git a/install/share/71idviews.ldif b/install/share/71idviews.ldif
index 3f8df2e..caa5cff 100644
--- a/install/share/71idviews.ldif
+++ b/install/share/71idviews.ldif
@@ -5,3 +5,4 @@ objectClasses: (2.16.840.1.113730.3.8.12.29 NAME 'ipaIDView' SUP nsContainer STR
 objectClasses: (2.16.840.1.113730.3.8.12.30 NAME 'ipaOverrideAnchor' SUP top STRUCTURAL MUST ( ipaAnchorUUID ) MAY ( description ) X-ORIGIN 'IPA v4' )
 objectClasses: (2.16.840.1.113730.3.8.12.31 NAME 'ipaUserOverride' DESC 'Override for User Attributes' SUP ipaOverrideAnchor STRUCTURAL MAY ( uid $ uidNumber $ gidNumber $ homeDirectory $ loginShell $ gecos $ ipaOriginalUid ) X-ORIGIN 'IPA v4' )
 objectClasses: (2.16.840.1.113730.3.8.12.32 NAME 'ipaGroupOverride' DESC 'Override for Group Attributes' SUP ipaOverrideAnchor STRUCTURAL MAY ( gidNumber $ cn ) X-ORIGIN 'IPA v4' )
+objectClasses: (2.16.840.1.113730.3.8.12.34 NAME 'ipaOverrideTarget' SUP top STRUCTURAL MUST ( ipaAnchorUUID ) X-ORIGIN 'IPA v4' )
diff --git a/install/share/schema_compat.uldif b/install/share/schema_compat.uldif
index 6de812f..6769fd1 100644
--- a/install/share/schema_compat.uldif
+++ b/install/share/schema_compat.uldif
@@ -38,6 +38,10 @@ default:schema-compat-entry-attribute: uidNumber=%{uidNumber}
 default:schema-compat-entry-attribute: gidNumber=%{gidNumber}
 default:schema-compat-entry-attribute: loginShell=%{loginShell}
 default:schema-compat-entry-attribute: homeDirectory=%{homeDirectory}
+default:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","objectclass=ipaOverrideTarget","")
+default:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","ipaanchoruuid=:IPA:$DOMAIN:%{ipauniqueid}","")
+default:schema-compat-entry-attribute: ipaanchoruuid=%{ipaanchoruuid}
+default:schema-compat-entry-attribute: %ifeq("ipaanchoruuid","%{ipaanchoruuid}","objectclass=ipaOverrideTarget","")
 
 dn: cn=groups, cn=Schema Compatibility, cn=plugins, cn=config
 default:objectClass: top
@@ -52,6 +56,10 @@ default:schema-compat-entry-attribute: objectclass=posixGroup
 default:schema-compat-entry-attribute: gidNumber=%{gidNumber}
 default:schema-compat-entry-attribute: memberUid=%{memberUid}
 default:schema-compat-entry-attribute: memberUid=%deref_r("member","uid")
+default:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","objectclass=ipaOverrideTarget","")
+default:schema-compat-entry-attribute: %ifeq("ipauniqueid","%{ipauniqueid}","ipaanchoruuid=:IPA:$DOMAIN:%{ipauniqueid}","")
+default:schema-compat-entry-attribute: ipaanchoruuid=%{ipaanchoruuid}
+default:schema-compat-entry-attribute: %ifeq("ipaanchoruuid","%{ipaanchoruuid}","objectclass=ipaOverrideTarget","")
 
 dn: cn=ng,cn=Schema Compatibility,cn=plugins,cn=config
 add:objectClass: top
diff --git a/install/updates/10-schema_compat.update b/install/updates/10-schema_compat.update
index aeddadb..e88b492 100644
--- a/install/updates/10-schema_compat.update
+++ b/install/updates/10-schema_compat.update
@@ -47,3 +47,15 @@ dn: cn=Schema Compatibility,cn=plugins,cn=config
 # rewritten to the original entry if needed
 add:nsslapd-pluginprecedence: 49
 
+dn: cn=users,cn=Schema Compatibility,cn=plugins,cn=config
+add:schema-compat-entry-attribute: '%ifeq("ipauniqueid","%{ipauniqueid}","objectclass=ipaOverrideTarget","")'
+add:schema-compat-entry-attribute: '%ifeq("ipauniqueid","%{ipauniqueid}","ipaanchoruuid=:IPA:$DOMAIN:%{ipauniqueid}","")'
+add:schema-compat-entry-attribute: 'ipaanchoruuid=%{ipaanchoruuid}'
+add:schema-compat-entry-attribute: '%ifeq("ipaanchoruuid","%{ipaanchoruuid}","objectclass=ipaOverrideTarget","")'
+
+dn: cn=groups,cn=Schema Compatibility,cn=plugins,cn=config
+add:schema-compat-entry-attribute: '%ifeq("ipauniqueid","%{ipauniqueid}","objectclass=ipaOverrideTarget","")'
+add:schema-compat-entry-attribute: '%ifeq("ipauniqueid","%{ipauniqueid}","ipaanchoruuid=:IPA:$DOMAIN:%{ipauniqueid}","")'
+add:schema-compat-entry-attribute: 'ipaanchoruuid=%{ipaanchoruuid}'
+add:schema-compat-entry-attribute: '%ifeq("ipaanchoruuid","%{ipaanchoruuid}","objectclass=ipaOverrideTarget","")'
+
diff --git a/ipalib/plugins/group.py b/ipalib/plugins/group.py
index 9c2e308..03e6893 100644
--- a/ipalib/plugins/group.py
+++ b/ipalib/plugins/group.py
@@ -212,6 +212,16 @@ class group(LDAPObject):
                 'objectclass', 'cn', 'memberuid', 'gidnumber',
             },
         },
+        'System: Read Group Views Compat Tree': {
+            'non_object': True,
+            'ipapermbindruletype': 'anonymous',
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN('cn=groups', 'cn=*', 'cn=views', 'cn=compat', api.env.basedn),
+            'ipapermright': {'read', 'search', 'compare'},
+            'ipapermdefaultattr': {
+                'objectclass', 'cn', 'memberuid', 'gidnumber',
+            },
+        },
     }
 
     label = _('User Groups')
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index f95b4fd..e206289 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -435,6 +435,17 @@ class user(LDAPObject):
                 'homedirectory', 'loginshell',
             },
         },
+        'System: Read User Views Compat Tree': {
+            'non_object': True,
+            'ipapermbindruletype': 'anonymous',
+            'ipapermlocation': api.env.basedn,
+            'ipapermtarget': DN('cn=users', 'cn=*', 'cn=views', 'cn=compat', api.env.basedn),
+            'ipapermright': {'read', 'search', 'compare'},
+            'ipapermdefaultattr': {
+                'objectclass', 'uid', 'cn', 'gecos', 'gidnumber', 'uidnumber',
+                'homedirectory', 'loginshell',
+            },
+        },
     }
 
     label = _('Users')
diff --git a/ipaserver/install/plugins/update_managed_permissions.py b/ipaserver/install/plugins/update_managed_permissions.py
index df49d5d..032485a 100644
--- a/ipaserver/install/plugins/update_managed_permissions.py
+++ b/ipaserver/install/plugins/update_managed_permissions.py
@@ -117,6 +117,17 @@ NONOBJECT_PERMISSIONS = {
         },
         'default_privileges': {'IPA Masters Readers'},
     },
+    'System: Compat Tree ID View targets': {
+        'replaces_global_anonymous_aci': True,
+        'ipapermlocation':  api.env.basedn,
+        'ipapermtarget': DN('cn=*,cn=compat', api.env.basedn),
+        'ipapermtargetfilter': {'(objectclass=ipaOverrideTarget)'},
+        'ipapermbindruletype': 'anonymous',
+        'ipapermright': {'read', 'search', 'compare'},
+        'ipapermdefaultattr': {
+            'ipaAnchorUUID',
+        },
+    },
     'System: Read DNA Configuration': {
         'replaces_global_anonymous_aci': True,
         'ipapermlocation': DN('cn=dna,cn=ipa,cn=etc', api.env.basedn),
-- 
2.1.0

-------------- next part --------------
From 6855012f03490188a3d4d188f028b1e54fc37858 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Tue, 30 Sep 2014 15:44:31 +0300
Subject: [PATCH 3/6] Support overridding user shell in ID views

---
 ACI.txt                   | 2 +-
 API.txt                   | 9 ++++++---
 ipalib/plugins/idviews.py | 8 ++++++--
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/ACI.txt b/ACI.txt
index 87c057e..b2192ce 100644
--- a/ACI.txt
+++ b/ACI.txt
@@ -123,7 +123,7 @@ aci: (targetfilter = "(objectclass=ipahostgroup)")(version 3.0;acl "permission:S
 dn: cn=views,cn=accounts,dc=ipa,dc=example
 aci: (targetattr = "cn || createtimestamp || description || entryusn || gidnumber || ipaanchoruuid || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaGroupOverride)")(version 3.0;acl "permission:System: Read Group ID Overrides";allow (compare,read,search) userdn = "ldap:///all";)
 dn: cn=views,cn=accounts,dc=ipa,dc=example
-aci: (targetattr = "createtimestamp || description || entryusn || homedirectory || ipaanchoruuid || ipaoriginaluid || modifytimestamp || objectclass || uid || uidnumber")(targetfilter = "(objectclass=ipaUserOverride)")(version 3.0;acl "permission:System: Read User ID Overrides";allow (compare,read,search) userdn = "ldap:///all";)
+aci: (targetattr = "createtimestamp || description || entryusn || homedirectory || ipaanchoruuid || ipaoriginaluid || loginshell || modifytimestamp || objectclass || uid || uidnumber")(targetfilter = "(objectclass=ipaUserOverride)")(version 3.0;acl "permission:System: Read User ID Overrides";allow (compare,read,search) userdn = "ldap:///all";)
 dn: cn=ranges,cn=etc,dc=ipa,dc=example
 aci: (targetattr = "cn || createtimestamp || entryusn || ipabaseid || ipabaserid || ipaidrangesize || ipanttrusteddomainsid || iparangetype || ipasecondarybaserid || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaidrange)")(version 3.0;acl "permission:System: Read ID Ranges";allow (compare,read,search) userdn = "ldap:///all";)
 dn: cn=views,cn=accounts,dc=ipa,dc=example
diff --git a/API.txt b/API.txt
index c5e76c7..41b852b 100644
--- a/API.txt
+++ b/API.txt
@@ -2104,7 +2104,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: PrimaryKey('value', None, None)
 command: idoverrideuser_add
-args: 2,10,3
+args: 2,11,3
 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True)
 arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=False, primary_key=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
@@ -2112,6 +2112,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui
 option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
 option: Str('homedirectory', attribute=True, cli_name='homedir', multivalue=False, required=False)
 option: Str('ipaoriginaluid', attribute=True, cli_name='ipaoriginaluid', multivalue=False, required=False)
+option: Str('loginshell', attribute=True, cli_name='shell', multivalue=False, required=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Str('setattr*', cli_name='setattr', exclude='webui')
 option: Str('uid', attribute=True, cli_name='login', maxlength=255, multivalue=False, pattern='^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?$', required=False)
@@ -2130,7 +2131,7 @@ output: Output('result', <type 'dict'>, None)
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: ListOfPrimaryKeys('value', None, None)
 command: idoverrideuser_find
-args: 2,12,4
+args: 2,13,4
 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True)
 arg: Str('criteria?', noextrawhitespace=False)
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
@@ -2138,6 +2139,7 @@ option: Str('description', attribute=True, autofill=False, cli_name='desc', mult
 option: Str('homedirectory', attribute=True, autofill=False, cli_name='homedir', multivalue=False, query=True, required=False)
 option: Str('ipaanchoruuid', attribute=True, autofill=False, cli_name='anchor', multivalue=False, primary_key=True, query=True, required=False)
 option: Str('ipaoriginaluid', attribute=True, autofill=False, cli_name='ipaoriginaluid', multivalue=False, query=True, required=False)
+option: Str('loginshell', attribute=True, autofill=False, cli_name='shell', multivalue=False, query=True, required=False)
 option: Flag('pkey_only?', autofill=True, default=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Int('sizelimit?', autofill=False, minvalue=0)
@@ -2150,7 +2152,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: Output('truncated', <type 'bool'>, None)
 command: idoverrideuser_mod
-args: 2,13,3
+args: 2,14,3
 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True)
 arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=False, primary_key=True, query=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
@@ -2159,6 +2161,7 @@ option: Str('delattr*', cli_name='delattr', exclude='webui')
 option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
 option: Str('homedirectory', attribute=True, autofill=False, cli_name='homedir', multivalue=False, required=False)
 option: Str('ipaoriginaluid', attribute=True, autofill=False, cli_name='ipaoriginaluid', multivalue=False, required=False)
+option: Str('loginshell', attribute=True, autofill=False, cli_name='shell', multivalue=False, required=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Str('rename', cli_name='rename', multivalue=False, primary_key=True, required=False)
 option: Flag('rights', autofill=True, default=False)
diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py
index 3b0df02..afaa6f9 100644
--- a/ipalib/plugins/idviews.py
+++ b/ipalib/plugins/idviews.py
@@ -650,14 +650,14 @@ class idoverrideuser(baseidoverride):
             'ipapermright': {'read', 'search', 'compare'},
             'ipapermdefaultattr': {
                 'objectClass', 'ipaAnchorUUID', 'uidNumber', 'description',
-                'homeDirectory', 'uid', 'ipaOriginalUid',
+                'homeDirectory', 'uid', 'ipaOriginalUid', 'loginShell',
             },
         },
     }
 
     object_class = baseidoverride.object_class + ['ipaUserOverride']
     default_attributes = baseidoverride.default_attributes + [
-       'homeDirectory', 'uidNumber', 'uid', 'ipaOriginalUid',
+       'homeDirectory', 'uidNumber', 'uid', 'ipaOriginalUid', 'loginShell',
     ]
 
     takes_params = baseidoverride.takes_params + (
@@ -679,6 +679,10 @@ class idoverrideuser(baseidoverride):
             cli_name='homedir',
             label=_('Home directory'),
         ),
+        Str('loginshell?',
+            cli_name='shell',
+            label=_('Login shell'),
+        ),
         Str('ipaoriginaluid?',
             flags=['no_option', 'no_output']
             ),
-- 
2.1.0

-------------- next part --------------
From d9006d1ec317d2c01ee9adad8e2e06c5afbf91fd Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Fri, 10 Oct 2014 09:26:13 +0300
Subject: [PATCH 4/9] Allow user overrides to specify SSH public keys

Overrides for users can have SSH public keys. This, however, will not enable
SSH public keys from overrides to be actually used until SSSD gets fixed to
pull them in.

SSSD ticket for SSH public keys in overrides:
https://fedorahosted.org/sssd/ticket/2454

Resolves https://fedorahosted.org/freeipa/ticket/4509
---
 API.txt                   |  6 ++++--
 ipalib/plugins/idviews.py | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/API.txt b/API.txt
index 41b852b..5316ac2 100644
--- a/API.txt
+++ b/API.txt
@@ -2104,7 +2104,7 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: PrimaryKey('value', None, None)
 command: idoverrideuser_add
-args: 2,11,3
+args: 2,12,3
 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True)
 arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=False, primary_key=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
@@ -2112,6 +2112,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui
 option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
 option: Str('homedirectory', attribute=True, cli_name='homedir', multivalue=False, required=False)
 option: Str('ipaoriginaluid', attribute=True, cli_name='ipaoriginaluid', multivalue=False, required=False)
+option: Str('ipasshpubkey', attribute=True, cli_name='sshpubkey', csv=True, multivalue=True, required=False)
 option: Str('loginshell', attribute=True, cli_name='shell', multivalue=False, required=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Str('setattr*', cli_name='setattr', exclude='webui')
@@ -2152,7 +2153,7 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: Output('truncated', <type 'bool'>, None)
 command: idoverrideuser_mod
-args: 2,14,3
+args: 2,15,3
 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True)
 arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=False, primary_key=True, query=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
@@ -2161,6 +2162,7 @@ option: Str('delattr*', cli_name='delattr', exclude='webui')
 option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
 option: Str('homedirectory', attribute=True, autofill=False, cli_name='homedir', multivalue=False, required=False)
 option: Str('ipaoriginaluid', attribute=True, autofill=False, cli_name='ipaoriginaluid', multivalue=False, required=False)
+option: Str('ipasshpubkey', attribute=True, autofill=False, cli_name='sshpubkey', csv=True, multivalue=True, required=False)
 option: Str('loginshell', attribute=True, autofill=False, cli_name='shell', multivalue=False, required=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False, exclude='webui')
 option: Str('rename', cli_name='rename', multivalue=False, primary_key=True, required=False)
diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py
index afaa6f9..95bf23a 100644
--- a/ipalib/plugins/idviews.py
+++ b/ipalib/plugins/idviews.py
@@ -25,6 +25,8 @@ from ipalib.plugins.hostgroup import get_complete_hostgroup_member_list
 from ipalib import api, Str, Int, Flag, _, ngettext, errors, output
 from ipalib.constants import IPA_ANCHOR_PREFIX, SID_ANCHOR_PREFIX
 from ipalib.plugable import Registry
+from ipalib.util import (normalize_sshpubkey, validate_sshpubkey,
+    convert_sshpubkey_post)
 
 from ipapython.dn import DN
 
@@ -658,6 +660,7 @@ class idoverrideuser(baseidoverride):
     object_class = baseidoverride.object_class + ['ipaUserOverride']
     default_attributes = baseidoverride.default_attributes + [
        'homeDirectory', 'uidNumber', 'uid', 'ipaOriginalUid', 'loginShell',
+       'ipaSshPubkey',
     ]
 
     takes_params = baseidoverride.takes_params + (
@@ -686,6 +689,13 @@ class idoverrideuser(baseidoverride):
         Str('ipaoriginaluid?',
             flags=['no_option', 'no_output']
             ),
+        Str('ipasshpubkey*', validate_sshpubkey,
+            cli_name='sshpubkey',
+            label=_('SSH public key'),
+            normalizer=normalize_sshpubkey,
+            csv=True,
+            flags=['no_search'],
+        ),
     )
 
     override_object = 'user'
@@ -758,6 +768,11 @@ class idoverrideuser_add(baseidoverride_add):
         self.obj.update_original_uid_reference(entry_attrs)
         return dn
 
+    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
+        convert_sshpubkey_post(ldap, dn, entry_attrs)
+        return dn
+
+
 
 @register()
 class idoverrideuser_del(baseidoverride_del):
@@ -777,6 +792,18 @@ class idoverrideuser_mod(baseidoverride_mod):
         # Update the ipaOriginalUid
         self.obj.set_anchoruuid_from_dn(dn, entry_attrs)
         self.obj.update_original_uid_reference(entry_attrs)
+        if 'objectclass' in entry_attrs:
+            obj_classes = entry_attrs['objectclass']
+        else:
+            _entry_attrs = ldap.get_entry(dn, ['objectclass'])
+            obj_classes = entry_attrs['objectclass'] = _entry_attrs['objectclass']
+
+        if 'ipasshpubkey' in entry_attrs and 'ipasshuser' not in obj_classes:
+            obj_classes.append('ipasshuser')
+        return dn
+
+    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
+        convert_sshpubkey_post(ldap, dn, entry_attrs)
         return dn
 
 
@@ -786,11 +813,19 @@ class idoverrideuser_find(baseidoverride_find):
     msg_summary = ngettext('%(count)d User ID override matched',
                            '%(count)d User ID overrides matched', 0)
 
+    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
+        convert_sshpubkey_post(ldap, dn, entry_attrs)
+        return dn
+
 
 @register()
 class idoverrideuser_show(baseidoverride_show):
     __doc__ = _('Display information about an User ID override.')
 
+    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
+        convert_sshpubkey_post(ldap, dn, entry_attrs)
+        return dn
+
 
 @register()
 class idoverridegroup_add(baseidoverride_add):
-- 
2.1.0

-------------- next part --------------
From 1ef2aa69defc5228c97d6d886c28fcc4a26dee37 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Fri, 10 Oct 2014 09:30:51 +0300
Subject: [PATCH 5/9] Allow user overrides to specify GID of the user

Resolves https://fedorahosted.org/freeipa/ticket/4617
---
 API.txt                   | 9 ++++++---
 ipalib/plugins/idviews.py | 7 ++++++-
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/API.txt b/API.txt
index 5316ac2..ea5d6fe 100644
--- a/API.txt
+++ b/API.txt
@@ -2104,12 +2104,13 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: PrimaryKey('value', None, None)
 command: idoverrideuser_add
-args: 2,12,3
+args: 2,13,3
 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True)
 arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=False, primary_key=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
+option: Int('gidnumber', attribute=True, cli_name='gidnumber', minvalue=1, multivalue=False, required=False)
 option: Str('homedirectory', attribute=True, cli_name='homedir', multivalue=False, required=False)
 option: Str('ipaoriginaluid', attribute=True, cli_name='ipaoriginaluid', multivalue=False, required=False)
 option: Str('ipasshpubkey', attribute=True, cli_name='sshpubkey', csv=True, multivalue=True, required=False)
@@ -2132,11 +2133,12 @@ output: Output('result', <type 'dict'>, None)
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: ListOfPrimaryKeys('value', None, None)
 command: idoverrideuser_find
-args: 2,13,4
+args: 2,14,4
 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True)
 arg: Str('criteria?', noextrawhitespace=False)
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False)
+option: Int('gidnumber', attribute=True, autofill=False, cli_name='gidnumber', minvalue=1, multivalue=False, query=True, required=False)
 option: Str('homedirectory', attribute=True, autofill=False, cli_name='homedir', multivalue=False, query=True, required=False)
 option: Str('ipaanchoruuid', attribute=True, autofill=False, cli_name='anchor', multivalue=False, primary_key=True, query=True, required=False)
 option: Str('ipaoriginaluid', attribute=True, autofill=False, cli_name='ipaoriginaluid', multivalue=False, query=True, required=False)
@@ -2153,13 +2155,14 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: Output('truncated', <type 'bool'>, None)
 command: idoverrideuser_mod
-args: 2,15,3
+args: 2,16,3
 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True)
 arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=False, primary_key=True, query=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('delattr*', cli_name='delattr', exclude='webui')
 option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
+option: Int('gidnumber', attribute=True, autofill=False, cli_name='gidnumber', minvalue=1, multivalue=False, required=False)
 option: Str('homedirectory', attribute=True, autofill=False, cli_name='homedir', multivalue=False, required=False)
 option: Str('ipaoriginaluid', attribute=True, autofill=False, cli_name='ipaoriginaluid', multivalue=False, required=False)
 option: Str('ipasshpubkey', attribute=True, autofill=False, cli_name='sshpubkey', csv=True, multivalue=True, required=False)
diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py
index 95bf23a..cbf78c1 100644
--- a/ipalib/plugins/idviews.py
+++ b/ipalib/plugins/idviews.py
@@ -660,7 +660,7 @@ class idoverrideuser(baseidoverride):
     object_class = baseidoverride.object_class + ['ipaUserOverride']
     default_attributes = baseidoverride.default_attributes + [
        'homeDirectory', 'uidNumber', 'uid', 'ipaOriginalUid', 'loginShell',
-       'ipaSshPubkey',
+       'ipaSshPubkey', 'gidNumber',
     ]
 
     takes_params = baseidoverride.takes_params + (
@@ -678,6 +678,11 @@ class idoverrideuser(baseidoverride):
             doc=_('User ID Number'),
             minvalue=1,
         ),
+        Int('gidnumber?',
+            label=_('GID'),
+            doc=_('Group ID Number'),
+            minvalue=1,
+        ),
         Str('homedirectory?',
             cli_name='homedir',
             label=_('Home directory'),
-- 
2.1.0

-------------- next part --------------
From fde7c592afb10b91ff6971eaaae1b41e5d44acca Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Fri, 10 Oct 2014 16:52:41 +0300
Subject: [PATCH 7/9] Update API version for ID views support

---
 VERSION | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/VERSION b/VERSION
index 78ef7d8..24a6a5e 100644
--- a/VERSION
+++ b/VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
 #                                                      #
 ########################################################
 IPA_API_VERSION_MAJOR=2
-IPA_API_VERSION_MINOR=104
-# Last change: mbasti - autofill --admin-email in DNS zone
+IPA_API_VERSION_MINOR=105
+# Last change: abbra - ID views attributes
-- 
2.1.0

-------------- next part --------------
From 3163cffb5c1f7f530cdee4ac6eac418df78fa1d8 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Fri, 10 Oct 2014 16:54:34 +0300
Subject: [PATCH 8/9] Require slapi-nis 0.54 or later for ID views support

---
 freeipa.spec.in | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/freeipa.spec.in b/freeipa.spec.in
index a52a1d1..30ffb89 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -126,7 +126,7 @@ Requires(pre): systemd-units
 Requires(post): systemd-units
 Requires: selinux-policy >= %{selinux_policy_version}
 Requires(post): selinux-policy-base
-Requires: slapi-nis >= 0.47.7
+Requires: slapi-nis >= 0.54-1
 Requires: pki-ca >= 10.2.0
 Requires: pki-kra >= 10.2.0
 %if 0%{?rhel}
-- 
2.1.0

-------------- next part --------------
From 240f859a91f0aeb7612e2986536c22b415547499 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy at redhat.com>
Date: Fri, 10 Oct 2014 16:44:47 +0300
Subject: [PATCH 6/9] Allow override of gecos field in ID views

---
 ACI.txt                   | 2 +-
 API.txt                   | 9 ++++++---
 ipalib/plugins/idviews.py | 7 +++++--
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/ACI.txt b/ACI.txt
index b2192ce..98e1143 100644
--- a/ACI.txt
+++ b/ACI.txt
@@ -123,7 +123,7 @@ aci: (targetfilter = "(objectclass=ipahostgroup)")(version 3.0;acl "permission:S
 dn: cn=views,cn=accounts,dc=ipa,dc=example
 aci: (targetattr = "cn || createtimestamp || description || entryusn || gidnumber || ipaanchoruuid || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaGroupOverride)")(version 3.0;acl "permission:System: Read Group ID Overrides";allow (compare,read,search) userdn = "ldap:///all";)
 dn: cn=views,cn=accounts,dc=ipa,dc=example
-aci: (targetattr = "createtimestamp || description || entryusn || homedirectory || ipaanchoruuid || ipaoriginaluid || loginshell || modifytimestamp || objectclass || uid || uidnumber")(targetfilter = "(objectclass=ipaUserOverride)")(version 3.0;acl "permission:System: Read User ID Overrides";allow (compare,read,search) userdn = "ldap:///all";)
+aci: (targetattr = "createtimestamp || description || entryusn || gecos || homedirectory || ipaanchoruuid || ipaoriginaluid || loginshell || modifytimestamp || objectclass || uid || uidnumber")(targetfilter = "(objectclass=ipaUserOverride)")(version 3.0;acl "permission:System: Read User ID Overrides";allow (compare,read,search) userdn = "ldap:///all";)
 dn: cn=ranges,cn=etc,dc=ipa,dc=example
 aci: (targetattr = "cn || createtimestamp || entryusn || ipabaseid || ipabaserid || ipaidrangesize || ipanttrusteddomainsid || iparangetype || ipasecondarybaserid || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaidrange)")(version 3.0;acl "permission:System: Read ID Ranges";allow (compare,read,search) userdn = "ldap:///all";)
 dn: cn=views,cn=accounts,dc=ipa,dc=example
diff --git a/API.txt b/API.txt
index ea5d6fe..1af7850 100644
--- a/API.txt
+++ b/API.txt
@@ -2104,12 +2104,13 @@ output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDA
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: PrimaryKey('value', None, None)
 command: idoverrideuser_add
-args: 2,13,3
+args: 2,14,3
 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True)
 arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=False, primary_key=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('description', attribute=True, cli_name='desc', multivalue=False, required=False)
+option: Str('gecos', attribute=True, cli_name='gecos', multivalue=False, required=False)
 option: Int('gidnumber', attribute=True, cli_name='gidnumber', minvalue=1, multivalue=False, required=False)
 option: Str('homedirectory', attribute=True, cli_name='homedir', multivalue=False, required=False)
 option: Str('ipaoriginaluid', attribute=True, cli_name='ipaoriginaluid', multivalue=False, required=False)
@@ -2133,11 +2134,12 @@ output: Output('result', <type 'dict'>, None)
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: ListOfPrimaryKeys('value', None, None)
 command: idoverrideuser_find
-args: 2,14,4
+args: 2,15,4
 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True)
 arg: Str('criteria?', noextrawhitespace=False)
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, query=True, required=False)
+option: Str('gecos', attribute=True, autofill=False, cli_name='gecos', multivalue=False, query=True, required=False)
 option: Int('gidnumber', attribute=True, autofill=False, cli_name='gidnumber', minvalue=1, multivalue=False, query=True, required=False)
 option: Str('homedirectory', attribute=True, autofill=False, cli_name='homedir', multivalue=False, query=True, required=False)
 option: Str('ipaanchoruuid', attribute=True, autofill=False, cli_name='anchor', multivalue=False, primary_key=True, query=True, required=False)
@@ -2155,13 +2157,14 @@ output: ListOfEntries('result', (<type 'list'>, <type 'tuple'>), Gettext('A list
 output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
 output: Output('truncated', <type 'bool'>, None)
 command: idoverrideuser_mod
-args: 2,16,3
+args: 2,17,3
 arg: Str('idviewcn', cli_name='idview', multivalue=False, primary_key=True, query=True, required=True)
 arg: Str('ipaanchoruuid', attribute=True, cli_name='anchor', multivalue=False, primary_key=True, query=True, required=True)
 option: Str('addattr*', cli_name='addattr', exclude='webui')
 option: Flag('all', autofill=True, cli_name='all', default=False, exclude='webui')
 option: Str('delattr*', cli_name='delattr', exclude='webui')
 option: Str('description', attribute=True, autofill=False, cli_name='desc', multivalue=False, required=False)
+option: Str('gecos', attribute=True, autofill=False, cli_name='gecos', multivalue=False, required=False)
 option: Int('gidnumber', attribute=True, autofill=False, cli_name='gidnumber', minvalue=1, multivalue=False, required=False)
 option: Str('homedirectory', attribute=True, autofill=False, cli_name='homedir', multivalue=False, required=False)
 option: Str('ipaoriginaluid', attribute=True, autofill=False, cli_name='ipaoriginaluid', multivalue=False, required=False)
diff --git a/ipalib/plugins/idviews.py b/ipalib/plugins/idviews.py
index cbf78c1..b55a78e 100644
--- a/ipalib/plugins/idviews.py
+++ b/ipalib/plugins/idviews.py
@@ -652,7 +652,7 @@ class idoverrideuser(baseidoverride):
             'ipapermright': {'read', 'search', 'compare'},
             'ipapermdefaultattr': {
                 'objectClass', 'ipaAnchorUUID', 'uidNumber', 'description',
-                'homeDirectory', 'uid', 'ipaOriginalUid', 'loginShell',
+                'homeDirectory', 'uid', 'ipaOriginalUid', 'loginShell', 'gecos',
             },
         },
     }
@@ -660,7 +660,7 @@ class idoverrideuser(baseidoverride):
     object_class = baseidoverride.object_class + ['ipaUserOverride']
     default_attributes = baseidoverride.default_attributes + [
        'homeDirectory', 'uidNumber', 'uid', 'ipaOriginalUid', 'loginShell',
-       'ipaSshPubkey', 'gidNumber',
+       'ipaSshPubkey', 'gidNumber', 'gecos',
     ]
 
     takes_params = baseidoverride.takes_params + (
@@ -678,6 +678,9 @@ class idoverrideuser(baseidoverride):
             doc=_('User ID Number'),
             minvalue=1,
         ),
+        Str('gecos?',
+            label=_('GECOS'),
+        ),
         Int('gidnumber?',
             label=_('GID'),
             doc=_('Group ID Number'),
-- 
2.1.0



More information about the Freeipa-devel mailing list