public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Alexander Bokovoy <abokovoy@redhat.com>
To: git-commits@fedoraproject.org
Subject: [rpms/freeipa] rawhide: Fine-tune permissions checks
Date: Mon, 07 Sep 2026 13:20:12 GMT [thread overview]
Message-ID: <178878721246.1.12913005766144279511.rpms-freeipa-3f63d99de891@fedoraproject.org> (raw)
A new commit has been pushed.
Repo : rpms/freeipa
Branch : rawhide
Commit : 3f63d99de891e7f99b67d0e6ffbbc6db950f7d1b
Author : Alexander Bokovoy <abokovoy@redhat.com>
Date : 2026-09-07T16:17:25+03:00
Stats : +123/-1 in 2 file(s)
URL : https://src.fedoraproject.org/rpms/freeipa/c/3f63d99de891e7f99b67d0e6ffbbc6db950f7d1b?branch=rawhide
Log:
Fine-tune permissions checks
Upstream PR#8558: https://github.com/freeipa/freeipa/pull/8558
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
---
diff --git a/freeipa-pr-8558.patch b/freeipa-pr-8558.patch
new file mode 100644
index 0000000..a9aa494
--- /dev/null
+++ b/freeipa-pr-8558.patch
@@ -0,0 +1,118 @@
+From 3c37b5ab9bdb0d1788180b586b5f814535d892cf Mon Sep 17 00:00:00 2001
+From: Alexander Bokovoy <abokovoy@redhat.com>
+Date: Mon, 7 Sep 2026 16:12:33 +0300
+Subject: [PATCH] Allow fine tuned privilege check
+
+Let users pass through the privilege check if either
+- whole entry read granted ('v' in the GER response)
+- at least one attribute read granted
+
+This is enough to allow LDAPRetrieve to pass, because the rest is
+controlled by the explicit ACIs in LDAP.
+
+Related: CVE-2026-79678
+
+Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
+---
+ ipaserver/plugins/baseldap.py | 27 ++++++++++++++++++++++-----
+ ipaserver/plugins/privilege.py | 29 +++++++++++++++++++++--------
+ 2 files changed, 43 insertions(+), 13 deletions(-)
+
+diff --git a/ipaserver/plugins/baseldap.py b/ipaserver/plugins/baseldap.py
+index d693c7112..e751dc673 100644
+--- a/ipaserver/plugins/baseldap.py
++++ b/ipaserver/plugins/baseldap.py
+@@ -1054,11 +1054,22 @@ last, after all sets and adds."""),
+ if not attrs:
+ return True
+ return any('w' in attr_rights.get(a, '') for a in attrs)
+- # read / search / compare
+- attrs = {a.lower() for a in perm.get('ipapermdefaultattr', ())}
+- if not attrs:
++ # read / search / compare: a read is never denied wholesale by
++ # 389-ds -- it returns the entry and silently filters out the
++ # individual attributes the caller may not see. Permit the
++ # operation whenever the caller can view the entry (entry-level
++ # 'v') or read *any* of its attributes. IPA's read ACIs are
++ # attribute-scoped, so an unprivileged caller reading its own entry
++ # gets 'entryLevelRights: none' yet can still read cn/sn/mail/...;
++ # requiring read on this permission's specific attributes would
++ # wrongly turn such a legitimate partial read into a total denial.
++ # Attribute-level confidentiality (e.g. the admin-only Kerberos
++ # login attributes) stays enforced by 389-ds on the read that
++ # follows. The probe always requests '*' (see
++ # _probe_effective_rights), so attr_rights reflects every attribute.
++ if 'v' in entry_rights:
+ return True
+- return any('r' in attr_rights.get(a, '') for a in attrs)
++ return any('r' in r for r in attr_rights.values())
+
+ modified_attrs = None # computed lazily, only for 'write'
+ for m in mp.keys():
+@@ -1214,8 +1225,14 @@ last, after all sets and adds."""),
+ continue
+ needed.update(a.lower() for a in perm.get('ipapermdefaultattr', ()))
+
++ # Always include '*' so the effective rights cover every attribute of
++ # the entry, not only the gated ones. The read/search/compare check
++ # needs to know whether the caller can read *any* attribute (an
++ # unprivileged caller may read its own entry without holding the
++ # object's read privilege), which cannot be answered from the gated
++ # attributes alone.
+ try:
+- rights = ldap.get_effective_rights(dn, sorted(needed) or ['*'])
++ rights = ldap.get_effective_rights(dn, sorted(needed | {'*'}))
+ except errors.NotFound:
+ return None
+
+diff --git a/ipaserver/plugins/privilege.py b/ipaserver/plugins/privilege.py
+index 47f27f12c..65199adc0 100644
+--- a/ipaserver/plugins/privilege.py
++++ b/ipaserver/plugins/privilege.py
+@@ -92,11 +92,28 @@ def principal_has_privilege(api, principal, privilege):
+ privilege_dn = api.Object.privilege.get_dn(privilege)
+ ldap = api.Backend.ldap2
+ if principal is None:
+- dn_or_princ = DN(ldap.conn.whoami_s()[4:])
+- if dn_or_princ == DN('cn=Directory Manager'):
++ # whoami reports the bound identity as an entry DN, not a Kerberos
++ # principal name. Check its privilege membership directly by DN: a
++ # 'krbprincipalname=<DN>' filter can never match and would always
++ # (wrongly) report the caller as lacking the privilege.
++ bound_dn = DN(ldap.conn.whoami_s()[4:])
++ if bound_dn == DN('cn=Directory Manager'):
+ return True
+- else:
+- dn_or_princ = principal
++ filter = ldap.make_filter(
++ {'memberof': privilege_dn}, rules=ldap.MATCH_ALL)
++ try:
++ ldap.find_entries(base_dn=bound_dn, scope=ldap.SCOPE_BASE,
++ filter=filter)
++ return True
++ except errors.ExecutionError:
++ # NotFound is the normal negative result (not a member, or the
++ # bound entry does not exist). Any other execution error (database
++ # error, limits, ...) cannot positively confirm the privilege
++ # either, and there is no Kerberos principal to fall back on for
++ # the ID override check below, so fail closed: not privileged.
++ return False
++
++ dn_or_princ = principal
+
+ # First try: Check if there is a principal that has the needed
+ # privilege.
+@@ -110,10 +127,6 @@ def principal_has_privilege(api, principal, privilege):
+ except errors.NotFound:
+ pass
+
+- # Do not run ID override check for the user that has no Kerberos principal
+- if principal is None:
+- return False
+-
+ # Second try: Check if there is an idoverride for the principal as
+ # ipaOriginalUid that has the needed privilege.
+ filter = ldap.make_filter(
+--
+2.55.0
+
diff --git a/freeipa.spec b/freeipa.spec
index c0e9e89..98f9e7b 100644
--- a/freeipa.spec
+++ b/freeipa.spec
@@ -211,7 +211,7 @@
Name: %{package_name}
Version: %{IPA_VERSION}
-Release: 1.1%{?rc_version:.%rc_version}%{?dist}
+Release: 1.2%{?rc_version:.%rc_version}%{?dist}
Summary: The Identity, Policy and Audit system
License: GPL-3.0-or-later
@@ -236,6 +236,7 @@ Source2: gpgkey-B40A78FBA576C4A3FC7D7BBC359FAF777296F653.asc
Patch0: freeipa-version-upgrade-fedora-only.patch
Patch1: freeipa-pr-8557.patch
+Patch2: freeipa-pr-8558.patch
# RHEL spec file only: START: Change branding to IPA and Identity Management
# Moved branding logos and background to redhat-logos-ipa-80.4:
@@ -1973,6 +1974,9 @@ fi
%endif
%changelog
+* Mon Sep 07 2026 Alexander Bokovoy <abokovoy@redhat.com> - 4.13.4-1.2
+- Fine-tune privilege checks (upstream PR 8558)
+
* Mon Sep 07 2026 Alexander Bokovoy <abokovoy@redhat.com> - 4.13.4-1.1
- Fix cross-forest trust identity confusion protection (upstream PR 8557)
reply other threads:[~2026-09-07 13:20 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178878721246.1.12913005766144279511.rpms-freeipa-3f63d99de891@fedoraproject.org \
--to=abokovoy@redhat.com \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox