This patch fixes the inconsistency between storing certificates in 'userCertificate'/'userCertificate;binary' attribute for the user entries: the certificate must be stored in the latter attribute only.

Since a more general fix is out of 4.2.1 scope, I have implemented some workarounds in pre/post callbacks of user-* commands in order to enforce this behavior.

--
Martin^3 Babinsky
From f3a35458271c3fd149eed752fe0815e61edf0cb4 Mon Sep 17 00:00:00 2001
From: Martin Babinsky <mbabi...@redhat.com>
Date: Mon, 3 Aug 2015 13:36:29 +0200
Subject: [PATCH] store certificates issued for user entries as
 userCertificate;binary

This patch forces the user management CLI command to store certificates as
userCertificate;binary attribute. The code to retrieve of user information was
modified to enable outputting of userCertificate;binary attribute to the
command line.
---
 ipalib/plugins/baseuser.py | 26 +++++++++++++++++++++++++-
 ipalib/plugins/user.py     |  4 ++++
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/ipalib/plugins/baseuser.py b/ipalib/plugins/baseuser.py
index bd66cf5a3e3a4e6c18d1a54408f969668c834fab..36ad0590833ab1279920d7e1c19851832266a57d 100644
--- a/ipalib/plugins/baseuser.py
+++ b/ipalib/plugins/baseuser.py
@@ -187,7 +187,7 @@ class baseuser(LDAPObject):
         'telephonenumber', 'title', 'memberof', 'nsaccountlock',
         'memberofindirect', 'ipauserauthtype', 'userclass',
         'ipatokenradiusconfiglink', 'ipatokenradiususername',
-        'krbprincipalexpiration', 'usercertificate',
+        'krbprincipalexpiration', 'usercertificate;binary',
     ]
     search_display_attributes = [
         'uid', 'givenname', 'sn', 'homedirectory', 'loginshell',
@@ -465,11 +465,31 @@ class baseuser(LDAPObject):
         assert isinstance(user, DN)
         return self._user_status(user, DN(self.delete_container_dn, api.env.basedn))
 
+    def convert_usercertificate_pre(self, entry_attrs, **options):
+        if options.get('all', False):
+            return
+
+        if 'usercertificate' in entry_attrs:
+            entry_attrs['usercertificate;binary'] = entry_attrs.pop(
+                'usercertificate')
+
+    def convert_usercertificate_post(self, entry_attrs, **options):
+        if options.get('all', False):
+            return
+
+        if 'usercertificate;binary' in entry_attrs:
+            entry_attrs['usercertificate'] = entry_attrs.pop(
+                'usercertificate;binary')
+
 class baseuser_add(LDAPCreate):
     """
     Prototype command plugin to be implemented by real plugin
     """
 
+    def post_common_callback(self, ldap, dn, entry_attrs, **options):
+        assert isinstance(dn, DN)
+        self.obj.convert_usercertificate_post(entry_attrs, **options)
+
 class baseuser_del(LDAPDelete):
     """
     Prototype command plugin to be implemented by real plugin
@@ -542,6 +562,7 @@ class baseuser_mod(LDAPUpdate):
         self.check_userpassword(entry_attrs, **options)
 
         self.check_objectclass(ldap, dn, entry_attrs)
+        self.obj.convert_usercertificate_pre(entry_attrs, **options)
 
     def post_common_callback(self, ldap, dn, entry_attrs, **options):
         assert isinstance(dn, DN)
@@ -554,6 +575,7 @@ class baseuser_mod(LDAPUpdate):
         convert_nsaccountlock(entry_attrs)
         self.obj.convert_manager(entry_attrs, **options)
         self.obj.get_password_attributes(ldap, dn, entry_attrs)
+        self.obj.convert_usercertificate_post(entry_attrs, **options)
         convert_sshpubkey_post(ldap, dn, entry_attrs)
         radius_dn2pk(self.api, entry_attrs)
 
@@ -584,6 +606,7 @@ class baseuser_find(LDAPSearch):
         for attrs in entries:
             self.obj.convert_manager(attrs, **options)
             self.obj.get_password_attributes(ldap, attrs.dn, attrs)
+            self.obj.convert_usercertificate_post(attrs, **options)
             if (lockout):
                 attrs['nsaccountlock'] = True
             else:
@@ -598,5 +621,6 @@ class baseuser_show(LDAPRetrieve):
         assert isinstance(dn, DN)
         self.obj.convert_manager(entry_attrs, **options)
         self.obj.get_password_attributes(ldap, dn, entry_attrs)
+        self.obj.convert_usercertificate_post(entry_attrs, **options)
         convert_sshpubkey_post(ldap, dn, entry_attrs)
         radius_dn2pk(self.api, entry_attrs)
diff --git a/ipalib/plugins/user.py b/ipalib/plugins/user.py
index 0209b29b130f2377c04f497f95c8ad39e98f2587..61d174d82c077a5c9f945ebafa123569df75fea3 100644
--- a/ipalib/plugins/user.py
+++ b/ipalib/plugins/user.py
@@ -510,6 +510,7 @@ class user_add(baseuser_add):
             answer = self.api.Object['radiusproxy'].get_dn_if_exists(rcl)
             entry_attrs['ipatokenradiusconfiglink'] = answer
 
+        self.obj.convert_usercertificate_pre(entry_attrs, **options)
         return dn
 
     def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
@@ -557,6 +558,9 @@ class user_add(baseuser_add):
         convert_sshpubkey_post(ldap, dn, entry_attrs)
         radius_dn2pk(self.api, entry_attrs)
         self.obj.get_preserved_attribute(entry_attrs, options)
+
+        self.post_common_callback(ldap, dn, entry_attrs, **options)
+
         return dn
 
 
-- 
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