From b3c2dd6c4ac5415b1518d26aa4631211a97b5d6b Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Wed, 9 Sep 2020 16:09:12 +0300
Subject: [PATCH 1/2] ipa-kdb: support getprincs request in kadmin.local

kadmin.local getprincs command results in passing '*' as a principal to
KDB driver function that looks up the principals.

The whole filter looks like this

 (&(|
    (objectclass=krbprincipalaux)
    (objectclass=krbprincipal)
    (objectclass=ipakrbprincipal))
   (|(ipakrbprincipalalias=*)
     (krbprincipalname:caseIgnoreIA5Match:=*)))

There are two parts of the LDAP filter we use to look up principals, the
part with 'krbprincipalname' uses extensible filter syntax of RFC 4515
section 3:

      extensible     = ( attr [dnattrs]
                           [matchingrule] COLON EQUALS assertionvalue )
                       / ( [dnattrs]
                            matchingrule COLON EQUALS assertionvalue )

In case we've got a principal name as '*' we have to follow RFC 4515
section 3 and reencode it using <valueencoding> rule from RFC 4511
section 4.1.6 but only to the part of the filter that does use assertion
value.

Fixes: https://pagure.io/freeipa/issue/8490

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
---
 daemons/ipa-kdb/ipa_kdb_principals.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c
index cdfb3223dc..39b6ca902d 100644
--- a/daemons/ipa-kdb/ipa_kdb_principals.c
+++ b/daemons/ipa-kdb/ipa_kdb_principals.c
@@ -966,6 +966,7 @@ ipadb_fetch_principals_with_extra_filter(struct ipadb_context *ipactx,
     krb5_error_code kerr;
     char *src_filter = NULL, *esc_original_princ = NULL;
     int ret;
+    int len = 0;
 
     if (!ipactx->lcontext) {
         ret = ipadb_get_connection(ipactx);
@@ -983,6 +984,8 @@ ipadb_fetch_principals_with_extra_filter(struct ipadb_context *ipactx,
         goto done;
     }
 
+    len = strlen(esc_original_princ);
+
     /* Starting in DAL 8.0, aliases are always okay. */
 #ifdef KRB5_KDB_FLAG_ALIAS_OK
     if (!(flags & KRB5_KDB_FLAG_ALIAS_OK)) {
@@ -996,12 +999,24 @@ ipadb_fetch_principals_with_extra_filter(struct ipadb_context *ipactx,
     } else
 #endif
     {
+        /* In case we've got a principal name as '*' we have to
+         * follow RFC 4515 section 3 and reencode it using
+         * <valueencoding> rule from RFC 4511 section 4.1.6 but
+         * only to the part of the filter that does use assertion
+         * value. */
+        const char *asterisk = "%x2A";
+        char *assertion_value = esc_original_princ;
+
+        if ((len == 1) && (esc_original_princ[0] == '*')) {
+            assertion_value = asterisk;
+        }
+
         if (filter == NULL) {
             ret = asprintf(&src_filter, PRINC_TGS_SEARCH_FILTER,
-                           esc_original_princ, esc_original_princ);
+                           esc_original_princ, assertion_value);
         } else {
             ret = asprintf(&src_filter, PRINC_TGS_SEARCH_FILTER_EXTRA,
-                           esc_original_princ, esc_original_princ, filter);
+                           esc_original_princ, assertion_value, filter);
         }
     }
 

From 6bcbe3c468e790fbb66599631d82175350cf0dbe Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Wed, 9 Sep 2020 16:26:56 +0300
Subject: [PATCH 2/2] ipa-kdb: test kadmin.local getprincs command

Fixes: https://pagure.io/freeipa/issue/8490
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
---
 ipatests/test_ipaserver/test_kadmin.py | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/ipatests/test_ipaserver/test_kadmin.py b/ipatests/test_ipaserver/test_kadmin.py
index 5ef565cc18..ab32f6c3f6 100644
--- a/ipatests/test_ipaserver/test_kadmin.py
+++ b/ipatests/test_ipaserver/test_kadmin.py
@@ -123,3 +123,9 @@ def test_append_key(self, service, keytab):
             installutils.create_keytab,
             keytab,
             service)
+
+    def test_getprincs(self):
+        """
+        tests that kadmin.local getprincs command returns a list of principals
+        """
+        self.assert_success(installutils.kadmin, 'getprincs')
