342 Commits
Author SHA1 Message Date
zpericic 42d0bb0805 ipaserver: Move /etc/httpd/ipa to /etc/ipa/httpd 2026-06-25 10:04:50 +02:00
zpericic 024b410710 ipaserver: Use apache VirtualHost for IPA UI 2026-06-25 10:04:50 +02:00
Antonio Torres 96ea6f94c8 Become IPA 4.12.5
Signed-off-by: Antonio Torres <antorres@redhat.com>
2025-09-30 10:22:09 +02:00
Florence Blanc-Renaud 20c03a3e89 ipatests: extend test for unique krbcanonicalname
Add a test ensuring that root@REALM cannot be added as
krbcanonicalname

Add a test for PAC enforcement:
try to access a service using a TGT obtained without PAC.
Should fail as PAC is now enforced.

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
2025-09-30 10:21:25 +02:00
Julien Rische bb24703a18 ipa-kdb: enforce PAC presence on TGT for TGS-REQ
MS-KILE's PA-PAC-REQUEST sequence allows the Kerberos client to request
a TGT without a PAC. At the moment, there is no way to configure the MIT
KDC to reject such request.

This commit enforces the presence of the PAC when processing TGTs
provided by TGS-REQ. It ensures the server principal of the TGT is the
same as the one in PAC_CLIENT_INFO (i.e. enforces client principal
canonicalization) with integrity check.

Only one exception is applied: this check is skipped for local TGTs on
domain where the MS-PAC generator is not initialized (i.e. domains where
SID generation was not executed yet).

Signed-off-by: Julien Rische <jrische@redhat.com>
2025-09-30 10:21:19 +02:00
Rob Crittenden 67a9d537e3 Enforce uniqueness across krbprincipalname and krbcanonicalname
This relies on a fix in 389-ds that extends the uniqueness plugin
to be able to compare attributes with different matching syntax.

This will prevent privilege escalation attacks if one of the
attributes is not set on an entry if it is set elsewhere.

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
2025-09-30 10:20:32 +02:00
Antonio Torres f2fc367fb0 Become IPA 4.12.4 2025-06-17 09:14:30 +02:00
Rob Crittenden e8c410ae5f Set krbCanonicalName=admin@REALM on the admin user
The admin must always own this name. If another entry has this
value set then remove it.

There is a uniqueness plugin for this attribute so the only two
possibilities are:

- no entry has this value set
- the admin user has this value set
- a different entry has the value set

Still, for robustness purposes, the upgrade plugin will handle
more entries.

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
2025-06-17 09:11:34 +02:00
Julien Rische 6ae52a2fb4 kdb: keep ipadb_get_connection() from succeeding with null LDAP context
The final call to ipadb_reinit_mspac() in ipadb_get_connection() is not
considered essential for the function to succeed, as there might be
cases where the required pieces of information to generate PACs are not
yet configured in the database. However, in environments where 389ds is
overwhelmed, the LDAP connection established at the beginning of
ipadb_get_connection() might already be lost while executing
ipadb_reinit_mspac().

Connection errors were not distinguished from configuration errors,
which could result in ipadb_get_connection() succeeding while the LDAP
context is set to null, leading to a KDC crash on the next LDAP request.

ipadb_get_connection() now explicitly checks the value of the LDAP
context before returning.

Fixes: https://pagure.io/freeipa/issue/9777
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2025-06-17 09:08:19 +02:00
Antonio Torres f33a0e8e71 Become IPA 4.12.3 2025-01-15 12:01:25 +01:00
Sumit Bose 7a5a10b6bf ipa-otpd: use oidc_child's --client-secret-stdin option
To remove the client secret from the command line where it would be
visible e.g. when calling ps it is now passed via stdin to oidc_child.

Fixes: CVE-2024-11029

Signed-off-by: Sumit Bose <sbose@redhat.com>
2025-01-15 11:15:39 +01:00
Alexander Bokovoy 3b38efe758 ipa tools: remove sensitive material from the commandline
When command line tools accept passwords, remove them from the command
line so that they don't get visible in '/proc/pid/commandline'.

There is no common method to access the original ARGV vector and modify
it from Python. Since this mostly affects Linux systems where IPA
services run, we expect use of GNU libc and thus can rely on internal
glibc symbols. If they aren't available, the code will skip removing
passwords.

Fixes: CVE-2024-11029

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
2025-01-15 11:15:39 +01:00
Alexander Bokovoy cf84a22228 Unify use of option parsers
Do not use direct optparse references, instead import IPAOptionParser

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
2025-01-15 11:15:09 +01:00
Rob Crittenden c7da7e0dc9 Become IPA v4.12.2 2024-08-21 11:06:37 -04:00
Sudhir Menon f5c7237204 ipatests: Test to check that the configured value for "nsslapd-ignore-time-skew" remains on even after a "force-sync" is done
Related: https://pagure.io/freeipa/issue/9635

Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-08-21 16:59:22 +02:00
Sudhir Menon ed813fe6f0 ipatests: Replace 'usermod -r' command with 'gpasswd -d' in test_hsm.py
Test 'test_hsm_negative_bad_token_dir_permissions'
was failing in RHEL because of the below error.

"ipa: ERROR: stderr: usermod: invalid option -- 'r'"

Hence replaced the usermod with gpasswd command which does the same and
works on both RHEL and Fedora.

Ref: https://pagure.io/freeipa/issue/9626

Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-08-16 17:14:03 +02:00
Rob Crittenden 21c6ccc982 Fix some resource leaks identified by a static analyzer
Fixes: https://pagure.io/freeipa/issue/9367

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2024-08-16 07:18:33 +02:00
Rob Crittenden d0684a7ecf Ignore TripleDES python-cryptography import warnings
TripleDES will be deprecated in python-cryptography 48.0.0. We
have code that uses it if it is available and otherwise ignores
it.

Because this gets imports in constants.py this warning is promiment
pretty much everywhere. So let's ignore it since we already handle
the issue.

Related: https://pagure.io/freeipa/issue/9641

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-08-15 10:03:40 +02:00
Rob Crittenden 5cc7941f30 Correct usage of public_key_algorithm_oid in ipalib/x509
public_key_algorithm_oid is property of underlying Certificate object
that is not supposed to be callable. I missed that it contained
() at the end.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-08-15 10:03:40 +02:00
Florence Blanc-Renaud f37c2eb878 trust-add: handle unavailable domain
When ipa trust-add fails to retrieve the remote domain information,
it exits with "an internal error has occurred".
Handle the case with a better error message.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-08-14 18:34:48 +02:00
Florence Blanc-Renaud 1fc63e2b51 HSM: fix the module name
During the server installation, the installer checks if the
SElinux policy module for the specific hardware is detected. The
current code mixed up SElinux policy module name and RPM
package name and resulted in a false warning that the module
was missing.

The module name is ipa-nfast or ipa-luna, not ipa-selinux-nfast
or ipa-selinux-luna.
The name is defined in the spec file as %{module}-nfast
and module=ipa.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-08-14 17:05:16 +02:00
Florence Blanc-Renaud 84751a26a9 ipatests: skip HSM test if pki < 11.5.9
The test TestHSMNegative should be skipped if PKI is too old,
but its uninstall method does not check the PKI version.

Add a call to check_version in the class uninstall method.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2024-08-12 07:42:33 +02:00
Sudhir Menon 8046023fc4 ipatests: ipa-migrate tool with -Z option (CACERTFILE)
This patch add tests to check the scenarios associated with
pagure tickets

https://pagure.io/freeipa/issue/9642 - ipa-migrate - properly handle invalid certificates
https://pagure.io/freeipa/issue/9619 - ipa-migrate starttls does not work

Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-08-08 16:20:26 +02:00
Mohammad Rizwan ee96c129a6 ipatests: Verify that SIDgen task continue even if it fails to assign sid
related: https://pagure.io/freeipa/issue/9618

Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-08-08 13:37:42 +02:00
Florence Blanc-Renaud 81401e6c01 ipatests: increase the timeout for test_hsm.py::TestHSMInstall
The test is often failing on timeout. Add 15min to the test definitions.

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-08-05 21:23:27 +02:00
Rob Crittenden e83d949c7f Log errors reported by adtrustinstance.check_inst() using logger
It previously only printed the issue which made troubleshooting
after the fact difficult. Using logger.error() provides the same
visual functionality but also logs to the server install log.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-08-05 14:52:12 +02:00
Rob Crittenden ffba69648a Force a logout in KerberosSession if a login is needed
Remove the client side cookie if a user possesses an IPA session
cookie and the associated credentials can't be found on the
server.

This handles the case where the ccaches are removed for some reason
(maybe cleanup, maybe a container was restarted) and allows for
a successful SSO if the user's Kerberos ticket is still valid.

Without this change the user is always dropped into a the
username/password dialog. The only workaround is to remove
the cookie on the client side.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-08-05 14:50:10 +02:00
Florence Blanc-Renaud aadb8051d4 Replica CA installation: ignore time skew during initial replication
During a replica CA installation, the initial replication step may fail
if there is too much time skew between the server and replica.

The replica installer already takes care of this for the replication of
the domain suffix but the replica CA installer does not set
nssldapd-ignore-time-skew to on for o=ipaca suffix.

During a replica CA installation, read the initial value of
nssldapd-ignore-time-skew, force it to on, start replication and
revert to the initial value.

Apply the same logic to dsinstance and ipa-replica-manage force-sync.

Fixes: https://pagure.io/freeipa/issue/9635
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-08-01 09:51:11 +02:00
Alexander Bokovoy 7b5f3d7971 Get rid of unicode and long helpers in ipa-otptoken-import
Related: https://pagure.io/freeipa/issue/9641

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-31 16:20:31 -04:00
Alexander Bokovoy fc02904340 ipalib/constants.py: factor out TripleDES use
Cryptography 43 started to warn that in version 48 it will remove
TripleDES support. Change the code to detect missing TripleDES algorithm
and do not fail.

Related: https://pagure.io/freeipa/issue/9641

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-31 16:20:31 -04:00
Alexander Bokovoy 7f9c890c04 ipalib/x509.py: get rid of unicode helper
Pylint started to complain that 'unicode' variable is accessed before
definition. This is clearly a bug in how 'six' and pylint are working
together.

Replace use of 'unicode()' by 'str()'.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-31 16:20:31 -04:00
Alexander Bokovoy 531bd05de9 ipalib/x509.py: support Cryptography 43
Cryptography 43 added two new abstract methods to Certificate class of
which we are using one, public_key_algorithm_oid.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-31 16:20:31 -04:00
Rob Crittenden 38b83c2b93 Run HSM validation as pkiuser to verify token permissions
Run all commands as pkiuser when validating that the HSM token
is available, that the token library path is correct and that
the password can read keys. This will avoid issues where the
initial validation is ok but the pkiuser is not granted read
access to some part of the token. This is very possible
when using softhsm2.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-07-31 16:19:02 -04:00
Rob Crittenden f03a96a7b9 ipatests: Fix usage of token_password_file
There were a few hardcoded places where it was set to
/tmp/token_passwd instead of using the class variable.

Don't rely on previous running tests installing the token
password file so they can be run individually.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-07-31 16:17:27 -04:00
Mark Reynolds 0e4fbc3b0d ipa-migrate - properly handle invalid certificates
A ValueError is raised when an invalid certificate is used, so the tool
should handle this properly and not produce a stack trace.

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

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-31 16:14:49 -04:00
Florence Blanc-Renaud 2ddca5d5d5 spec file: do not use nodejs-22 on f39 and f40
Nodejs22 has been released on f39 and f40 and freeipa fails
to build with this version. Nodejs22 will be the default version
in f41+ and adds a symlink from /usr/bin/node-22 to /usr/bin/node
but on older fedora versions, the symlink is not created.
As our build is using /usr/bin/node command, it fails with
command not found.

Stick to Nodejs 20 on these older versions.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-31 08:25:30 +02:00
Rob Crittenden fdd471d55c Fix a copy/paste issue when detecting the HSM SELinux subpackage
I made a mistake when trying to detect which HSM is being used
to ensure that the appropriate SELinux subpackage is installed.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-07-22 09:57:34 -04:00
Julien Rische 9f88188204 Remove RC4 and 3DES default encryption types on update
Fixes: https://pagure.io/freeipa/issue/9633

Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-07-19 08:44:49 -04:00
Julien Rische d1a485a435 Unconditionally add MS-PAC to global config on update
Fixes: https://pagure.io/freeipa/issue/9632

Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-07-19 08:44:49 -04:00
Florence Blanc-Renaud 6eb6a92930 ipatests: remove xfail for test_ipa_migrate_stage_mode
The test test_ipa_ipa_migration.py::TestIPAMigrateScenario1
::test_ipa_migrate_stage_mode is now passing, the issue has been fixed.

Related: https://pagure.io/freeipa/issue/9621

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Sudhir Menon <sumenon@redhat.com>
2024-07-19 08:39:21 -04:00
Florence Blanc-Renaud de940802bb ipatests: remove xfail for test_ipa_migrate_version_option
The test test_ipa_ipa_migration.py::TestIPAMigrateScenario1::
test_ipa_migrate_version_option is now passing, issue has been fixed.
The -V option has been removed.

Related: https://pagure.io/freeipa/issue/9620

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Sudhir Menon <sumenon@redhat.com>
2024-07-19 08:39:21 -04:00
Mark Reynolds 85a853ba93 Issue 9621 - ipa-migrate - should not update mapped attributes in managed entries
We should not migrate mmapped attributes (uidNumber, gidNumber) from
managed entries

We should also not migrate DNA ranges in staging mode

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

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-17 09:17:17 +02:00
Anuja More 8b703150a4 ipatests: Test replica installation using AD admin.
Test to verify that replica connection check is not failing when
the AD administrator Administrator@AD.EXAMPLE.COM is
used for the deployment or promotion of a replica

Related: https://pagure.io/freeipa/issue/9542

Signed-off-by: Anuja More <amore@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-07-17 09:11:13 +02:00
Alexander Bokovoy 051d61fdc3 ipa-pwd-extop: differentiate OTP requirements in LDAP binds
For users who has no OTP tokens defined (yet), a missing token should
not be seen as a failure. This is needed to allow a basic password
change.

The logic around enforcement of OTP over LDAP bind is the following:
----------------------------------------------------------------------
- when LDAP OTP control is requested by the LDAP client, OTP is
  explicitly required
- when EnforceLDAPOTP is set in the IPA configuration, OTP is implicitly
  required, regardless of the state of LDAP client

In either case, only users with 'user-auth-type: otp' are allowed to
authenticate.

If these users have no OTP token associated yet, they will be allowed to
authenticate with their password. This is to allow initial password
change and adding an OTP token.
----------------------------------------------------------------------

Implement test that simulates lifecycle for new user who get to change
their password before adding an OTP token.

Related: https://pagure.io/freeipa/issue/5169

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-17 09:06:14 +02:00
Sudhir Menon ab47696fa6 Added new testsuite(ipa_ipa_migration) in prci definitions
Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-15 17:26:53 -04:00
Mark Reynolds eeade50933 ipa-migrate - starttls does not work
We were previousily taking the provided ca cert and creating a temporary
file from it. This was incorrect and caused the secure connection to
fail.  Instead just use the file path provided.

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

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-07-15 17:22:19 -04:00
Rob Crittenden 6c53a22a2c Include token password options in ipa-kra-install man page
Related: https://pagure.io/freeipa/issue/9603

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-07-15 10:26:54 -04:00
Mohammad Rizwan 4ea1ad6aca ipatests: tests related to --token-password-file
Test automation added around the --token-password-file
option for server/replica/kra install.

Related: https://pagure.io/freeipa/issue/9603

Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-07-15 10:26:54 -04:00
Rob Crittenden 7ab1bcb2d3 Re-organize HSM validation to be more consistent/less duplication
hsm_validator() was more or less bolted in place late in the
development cycle in in order to catch some of the more common
problems: bad token name, bad password, etc.

There was a fair bit of duplication and had the side-effect of not
reading in the token password from the --token-password-file option
in some cases.

This patch also re-adds a lost feature where an exception is raised if
both the --token-password and --token-password-file options are passed
in.

This also needs to be enforced on initial server, replica and when
called by ipa-kra-install. Given that each has a unique subject of
options some duplication remains.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-07-15 10:26:54 -04:00
Rob Crittenden 1b278de4ab Fix syntax error in the selinux-luna %postun script
It was missing a trailing fi.

This bad syntax was preventing cleanup of the
{free}ipa-selinux-luna SELinux module:

Running scriptlet: freeipa-selinux-luna-4.12.0.dev202402211727+git0ee   34/44
/var/tmp/rpm-tmp.qoCDFi: line 16: syntax error: unexpected end of file
warning: %postun(freeipa-selinux-luna-4.12.0.dev202402211727+git0eeecdcec-0.fc37.noarch) scriptlet failed, exit status

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-07-12 08:32:35 +02:00
Mark Reynolds efa5719363 ipa-migrate - remove -V option
The versioning in ipa-migrate was removed, but the "-V" option to display the version was not removed.

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

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-11 13:59:16 +02:00
Shunsuke matsumoto 06c02f5f2c The -d option of the ipa-advise command was able to used.
The -d option of the ipa-advise command was unavailable, so the default value was changed to True to enable its use.

Fixes: https://pagure.io/freeipa/issue/9625
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-07-11 10:30:59 +02:00
Thomas Woerner a8e75bbb77 ipa_sidgen: Allow sidgen_task to continue after finding issues
find_sid_for_ldap_entry could fail in several ways if a Posix ID can not
be converted to an unused SID. This could happen for example for ducplicate
IDs or user/group out of range.

This change enables ipa_sidgen_task to continue in the error case to try
to convert the entries without errors. The error messages have been
extended to additionally show the DN string for the bad entries.

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

Signed-off-by: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-07-08 16:39:16 +02:00
Florence Blanc-Renaud d635d70110 test_replica_install_after_restore: kinit after restore
After uninstall and restore, kinit is required before
launching any ipa command.

Related: https://pagure.io/freeipa/issue/9613
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-08 15:26:24 +02:00
Florence Blanc-Renaud 6fe268af5b Uninstall: stop sssd-kcm before removing KCM ccaches database
The service is socket-activated and will be restarted whenever
needed. It must be stopped before the database is removed
otherwise it fails to recreate the file.

Fixes: https://pagure.io/freeipa/issue/9616
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-08 15:26:24 +02:00
Florence Blanc-Renaud 2f902efd0e ipa-ods-enforcer: stop must also stop the socket
ipa-ods-enforcer is a socket-activated service. In order to fully stop
the service, IPA needs to call
systemctl stop ipa-ods-enforcer.service ipa-ods-enforcer.socket
otherwise the socket remains active (listening) and can restart the
service.

A consequence of the issue is the backup / uninstall / restore
scenario that is failing to sign the zones. The uninstaller removes
the socket /run/opendnssec/engine.sock but leaves the ipa-ods-enforcer.socket
active. A subsequent restore or install will not re-create the socket.

Fixes: https://pagure.io/freeipa/issue/9613
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-07-08 15:26:24 +02:00
Sudhir Menon 90b22ff888 ipatests: Tests for ipa-ipa migration tool
This patch includes tests for ipa-ipa migration
tool

Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Mark Reynolds <mreynolds@redhat.com>
2024-07-08 15:21:04 +02:00
TAKAHASHI Masatsuna 52ea4ad46e ipa-advise ipa-backup ipa-restore: Fix --v option of the manual.
Specifying the --v option results in an error.
The --v option is incorrect and should be -v.

Fixes: https://pagure.io/freeipa/issue/9617
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-07-04 17:48:04 +02:00
Florence Blanc-Renaud 48ff7da5cb ipatests: fix / permissions for test_nested_group_members
The test test_nested_group_members is performing a ssh login
with a private key and this command may fail if the root directory
does not have the right permissions on the ssh server
(see https://access.redhat.com/solutions/6798261)

Ensure that / has 755 before launching the test.

Fixes: https://pagure.io/freeipa/issue/9615
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2024-07-02 08:53:03 +02:00
Rob Crittenden 9e364910f5 Clean up more files and directories created by the installer(s)
Ideally all files created during an IPA server installation are
removed by the uninstaller. Some files are purposefully left,
like token passwords, private keys, logs and more. Add an
allow list for those files.

Include a test to catch any additional files that may be created
and left behind.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-06-26 13:30:48 +02:00
Florence Blanc-Renaud 60c127d197 ipatests: fix / permissions to allow ssh with private key
The test test_ssh_key_connection is performing a ssh login
with a private and this command may fail if the root directory
does not have the right permissions on the ssh server
(see https://access.redhat.com/solutions/6798261)

Ensure that / has 755 before launching the test.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2024-06-26 09:50:34 +02:00
Florence Blanc-Renaud 4521fe5f91 ipatests: mark test_ca_show_error_handling as xfail
With PKI 11.5.0, the test
 test_cert.py::TestCAShowErrorHandling::test_ca_show_error_handling
is failing with an exception and a different error message.
Mark as xfail until PKI provides a fix

Related: https://pagure.io/freeipa/issue/9606
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2024-06-26 09:50:34 +02:00
Florence Blanc-Renaud 58154be74f ipatests: configure gating and nightly tests on ipa-4-12 branch
Update the pipelines for ipa-4-12 branch:
- run tests on fedora 40
- use the vagrant image freeipa/ci-ipa-4-12-f40

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2024-06-26 09:50:34 +02:00
Florence Blanc-Renaud 467ec04f93 ipatests: add test for PKINIT renewal on hidden replica
Test scenario: on a hidden replica, force the renewal of
PKINIT cert by calling getcert resubmit.

Related: https://pagure.io/freeipa/issue/9611
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-06-26 07:36:53 +02:00
Florence Blanc-Renaud c8e3fdeb00 PKINIT certificate: fix renewal on hidden replica
The renewal of PKINIT cert on hidden replica is failing because
of a test ensuring that the KDC service is either enabled or
configured. The test needs to be extended and allow hidden, too.

Fixes: https://pagure.io/freeipa/issue/9611
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-06-26 07:36:53 +02:00
Florence Blanc-Renaud 4d51446bd3 ipatests: add test for ticket 9610
Test scenario:
- ensure there is no /etc/ssh/ssh_config.orig file
- force ipa-client package reinstallation
- ensure no backup file is created in /etc/ssh/ssh_config.orig

Related: https://pagure.io/freeipa/issue/9610
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2024-06-24 14:51:38 +02:00
Florence Blanc-Renaud 09e66dc936 spec file: do not create /etc/ssh/ssh_config.orig if unchanged
The upgrade removes the line
HostKeyAlgorithms ssh-rsa,ssh-dss
if present in /etc/ssh/ssh_config and creates a backup in
/etc/ssh/ssh_config.orig, even if no change was applied.

Create the backup file only if the file was changed.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2024-06-24 14:51:38 +02:00
Florence Blanc-Renaud 9de053ef02 ipa-otptoken-import: open the key file in binary mode
ipa-otptoken-import provides an option (-k KEYFILE) to import
an encrypted PSKC file but this option does not work with python3
in RHEL8 and above, because the key should be passed in binary
format to the cryptography functions instead of string format.

Open the keyfile in binary mode to pass the expected format.

Fixes: https://pagure.io/freeipa/issue/9609
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-06-18 08:46:14 +02:00
Rob Crittenden ebccaac3cf Add iparepltopoconf objectclass to topology permissions
The domain and ca objects were unreadable which caused
the conneciton lines between nodes in the UI to not be
visible.

Also add a manual ACI to allow reading the min/max
domain level.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2024-06-12 16:43:25 -04:00
Rob Crittenden 584d0cecbc Use a unique task name for each backend in ipa-backup
The name used to be "export_%Y_%m_%d_%H_%M_%S" so if the tasks
were added within the same second the second backend would fail.

Add the backend name to the task name to ensure uniqueness.
export_{backend}_%Y_%m_%d_%H_%M_%S

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Mark Reynolds <mreynolds@redhat.com>
2024-06-10 14:59:18 -04:00
Antonio Torres 5b3735b09d Bump minor version number
Signed-off-by: Antonio Torres <antorres@redhat.com>
2024-06-10 12:46:37 +02:00
Julien Rische 4a61184da6 kdb: apply combinatorial logic for ticket flags
The initial design for ticket flags was implementing this logic:
* If a ticket policy is defined for the principal entry, use flags from
  this policy if they are set. Otherwise, use default ticket flags.
* If no ticket policy is defined for the principal entry, but there is a
  global one, use flags from the global ticket policy if they are set.
  Otherwise, use default ticket flags.
* If no policy (principal nor global) is defined, use default ticket
  flags.

However, this logic was broken by a1165ffb which introduced creation of
a principal-level ticket policy in case the ticket flag set is modified.
This was typically the case for the -allow_tix flag, which was set
virtually by the KDB driver when a user was locked until they initialize
their password on first kinit pre-authentication.

This was causing multiple issues, which are mitigated by the new
approach:

Now flags from each level are combined together. There flags like
+requires_preauth which are set systematically by the KDB diver, as
well as -allow_tix which is set based on the value of "nsAccountLock".
This commit also adds the implicit -allow_svr ticket flag for user
principals to protect users against Kerberoast-type attacks. None of
these flags are stored in the LDAP database, they are hard-coded in the
KDB driver.

In addition to these "virtual" ticket flags, flags from both global and
principal ticket policies are applied (if these policies exist).

Principal ticket policies are not supported for hosts and services, but
this is only an HTTP API limitation. The "krbTicketPolicyAux" object
class is supported for all account types. This is required for ticket
flags like +ok_to_auth_as_delegate. Such flags can be set using "ipa
host-mod" and "ipa serivce-mod", or using kadmin's "modprinc".

It is possible to ignore flags from the global ticket policy or default
flags like -allow_svr for a user principal by setting the
"final_user_tkt_flags" string attribute to "true" in kadmin. In this
case, any ticket flag can be configured in the principal ticket policy,
except requires_preauth and allow_tix.

When in IPA setup mode (using the "ipa-setup-override-restrictions" KDB
argument), all the system described above is disabled and ticket flags
are written in the principal ticket policy as they are provided. This is
required to initialize the Kerberos LDAP container during IPA server
installation.

This fixes CVE-2024-3183

Signed-off-by: Julien Rische <jrische@redhat.com>
2024-06-10 12:46:05 +02:00
Julien Rische f77c0a573c kdb: fix vulnerability in GCD rules handling
The initial implementation of MS-SFU by MIT Kerberos was missing a
condition for granting the "forwardable" flag on S4U2Self tickets.
Fixing this mistake required adding special case for the
check_allowed_to_delegate() function: if the target service argument is
NULL, then it means the KDC is probing for general constrained
delegation rules, not actually checking a specific S4U2Proxy request.

In commit e86807b5, the behavior of ipadb_match_acl() was modified to
match the changes from upstream MIT Kerberos a441fbe3. However, a
mistake resulted in this mechanism to apply in cases where target
service argument is set AND unset. This results in S4U2Proxy requests to
be accepted regardless of the fact there is a matching service
delegation rule or not.

This vulnerability does not affect services having RBCD (resource-based
constrained delegation) rules.

This fixes CVE-2024-2698

Signed-off-by: Julien Rische <jrische@redhat.com>
2024-06-10 12:46:05 +02:00
Antonio Torres ea37593786 Back to git snapshots
Signed-off-by: Antonio Torres <antorres@redhat.com>
2024-05-28 16:26:57 +02:00
Antonio Torres 407408e9a8 Become IPA 4.12.0 2024-05-28 16:19:49 +02:00
Antonio Torres c250b1a7e4 Update list of contributors
Signed-off-by: Antonio Torres <antorres@redhat.com>
2024-05-28 16:13:33 +02:00
Antonio Torres b3789876b8 Update translations to FreeIPA master state
Signed-off-by: Antonio Torres <antorres@redhat.com>
2024-05-28 16:11:04 +02:00
Florence Blanc-Renaud 69c6a817ce ipa-replica-manage list-ruvs: display FQDN in the output
The behavior of ipa-replica-manage list-ruv was modified with
the commit 544652a and now displays host short names instead
of FQDN:port.
Fix the regular expression in order to return the FQDN:port again.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abbra@users.noreply.github.com>
2024-05-28 14:39:33 +02:00
Alexander Bokovoy 1223016ef2 console: for public errors only print a final one
By default, interactive console prints full traceback in case of an
error. This looks weird in the console when LDAP errors pop up.
Instead, process PublicError exceptions as if they are final ones and
only print their message.

As a result, calls like api.Command.user_show('unknown') would
result in a concise message:

  >>> api.Command.user_show('unknown')
  IPA public error exception: NotFound: unknown: user not found
  >>>

rather than a two-screen long traceback.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-05-28 11:14:35 +02:00
Alexander Bokovoy 5368120805 custodia: do not use deprecated jwcrypto wrappers
jwcrypto has turned JWK object into a dict-like structure in 2020 and
marked data wrappers as deprecated. The only exception for direct
foo['bar'] access is a key ID -- some keys might have no 'kid' property,
thus it is best to use jwk.get('kid') instead for those.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-05-23 15:12:27 -04:00
Alexander Bokovoy 84eed2a67f frontend: add systemd journal audit of executed API commands
For each executed command in server context, send the information about
the command to the systemd journal. The resulting string is similar to
what is recored in httpd's error_log for API requests coming through the
RPC layer.

In server mode operations are performed directly on the server over
LDAPI unix domain socket, so httpd end-point is not used and therefore
operations aren't recorded in the error_log.

With this change any IPA API operation is sent as an audit event to the
journal, alog with additional information collected by the journald
itself.

To aid with identification of these messages, an application name is
replaced with IPA.API and the actual name from api.env.script is made a
part of the logged message. The actual application script name is
available as part of the journal metadata anyway.

If no Kerberos authentication was used but rather LDAPI autobind was in
use, the name of the authenticated principal will be replaced with
[autobind].

Messages sent with syslog NOTICE priority.

More information is available in the design document 'audit-ipa-api.md'

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-05-22 17:06:23 -04:00
Alexander Bokovoy 145e33174d ipalib/rpc: Reformat after moving json code around
Context changes cause linters to complain for older code formatting

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-05-22 17:06:23 -04:00
Alexander Bokovoy fd0f432fec ipalib: move json formatter to a separate file
To prevent cyclic imports, move JSON handling code to a separate file.

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-05-22 17:06:23 -04:00
Alexander Bokovoy 9e861693fc batch: add keeponly option
batch(methods=Dict(), keeponly=list) will allow to execute batch of
commands and remove from the output everything but the attributes which
names were passed in the keeponly list.

This can be useful if you are only interested in getting names and
assigned random passwords, for example.

Fix batch API test in test_integration/test_idm_api.py and use it to
validate keeponly option.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-05-22 10:03:38 +02:00
Alexander Bokovoy 6cc0a0b9a8 pylint: use yield_from for trivial cases
Follow pylint recommendations (turned errors in recent pylint updates)
and use PEP-380 syntax for subgenerators. This is supported by all
Python 3 versions since ~2011.

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-05-22 10:03:38 +02:00
Alexander Bokovoy c325f9c045 user: handle LDAP auto-bind for whoami case
In LDAP auto-bind situation we will not have a Kerberos principal
available, so we should be using a different mechanism to find the
object. Since we already have a valid bound LDAP DN, use it as a base DN
here and simply require presence of the POSIX account.

This will not match 'cn=Directory Manager' but none of the code we have
uses LDAP auto-bind as root when calling 'ipa user-find --whoami'.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-05-22 10:03:38 +02:00
Alexander Bokovoy 902c8b0bae passwd: handle LDAP auto-bind use case as well
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-05-22 10:03:38 +02:00
Alexander Bokovoy e386e22046 cert: use context.principal only when it is defined
In server-like context we use LDAPI connection with auto-binding to LDAP
object based on the UID of the process connecting to LDAPI UNIX domain
socket. This means context.principal is not set and we cannot use it.

When processing certificate issuance requests a care has to be done to
match operations done as LDAP auto-bind to actual principals for
validation. This is a tough one as we have no principal to match for
cn=Directory Manager. Use fake principal to fail validation here and
rely on LDAP ACIs instead.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-05-22 10:03:38 +02:00
Alexander Bokovoy b6131b5737 trust: handle stray pylint warning
We only get to this code path when running in the server context. At
that point _bindings_installed will be defined. Pylint cannot track this
and always fails with this check.

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-05-22 10:03:38 +02:00
Alexander Bokovoy 08f1e6f2fd trust: use context.principal only when it is defined
In server-like context we use LDAPI connection with auto-binding to LDAP
object based on the UID of the process connecting to LDAPI UNIX domain
socket. This means context.principal is not set and we cannot use it.

Make sure to reject requests unless we are operating as a Directory
Manager in such cases.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-05-22 10:03:38 +02:00
Alexander Bokovoy ab5465639d server: use context.principal only when it is defined
In server-like context we use LDAPI connection with auto-binding to LDAP
object based on the UID of the process connecting to LDAPI UNIX domain
socket. This means context.principal is not set and we cannot use it.

Make sure to reject requests unless we are operating as a Directory
Manager in such cases.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-05-22 10:03:38 +02:00
Alexander Bokovoy 71d886f071 config: use context.principal only when it is defined
In server-like context we use LDAPI connection with auto-binding to LDAP
object based on the UID of the process connecting to LDAPI UNIX domain
socket. This means context.principal is not set and we cannot use it.

Make sure to reject requests unless we are operating as a Directory
Manager in such cases.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-05-22 10:03:38 +02:00
Alexander Bokovoy 3608b2b63d batch: account for auto-binding in server context
When batch runs under server context, we have no context.principal set
because we talk directly to LDAPI endpoint and authenticate using
auto-binding, not GSSAPI. Account to that in the logger.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-05-22 10:03:38 +02:00
Alexander Bokovoy 295ac6385c privilege: use context.principal only when it is defined
In server-like context we use LDAPI connection with auto-binding to LDAP
object based on the UID of the process connecting to LDAPI UNIX domain
socket. This means context.principal is not set and we cannot use it.

In principal_has_privilege() we can take None principal object as a sign
that currently bound LDAP DN has to be checked for the privilege. This
allows to match any type of account to the privilege, with exception of
the cn=Directory Manager which is never added to privileges explicitly.

cn=Directory Manager will be allowed any privilege because it already
can write to any LDAP entry.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-05-22 10:03:38 +02:00
Rob Crittenden 6fc35156d9 Add permissions for topologysegment
I don't know why these weren't added originally when the
topology plugin was created.

Add them all to the 'Replication Administrators' privilege

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-05-22 10:00:39 +02:00
Thomas Woerner 9dc57ef77e idviews: Use ipaAnchorUUID without DCERPC bindings for SID anchors
SID anchors are only resolvable on servers with DCERPC bindings
installed. On non agent replica these bindings are not installed and
therefore group and role management if there are AD user idoverride
members.

If there is an ipaUserOverride for the anchor, the ipaoriginaluid is
returned.

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

Signed-off-by: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-05-22 09:59:34 +02:00
Erik Belko 47920e78c8 ipatests: Update ipa-adtrust-install test
update after change in implementation of `krb_utils.get_principal()` now using GSSAPI

Related: https://pagure.io/freeipa/issue/9575

Signed-off-by: Erik Belko <ebelko@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2024-05-21 14:50:46 +02:00
Mark Reynolds 544652aae4 Issue 9591 - Allow get_ruv() to handle incomplete RUV elements
Sometimes RUV's are missing the LDAP Url and max/min csns. This prevents
cleanallruv task from running.  However, cleanallruv doesn't need to
know the LDAP URL or min/max csns. Added a new paramter to get_run()
called "strict", and when set to False it will still process and
include incomplete RUVs.

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

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-05-20 14:52:12 -04:00
Rob Crittenden f225b3df17 Don't try to validate the HSM arguments on a non-HSM installation
If there is no token name it is safe to assume that an HSM
installation is not requested. The validator assumes that if
there is a token name then the library and password are also
provided.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-20 14:46:55 -04:00
Francisco Trivino b34525c76e Spec file: add support for sss_ssh_knownhosts
sss_ssh_knownhostsproxy will be deprecated in favor of sss_ssh_knownhosts. This commit
implements a mechanism to apply the change when upgrading from older versions.

Fixes: https://pagure.io/freeipa/issue/9536
Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-05-17 09:53:53 +02:00
Francisco Trivino 7d54a6daaf ipa-client-install: add support for sss_ssh_knownhosts
sss_ssh_knownhostsproxy will be deprecated in favor of sss_ssh_knownhosts.

With this update, if the file /usr/bin/sss_ssh_knownhosts is present,
KnownHostsCommand will be used instead of ProxyCommand. Also, GlobalKnownHostsFile
is disabled as it is no longer needed.

Fixes: https://pagure.io/freeipa/issue/9536
Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-05-17 09:53:53 +02:00
Rob Crittenden 6af8577d58 docs: Add a section on SELinux modules to the HSM design
Additional SELinux rules are necessary for the HSM to be
managed by IPA and certmonger. Given the infinite possible
naming combinations of library paths and modules this is
a best effort. A message is logged if a missing module
is detected.

Related: https://pagure.io/freeipa/issue/9273

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden c861ce5a16 Add SELinux module checking to hsm_validator
Don't blow up if the expected module is not installed but warn
about it. Hopefully users will actually read the output and/or the
installation log.

This is done by looking for strings in the path. Not great but
it's at least something.

Related: https://pagure.io/freeipa/issue/9273

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 6b6c1879c5 Call hsm_validator on KRA installs and validate the HSM password
hsm_validator was validating that the token was available but
not that the provided password worked. Add that capability.

Also call it early in the CA and KRA installation cycle so that
it errors out early. This is particularly important for the KRA
because there is no uninstaller.

Bump the minimum PKI release to 11.5.0 as that contains important
fixes for the HSM.

Remove an unused arguments to hsm_version and hsm_validator.

Related: https://pagure.io/freeipa/issue/9273

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 879a937ddd Include the HSM tests in the nightlies
Related: https://pagure.io/freeipa/issue/9273

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden bcd8d2d90a Require certmonger 0.79.17+ for required HSM changes
* Switch to CA user when saving NSS certificates
* Add new certs to internal token, try harder to remove on renewal
* Don't restrict tokens to CKM_RSA_X_509

Related: https://pagure.io/freeipa/issue/9273

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden ea0bf4020c After an HSM replica install ensure all certs are visible
If a certificate on a token does not have NSS trust set then
it won't be visible in the softoken. This can be disconcerting
for those used to seeing all the certificates.

Loop through the possibilities and set no trust (or Peer) for
all the certificates on the token.

Also ensure that the CA certificate has the correct nickname.

Related: https://pagure.io/freeipa/issue/9273

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden b9ec2fb0a9 KRA: force OAEP for some HSM-based installations
Not all HSMs support PKCS#1 v1.5. The nShield nFast is one we know
of so force the KRA to use OAEP in this case..

This can be seen in HSMs where the device doesn't support the
PKCS#1 v1.5 mechanism. It will error out with either "invalid
algorithm" or CKR_FUNCTION_FAILED.

There is currently no good way to test for this capability in
advance of configuration. Testing for mechanisms alone is
insufficient. The only real way to test would be to attempt a
wrap/unwrap but it is very complex.

If the list of affected HSMs increases we can use a table
instead based on "best guess" of some sort of property but
looking for a unique string inside the library path is a
pretty straigthforward way.

Note that this doesn't preclude someone from wanting to require
OAEP directly by modifying the KRA CS.cfg and it won't impact
FIPs mode which requires OAEP.

Related: https://pagure.io/freeipa/issue/9191

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 31fda79a0e Prompt for token password if not provided in replica/ipa-ca-install
If the password wasn't provided by --token-password then an empty
value would be passed into the CA installer which promptly failed.

Related: https://pagure.io/freeipa/issue/9273

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden c6f2d0212b dogtag-ipa-ca-renew-agent-submit: expect certs to be on HSMs
On a non-HSM, non-renewal-server replica we look in LDAP for
an updated certificate. If the certificates don't match then we
have a new one and write it out. If they match the assumption is
that it hasn't been renewed yet so go into CA_WORKING.

The problem is that for networked HSMs the cert will already be
visible in the database so certmonger will always be in CA_WORKING.
In this case we can assume that if the certs are the same then
that's just fine.

Related: https://pagure.io/freeipa/issue/9273

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden b63103c88a tests: Fix failing test test_testconfig.py with missing token variables
Arguments were added to the configuration file to allow specifying
the token option values. These needed to be included into the
defaults as well.

This should be merged into the tests prior to pushing.

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Mohammad Rizwan 1ec875c6fe ipatests: test software HSM installation with server & replica
Use SoftHSM2 to install an IPA CA to store the keys in an HSM.

Whenenver new keys are generated either in the initial install
or if a KRA is installed then the token needs to be synced
between all servers prior to installing a new CA or KRA.

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

Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden f8798b3e16 Add SELinux subpackage for Thales Luna HSM support
This is simple, a port needs to be available to certmonger
to communicate during renewals of CA subsystem certificats.

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 87ecca0f18 Add SELinux subpackage for nCipher nfast HSM support
A number of files that need to be managed by certmonger
have unconfined_u:object_r:pki_common_t:s0.

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden c6dd21f04e Remove caSigningCert from list of certs to renew
This certificate should not be renewed this way.
ipa-cacert-manage renew should be used.

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 31d66bac64 Validate the HSM token library path and name during installation
It would fail eventually with the output in the CA logs but it
wasn't always very obvious and you had to wait a while to find
out about a typo.

Scraping modutil output is a bit ugly but it is guaranteed
to be installed and this should work both with p11-kit and
without.

Related: https://pagure.io/freeipa/issue/9273

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 6b894f28b5 After installing a KRA, copy the updated token to other machines
This can be eventually squashed into the main "test" patch but
keeping it separate to make it easier to see what has happened.

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Mohammad Rizwan 36dbc6b025 ipatests: test software HSM installation with server & replica
Use SoftHSM2 to install an IPA CA to store the keys in an HSM.

Whenenver new keys are generated either in the initial install
or if a KRA is installed then the token needs to be synced
between all servers prior to installing a new CA or KRA.

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

Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 06a8791b9b tests: helper to copy files from one host to another
Simple function that takes a list of file names and copies
them from one host to another.

It isn't the most efficient but for a small number of files it
should be sufficient.

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden b89aa91977 renew_ca_cert: set peer trust on the KRA audit certificate
The PKI audit certificates require that trusted peer (P) be
set on the certificate. This is done already for the CA audit
certificate. Also set this on the KRA audit certificate on
renewal.

https://pagure.io/freeipa/issue/9353

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 0708f603e2 renew_ca_cert: skip removing non-CA certs, fix nickname
This script deletes all CA certificates so a new chain
can be loaded. It identified CA certs by those that did
not have private keys. This change adds the  ca_flags test
in as well. It is probably sufficient on its own but it
is left for compatibility.

An HSM-based NSS database when not accessing it with the
token will not contain the private keys so removing all
certificates without a private key will remove certificates
that it shouldn't. The NSS softoken stores the certifcate
trust so the certificates will be visible but they lack
private keys because those reside in the HSM. Therefore
deleting any certificate without a private key removed
nearly everything.

Preserve the nickname 'caSigningCert cert-pki-ca'. The
certstore uses the nickame format '{REALM} IPA CA' and
will replace the PKI-named key if we don't act to
preserve it.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden d0c489e282 If HSM is configured add the token name to config-show output
A token can only be set in an HSM installation so this is implicit:
if a token exists then HSM is enabled, if not then it isn't.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 93622005ba Add token support to the renew_ca_cert certmonger helper
The certificates live on the token so need to be retrieved
from there with the token name. The certificates are visible
in NSS softoken but operations need to be done on the HSM
version. The right password is necessary so retrieve it from
the PKI password store.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 7ad3b489f6 Update SELinux policy to allow certmonger to PKI config files
Needed so the helper renew_ca_cert can read password.conf in order
to get the token password. These files are already readable with
FS permissions.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden a99091adc0 Add attribute ipacahsmconfiguration to the "Read CAs" ACI
This will allow the HSM stored configuration to be read.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 82c0b19acc Add HSM configuration options to installer scripts
The bulk of the installer effort to enable HSM support without
having to provide an override file.

This pulls the HSM configuration from a remote server when installing
a replica so that the token name and library don't need to be
passed with every installation.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden d9efa728c5 Add LDAP attribute ipaCaHSMConfiguration to store HSM state
This will be used so that when a replica is created it can
configure the HSM without relying on the user to pass in
the same token, library name, etc.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden f658a264f9 doc: Add token-password-file to HSM design, set new OID
Clarify when the user will be prompted interactively during
installation.

Set the OID for ipaCaHSMConfiguration.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden e3234708ac Don't move KRA keys when key backup is disabled
The KRA_BACKUP_KEYS_P12 file is not enabled when pki_backup_keys
is set to False. This is the case IPA is configured with HSM
support.

With an HSM you don't export private keys.

Related: https://pagure.io/freeipa/issue/7677
Related: https://pagure.io/freeipa/issue/9273

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 73d52a6135 Only generate kracert.p12 when not installing with HSM
The private keys are not retrievable from an HSM by
design so don't try during KRA install.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden 34f28f06db Add token support to installer certificate handling
Pass along the user-provided password file, if any, to the
underlying NSS database. This will provide for per-token
passwords.

If a token is in a nickname then break it out and pass it to
certutil separately.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden e6078c639c Don't generate a cafile on HSM instalations
We don't export the CA certificates on an HSM installation
because an HSM won't allow the private keys to leave the
HSM, by design.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Rob Crittenden cba3094c9a Support the certmonger nss-user option
Some certificate operations need to be executed as a specific
user so that underlying files will have the correct ownership.
certmogner normally runs as root. The nss-user option defines
a user to switch to when saving NSS certifciates so if a
software token (e.g. SoftHSM) then the files created will be
owned by the token owner.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-05-16 08:46:32 -04:00
Florence Blanc-Renaud bb8dd0bfcd Spec file: depend on nfs-utils or nfsv4-client-utils
The freeipa-client package currently requires nfs-utils.
The requirement can be relaxed and modified into nfs-utils or
nfsv4-client-utils.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-05-07 14:33:04 +02:00
Pavel Březina 9e1e22d46b ipaserver: fix incorrect double negative in exception message
Signed-off-by: Pavel Březina <pbrezina@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-05-06 17:10:18 -04:00
Rafael Guterres Jeffman 6c6b9354b5 Replace netifaces with ifaddr
Python netifaces has been unmaintained and its main repository has been
archived since June, 2021.

Python ifaddr is an alternative to netifaces, is currently maintained,
and provides an API which requires little change for FreeIPA current
usage.

This patch modifies FreeIPA to rely on ifaddr instead of neitfaces, due
to its current maintainance status.

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

Signed-off-by: Rafael Guterres Jeffman <rjeffman@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-05-03 16:35:19 -04:00
Mark Reynolds cce8dc4da8 Issue 9579 - Remove bash_completions_dir for RHEL
RHEL 9 does not support the bach_completions_dir macro, but it is still
needed for Fedora builds

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

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2024-04-30 14:26:55 -04:00
Mark Reynolds f9f96ac4a8 Issue 9570 - migrate nsaccountlock
IPA migration tool, when retrieving a remote entry from the
source/remote server request the operational attribute 'nsaccountlock'

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

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
2024-04-15 16:06:23 +02:00
Rob Crittenden f78d25fc97 ipa-crlgen-manage: manage the cert status task execution time
ca.certStatusUpdateInterval manages how frequently to update
the certificate status in LDAP (expired, etc).

By default this is not set on the initial master and pkispawn sets
it to 0 on replicas. This can lead to no server running this
task and therefore the status attribute not reflecting the current
state.

On enabling CRL generation remove any value which will cause PKI
to use its default. On disabling set it to 0.

Only one server should run the update status task to prevent
unnecessary replication.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-04-15 16:03:10 +02:00
Florence Blanc-Renaud dda223668a webui test: Update message for admin disable
An admin can be disabled if he is not the last member of the
admins group. Update the expecrted error message.

Fixes: https://pagure.io/freeipa/issue/9574
Related: https://pagure.io/freeipa/issue/9489

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-04-12 15:59:04 +02:00
Alexander Bokovoy d16c34997f internal: fix 'tokensfor' typo and regenerate pot file
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-04-10 09:30:53 +02:00
Rob Crittenden 6b0f6ff19e Allow the admin user to be disabled
A previous change made it not possible to remove the admin
user. This also included disabling the admin user. The user can
be disabled, just not deleted because it is required.

Move the test test_ipa_cacert_manage_prune to the end of the
class because it changes time which can break replication.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-04-10 09:26:47 +02:00
Thomas Woerner 182dca38c2 principal_has_privilege: Check also idoverriseuser (ipaOriginalUid)
The current filter in principal_has_privilege is only working for normal
IPA users where krbprincipalname is matching the principal. An idoverride
user (for example from AD) is not found with this filter.

A new filter for the principal as an ipaOriginalUid has been added as a
second try if a match with krbprincipalname was not found.

principal_has_privilege is used in the replica connection check. The
additional check enables to deploy replicas using an AD user/administrator
that has been added to the "admins" group.

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

Signed-off-by: Thomas Woerner <twoerner@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-04-05 10:05:56 +02:00
Mark Reynolds 8084b94c17 Issue 9568 - Update IPA to IPA migration design doc
The usage for migrating DNS changed. It went from "--skip-dns",
to "--migrate-dns"

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

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-04-04 17:25:04 -04:00
Rob Crittenden 6294b93e14 ipatests: Ignore spacing in OpenSSL validation error message
The error message format changed between releases of OpenSSL.
The updated version has dropped spaces around equal signs
between RDN elements in the subject.

e.g. In 3.1.1 it reports O = EXAMPLE.TEST, CN = IPA RA
and in 3.2.1 reports O=EXAMPLE.TEST, CN=IPA RA

So ignore all spacing in the error message so it works on all
versions.

I saw this in openssl-3.1.1-4.fc39.x86_64 vs
openssl-3.2.1-3.fc41.x86_64

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-04-04 16:30:09 -04:00
Mark Reynolds cbe1873591 IPA-to-IPA migration tool (beta)
Tool for migrating one remote IPA server to a local IPA server.
This should still be considered the beta version as it has not gone
through any QE yet

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

signed-off: Mark Reynolds (mreynolds@redhat.com)
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-04-04 15:49:42 -04:00
Stanislav Levin 1df2abbd5f ap: Migrate to docker compose V2
Azure Pipelines started to roll 20240401.4 Ubuntu image that doesn't
include docker-compose v1:

https://github.com/actions/runner-images/blob/ubuntu20/20240401.4/images/ubuntu/Ubuntu2004-Readme.md

See https://github.com/actions/runner-images/issues/9557

Compose V1 to V2 migration guide:

https://docs.docker.com/compose/migrate/

Fixes: https://pagure.io/freeipa/issue/9566
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-04-04 11:42:24 -04:00
Erik Belko fc7c2cb624 xmlrpc tests: Create user with manager option set using user-add
Related: https://pagure.io/freeipa/issue/9515

Signed-off-by: Erik Belko <ebelko@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2024-04-04 15:56:25 +01:00
Alexander Bokovoy ca6604b58b Use raw strings for Python 3 compatibility in old API client code
Python 3 enforces checks on \ sequences in strings. Instead of copying
over the new mix of normal and raw strings from the server side, turn
those strings in the remote plugins to raw mode.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-04-03 10:43:55 -04:00
Rob Crittenden 5d3c6b761b Return 2 when certificates are not found during requests
The ipa tool has nearly since epoch returned 2 for the case of
entry not found.

The certificate processing raises a separate error,
CertificateOperationsError, when something goes wrong.
This returns 1.

With the introduction of the JSON API most requests will get
a proper HTTP return code representing what went wrong. In this
case we can use 404 to determine if the request resulted in
a NotFound therefore can eventually return a 2 and be
consistent in return values.

Related: https://pagure.io/freeipa/issue/9562

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-04-02 23:06:43 +02:00
Rob Crittenden a9bb811296 Check for file permissions after the ca/cert-show is complete
The commands ca-show and cert-show provide the ability to direct
the certificate output to a file. If the requested object was
not present then this resulted in a zero-length file.

This is because the check to determine if the file was writable,
by opening it, was done prior to the operation to retrieve
the entry.

So move the check after the data retrieval.

Also convert cert-show to be more consistent with ca-show.

I considered cleaning up the empty file afterward but IMHO we
shouldn't touch the file until we're ready to write. This
costs an API roundtrip but its a small price to pay for
potentially protecting existing data.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-04-02 23:06:43 +02:00
Christian Heimes 38d0e74b6d Move ipalib.install.kinit to ipalib
- kinit helpers are now in `ipalib.kinit`.
- helpers can now use default ccache locations like many other similar
  helpers
- helpers return the result from `run` for debugging
- constants are now in `krb_utils`
- helpers pass `KRB5*` and `GSS*` env vars along, so `KRB5_TRACE` works
- document how to kinit for `ipalib.api`

Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-03-27 18:07:17 +01:00
Florence Blanc-Renaud 6cc668ffeb xmlrpc: adapt range plugin test
A warning is added in ipa idrange-add/mod/del for
local ranges. Adapt the test expectation.

Related: https://pagure.io/freeipa/issue/9558
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-27 18:04:26 +01:00
Alexander Bokovoy a57b665be0 idrange: only issue warning to restart services for a local range
SIDGEN plugin only uses local ID ranges and thus a restart is really
needed only when a local range is added, modified or removed.

Also fix the SSSD warning because removal of any range requires restart
everywhere, not just on a specific server.

Fixes: https://pagure.io/freeipa/issue/9558
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-27 18:04:26 +01:00
Sudhir Menon adf95dcf86 ipatests: Fixes for test_ipahealthcheck_ipansschainvalidation testcases.
Currently the test is using IPA_NSSDB_PWDFILE_TXT which is /etc/ipa/nssdb/pwdfile.txt
which causes error in STIG mode.

[root@master slapd-TESTRELM-TEST]# certutil -M -n 'TESTRELM.TEST IPA CA' -t ',,' -d . -f /etc/ipa/nssdb/pwdfile.txt
Incorrect password/PIN entered.

Hence modified the test to include paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE/pwd.txt.

Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-03-25 12:27:43 +01:00
Florence Blanc-Renaud 64861a0cf9 idrange-add: add a warning because 389ds restart is required
After the addition of a new idrange, the sidgen plugin is not
immediately aware of the new idrange and a restart of 389ds is
required. Otherwise the creation of new user/group with a uid/gid
inside the new range fails to grant a SID to the user/group.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-03-20 13:59:21 +01:00
Alexander Bokovoy f9a1d74f5e dcerpc: invalidate forest trust info cache when filtering out realm domains
When get_realmdomains() method is called, it will filter out subdomains
of the IPA primary domain. This is required because Active Directory
domain controllers are assuming subdomains already covered by the main
domain namespace.

[MS-LSAD] 3.1.4.7.16.1, 'Forest Trust Collision Generation' defines the
method of validating the forest trust information. They are the same as
rules in [MS-ADTS] section 6.1.6. Specifically,

  - A top-level name must not be superior to an enabled top-level name
    for another trusted domain object, unless the current trusted domain
    object has a corresponding exclusion record.

In practice, we filtered those subdomains already but the code wasn't
invalidating a previously retrieved forest trust information.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-19 15:20:39 +01:00
Mark Reynolds 557f0a5639 Issue 9547 - Update IPA to IPA migration design doc
Update the ipa to ipa migration doc in regards to the new IPA migration tool

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

Signed-off-by: Mark Reynolds <mreynolds@redhatr.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-03-14 13:59:48 +01:00
Alexander Bokovoy e431ce0ce7 ipa-pwd-extop: declare operation notes support from 389-ds locally
The function slapi_pblock_set_flag_operation_notes(); is defined in
ldap/servers/slapd/pblock.c in 389-ds but is only available through
slapi-private.h header, not through slapi-plugin.h public API.

It was introduced in ~1.4.1.7 (~2019) via https://pagure.io/389-ds-base/issue/50349.

Since we only use it with an MFA note, all versions of the 389-ds that
will support MFA note will have this function.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-14 13:53:16 +01:00
Alexander Bokovoy 23b224d7ad ipa-pwd-extop: add MFA note in case of a successful LDAP bind with OTP
In case there is a successful OTP authentication attempt, register it as
an operation note on the BIND operation in LDAP. 389-ds then will print
a multi-factor authentication note in both access and security logs
according to https://www.port389.org/docs/389ds/design/mfa-operation-note-design.html

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-12 13:53:11 +01:00
Alexander Bokovoy 1d2897e3d7 ipa-pwd-extop: allow enforcing 2FA-only over LDAP bind
When authentication indicators were introduced in 2016, ipa-pwd-extop
plugin gained ability to reject LDAP BIND when an LDAP client insists
the authentication must use an OTP token. This is used by ipa-otpd to
ensure Kerberos authentication using OTP method is done with at least
two factors (the token and the password).

This enfrocement is only possible when an LDAP client sends the LDAP
control. There are cases when LDAP clients cannot be configured to send
a custom LDAP control during BIND operation. For these clients an LDAP
BIND against an account that only has password and no valid token would
succeed even if admins intend it to fail.

Ability to do LDAP BIND without a token was added to allow users to add
their own OTP tokens securely. If administrators require full
enforcement over LDAP BIND, it is cannot be achieved with LDAP without
sending the LDAP control to do so.

Add IPA configuration string, EnforceLDAPOTP, to allow administrators to
prevent LDAP BIND with a password only if user is required to have OTP
tokens. With this configuration enabled, it will be not possible for
users to add OTP token if one is missing, thus ensuring no user can
authenticate without OTP and admins will have to add initial OTP tokens
to users explicitly.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-12 13:53:11 +01:00
Rob Crittenden c3d228d4a3 Vault: add additional fallback to RSA-OAEP wrapping algo
There is a fallback when creating the wrapping key but one was missing
when trying to use the cached transport_cert.

This allows, along with forcing keyWrap.useOAEP=true, vault creation
on an nCipher HSM.

This can be seen in HSMs where the device doesn't support the
PKCS#1 v1.5 mechanism. It will error out with either "invalid
algorithm" or CKR_FUNCTION_FAILED.

Related: https://pagure.io/freeipa/issue/9191

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-03-05 15:46:01 -05:00
Weblate Translation Memory ca776b6a9c Translated using Weblate (Korean)
Currently translated at 18.9% (922 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-04 08:44:31 +01:00
김인수 bf5c9892e9 Translated using Weblate (Korean)
Currently translated at 18.9% (922 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-04 08:44:31 +01:00
Weblate Translation Memory 05f1bf9e2c Translated using Weblate (Korean)
Currently translated at 18.4% (899 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-04 08:44:31 +01:00
김인수 04ac64a4ed Translated using Weblate (Korean)
Currently translated at 18.4% (899 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-04 08:44:31 +01:00
Weblate Translation Memory d8a4bde2c6 Translated using Weblate (Korean)
Currently translated at 14.5% (712 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-04 08:44:31 +01:00
김인수 e60072fe89 Translated using Weblate (Korean)
Currently translated at 14.5% (712 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-04 08:44:31 +01:00
Weblate Translation Memory ee6ff01b46 Translated using Weblate (Korean)
Currently translated at 13.4% (655 of 4877 strings)

Co-authored-by: Weblate Translation Memory <noreply-mt-weblate-translation-memory@weblate.org>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Translation: freeipa/master
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-04 08:44:31 +01:00
김인수 9ad27c954e Translated using Weblate (Korean)
Currently translated at 13.4% (655 of 4877 strings)

Co-authored-by: 김인수 <simmon@nplob.com>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Translation: freeipa/master
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-03-04 08:44:31 +01:00
Florence Blanc-Renaud 558a7de8b7 ipatests: some tests are date-sensitive and fail Feb 29
A few tests are changing the date back and forth using for
instance date -s +3Years+1day and date -s -3Years-1day.
This method does not bring the system back to the current date
if executed around Feb 28 or 29 on a leap year, and may result
in de-synchronized server and client.

Add a note in the test to warn about potential future failures.

Related: https://pagure.io/freeipa/issue/9548

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-03-01 11:53:48 +01:00
Weblate Translation Memory f4a1696a3b Translated using Weblate (Korean)
Currently translated at 10.6% (520 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 f2befb4944 Translated using Weblate (Korean)
Currently translated at 10.6% (520 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Weblate Translation Memory 7b2ac6a293 Translated using Weblate (Korean)
Currently translated at 8.4% (412 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 99922e9963 Translated using Weblate (Korean)
Currently translated at 8.4% (412 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 86aae371fa Translated using Weblate (Korean)
Currently translated at 7.5% (370 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Weblate Translation Memory 78d86ba060 Translated using Weblate (Korean)
Currently translated at 7.5% (370 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 d9afa62814 Translated using Weblate (Korean)
Currently translated at 7.0% (342 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Temuri Doghonadze 282b551533 Translated using Weblate (Georgian)
Currently translated at 35.0% (1709 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ka/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 1ce532d5a8 Translated using Weblate (Korean)
Currently translated at 6.7% (327 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 2877cae09f Translated using Weblate (Korean)
Currently translated at 6.7% (327 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Weblate Translation Memory c6aae2042d Translated using Weblate (Korean)
Currently translated at 6.7% (327 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 da9f2294e6 Translated using Weblate (Korean)
Currently translated at 6.4% (317 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Weblate Translation Memory f4504e1e91 Translated using Weblate (Korean)
Currently translated at 6.4% (317 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 bc3085cd01 Translated using Weblate (Korean)
Currently translated at 6.0% (295 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Weblate Translation Memory 049a56d603 Translated using Weblate (Korean)
Currently translated at 6.0% (295 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 f7a56eb35c Translated using Weblate (Korean)
Currently translated at 5.5% (270 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Weblate Translation Memory 23d64942e1 Translated using Weblate (Korean)
Currently translated at 5.5% (270 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Weblate Translation Memory 20b01b09f2 Translated using Weblate (Korean)
Currently translated at 4.7% (230 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 cd1a36f233 Translated using Weblate (Korean)
Currently translated at 4.7% (230 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Weblate Translation Memory f18db3abd7 Translated using Weblate (Korean)
Currently translated at 4.6% (228 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 655b13193a Translated using Weblate (Korean)
Currently translated at 4.6% (228 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Weblate Translation Memory 2959bec776 Translated using Weblate (Korean)
Currently translated at 4.6% (227 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 b4da6896d6 Translated using Weblate (Korean)
Currently translated at 4.6% (227 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Weblate Translation Memory cb073530fa Translated using Weblate (Korean)
Currently translated at 4.6% (226 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
김인수 633ea8ba62 Translated using Weblate (Korean)
Currently translated at 4.5% (223 of 4877 strings)

Co-authored-by: 김인수 <simmon@nplob.com>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Translation: freeipa/master
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Weblate Translation Memory da8ab4b54f Translated using Weblate (Korean)
Currently translated at 4.5% (223 of 4877 strings)

Co-authored-by: Weblate Translation Memory <noreply-mt-weblate-translation-memory@weblate.org>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Translation: freeipa/master
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Temuri Doghonadze 150050eda3 Translated using Weblate (Georgian)
Currently translated at 35.0% (1708 of 4877 strings)

Co-authored-by: Temuri Doghonadze <temuri.doghonadze@gmail.com>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ka/
Translation: freeipa/master
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-28 13:13:19 +01:00
Rob Crittenden 3766fb9863 ipa-restore: adapt for 389-ds switch to LMDB
ipa-restore is relying on the presence of specific directories,
e.g. /var/lib/dirsrv/slapd-/db/ipaca, to detect
which backends are in use (userRoot or ipaca).

With the switch to LMDB, these directories do not exist and the
restore fails finding the ipaca backend.

Use lib389.cli_ctl.dblib.run_dbscan utility instead to
check which backends are present.

This method was been introduced in 389ds 2.1.0 and works with
Berkeley DB and LMDB.

Add a --data option to the ipa-backup and ipa-restore tasks to do
only an LDIF backup and restore. Also add the ability to restore by
backend.

Add new tests to do a data-only backup and restore.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-23 14:11:25 +01:00
Rob Crittenden 33af154b7f validate_principal: Don't try to verify that the realm is known
The actual value is less important than whether it matches the
regular expression. A number of legal but difficult to know in
context realms could be passed in here (trust for example).

This fixes CVE-2024-1481

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-02-22 14:35:59 -05:00
Alexander Bokovoy 404fe1018e rpcserver: validate Kerberos principal name before running kinit
Do minimal validation of the Kerberos principal name when passing it to
kinit command line tool. Also pass it as the final argument to prevent
option injection.

Accepted Kerberos principals are:
 - user names, using the following regexp
   (username with optional @realm, no spaces or slashes in the name):
   "(?!^[0-9]+$)^[a-zA-Z0-9_.][a-zA-Z0-9_.-]*[a-zA-Z0-9_.$-]?@?[a-zA-Z0-9.-]*$"

 - service names (with slash in the name but no spaces). Validation of
   the hostname is done. There is no validation of the service name.

The regular expression above also covers cases where a principal name
starts with '-'. This prevents option injection as well.

This fixes CVE-2024-1481

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-02-21 17:07:33 -05:00
Julien Rische dc3e902b0b ipa-kdb: Fix double free in ipadb_reinit_mspac()
Fixes: https://pagure.io/freeipa/issue/9535

Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-20 16:33:59 +01:00
Julien Rische 835929353d ipa-kdb: Rework ipadb_reinit_mspac()
Modify ipadb_reinit_mspac() to allocate and initialize ipactx->mspac
only if all its attributes can be set. If not, ipactx->mspac is set to
NULL. This makes easier to determine if the KDC is able to generate PACs
or not.

Also ipadb_reinit_mspac() is now able to return a status message
explaining why initialization of the PAC generator failed. This message
is printed in KDC logs.

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

Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Alexander Bokovoy <abbra@users.noreply.github.com>
2024-02-16 09:38:02 +01:00
Florence Blanc-Renaud e5bb0f392a ipatests: fix tasks.wait_for_replication method
With the fix for https://pagure.io/freeipa/issue/9171, the
method entry.single_value['nsds5replicaupdateinprogress'] now
returns a Boolean instead of a string "TRUE"/"FALSE".

The method tasks.wait_for_replication needs to be fixed so that
it properly detects when replication is not done.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-02-14 09:26:00 +01:00
Temuri Doghonadze 4ab602a61f Translated using Weblate (Georgian)
Currently translated at 35.0% (1708 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ka/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-13 15:35:26 +01:00
Temuri Doghonadze e2cab8e900 Translated using Weblate (Georgian)
Currently translated at 30.0% (1466 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ka/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-13 15:35:26 +01:00
Weblate Translation Memory 5c91cb2f47 Translated using Weblate (Georgian)
Currently translated at 30.0% (1466 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ka/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-13 15:35:26 +01:00
Weblate Translation Memory 5b18239951 Translated using Weblate (Georgian)
Currently translated at 27.8% (1358 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ka/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-13 15:35:26 +01:00
Temuri Doghonadze b29f2e2307 Translated using Weblate (Georgian)
Currently translated at 27.8% (1358 of 4877 strings)

Translation: freeipa/master
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ka/
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-13 15:35:26 +01:00
Weblate Translation Memory 2750637544 Translated using Weblate (Georgian)
Currently translated at 11.7% (572 of 4877 strings)

Co-authored-by: Weblate Translation Memory <noreply-mt-weblate-translation-memory@weblate.org>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ka/
Translation: freeipa/master
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-13 15:35:26 +01:00
Temuri Doghonadze 05f8eaea63 Translated using Weblate (Georgian)
Currently translated at 11.7% (572 of 4877 strings)

Co-authored-by: Temuri Doghonadze <temuri.doghonadze@gmail.com>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ka/
Translation: freeipa/master
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-13 15:35:26 +01:00
Rafael Fontenelle 8b48c5f906 Translated using Weblate (Portuguese (Brazil))
Currently translated at 4.6% (227 of 4877 strings)

Co-authored-by: Rafael Fontenelle <rafaelff@gnome.org>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/pt_BR/
Translation: freeipa/master
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-13 15:35:26 +01:00
Florence Blanc-Renaud 908ef6a179 ipatests: add xfail for autoprivate group test with override
Because of SSSD issue 7169, secondary groups are not
retrieved when autoprivate group is set and an idoverride
replaces the user's primary group.
Mark the known issues as xfail.

Related: https://github.com/SSSD/sssd/issues/7169

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Anuja More <amore@redhat.com>
2024-02-12 08:32:20 +01:00
Florence Blanc-Renaud dfb5099e7f ipatests: remove xfail thanks to sssd 2.9.4
SSSD 2.9.4 fixes some issues related to auto-private-group

Related: https://pagure.io/freeipa/issue/9295
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Anuja More <amore@redhat.com>
2024-02-12 08:32:20 +01:00
김인수 bea9614b12 Translated using Weblate (Korean)
Currently translated at 4.4% (216 of 4877 strings)

Co-authored-by: 김인수 <simmon@nplob.com>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/ko/
Translation: freeipa/master
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-08 15:35:22 +01:00
Rafael Fontenelle d6aaa626a6 Translated using Weblate (Portuguese (Brazil))
Currently translated at 4.5% (223 of 4877 strings)

Co-authored-by: Rafael Fontenelle <rafaelff@gnome.org>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/pt_BR/
Translation: freeipa/master
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-08 15:35:22 +01:00
Emilio Herrera f3a3d29117 Translated using Weblate (Spanish)
Currently translated at 58.1% (2834 of 4877 strings)

Co-authored-by: Emilio Herrera <ehespinosa57@gmail.com>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/es/
Translation: freeipa/master
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-08 15:35:22 +01:00
Weblate 6a59110947 Update translation files
Updated by "Update PO files to match POT (msgmerge)" hook in Weblate.

Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.fedoraproject.org/projects/freeipa/master/
Translation: freeipa/master
Reviewed-By: Alexander Bokovoy <abbra@users.noreply.github.com>
2024-02-07 09:46:12 +01:00
Andika Triwidada b9552bcb71 Translated using Weblate (Indonesian)
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-02-06 15:14:45 +01:00
Yuri Chornoivan 591bbee847 Translated using Weblate (Ukrainian)
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-02-06 15:14:45 +01:00
Piotr Drąg 9e31e70434 Translated using Weblate (Polish)
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-02-06 15:14:45 +01:00
Jan KuparinenandRicky Tigg c3cb63e582 Translated using Weblate (Finnish)
Co-authored-by: Ricky Tigg <ricky.tigg@gmail.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-02-06 15:14:45 +01:00
김인수 abc48e285e Translated using Weblate (Korean)
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-02-06 15:14:45 +01:00
Temuri Doghonadze 41bc6fc382 Translated using Weblate (Georgian)
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-02-06 15:14:45 +01:00
Alexander Bokovoy bd04dc28c8 ipa-kdb: support Samba 4.20 private libraries
Samba 4.20 will change name extension of the private libraries from
'samba4' to 'private-samba'. Detect private extension through configure
step and make sure to use the right library name in Makefile.

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-06 10:57:08 +01:00
Sudhir Menon 7f849956df ipatests: Skip tests for ipahealtcheck tests for specific pki version
CADogtagCertsConfigCheck is no more available on RHEL9, hence the
respective tests are skipped.

Check 'CADogtagCertsConfigCheck' not found in Source 'pki.server.healthcheck.meta.csconfig'

Ref: https://issues.redhat.com/browse/RHEL-21367

Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-02-02 11:03:00 +01:00
Florence Blanc-Renaud 9c470d10a5 ipatests: test_idp fails calling yum list wget
On rawhide, the package wget has been replaced with wget2
(more info in https://bugzilla.redhat.com/show_bug.cgi?id=2254790).

The test test_idp is checking that the sudo command is working
for a keycloak user, by creating a sudo rule for the yum command
and calling sudo yum list wget.
As the wget package does not exist any more on Rawhide, the command
returns an error:
Error: No matching Packages to list
and the test fails.

Replace the call "sudo yum list wget" with a call to "sudo yum list yum"
as the yum package is always present.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-01-30 18:27:12 +01:00
Florence Blanc-Renaud 677d308066 ipa-backup: adapt for 389ds switch to LMDB
ipa-backup is relying on the presence of the directory
/var/lib/dirsrv/slapd-<INSTANCE>/db/ipaca/
to detect if the CA is installed on the server and backup
the ipaca backend.

With the switch to LMDB, this directory does not exist and the
backup is missing ipaca information.

Use lib389.cli_ctl.dblib.run_dbscan utility instead to
check if ipaca backend is present (this method has been
introduced in 389ds 2.1.0 and works with Berkeley DB and LMDB).

Fixes: https://pagure.io/freeipa/issue/9516
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
2024-01-30 18:25:10 +01:00
Alexander Bokovoy ed977a6e82 kdb: PAC generator: do not fail if canonical principal is missing
krbCanonicalName is mandatory for services but IPA services created
before commit e6ff83e (FreeIPA 4.4.0, ~2016) had no normalization done
to set krbCanonicalName; services created after that version were
upgraded to do have krbCanonicalName.

Accept krbPrincipalName alone since they have no alias either */

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
2024-01-30 16:25:29 +01:00
Alexander Bokovoy 89d945fe6f sidgen: fix missing prototypes
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
2024-01-30 16:25:29 +01:00
Alexander Bokovoy f8dcd78873 sidgen: ignore staged users when generating SIDs
Staged users have

  uidNumber: -1
  gidNumber: -1
  ipaUniqueID: autogenerate

We cannot generate ipaSecurityIdentifier based on those UID/GID numbers.
However, '-1' value will trigger an error

 find_sid_for_ldap_entry - [file ipa_sidgen_common.c, line 483]: ID value too large.

And that, in turn, will cause stopping SID generation for all users.

Detect 'ipaUniqueID: autogenerate' situation and ignore these entries.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Thierry Bordaz <tbordaz@redhat.com>
2024-01-30 16:25:29 +01:00
Francisco Trivino 305fcc25b4 kra: set RSA-OAEP as default wrapping algo when FIPS is enabled
Vault uses PKCS1v15 as default padding wrapping algo, which is not an approved
FIPS algorithm. This commit ensures that KRA is installed with RSA-OAEP if FIPS
is enabled. It also handles upgrade path.

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

Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-01-30 10:18:02 -05:00
Francisco Trivino 4cc6b9cd17 Vault: improve vault server archival/retrieval calls error handling
If a vault operation fails, the error message just says "InternalError". This commit
improves error handling of key archival and retrieval calls by catching the PKIException
error and raising it as an IPA error.

Related: https://pagure.io/freeipa/issue/9191

Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-01-30 10:18:02 -05:00
Francisco Trivino 2d0a088f93 Vault: add support for RSA-OAEP wrapping algo
None of the FIPS certified modules in RHEL support PKCS#1 v1.5 as FIPS
approved mechanism. This commit adds support for RSA-OAEP padding as a
fallback.

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

Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-01-30 10:18:02 -05:00
Alexander Bokovoy d4ffc53b2a doc/designs/id-mapping.md: expand on ID range allocation details
Related: https://pagure.io/freeipa/issue/9477

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-01-30 10:11:47 -05:00
Julien Rische 75afdfea5d ipa-kdb: Fix memory leak during PAC verification
Commit 0022bd70d9 introduced a memory leak
during the copy of some PAC buffers, because of an unfreed memory
allocation context.

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

Signed-off-by: Julien Rische <jrische@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-01-30 07:50:19 +01:00
Stanislav Levin 9802e852cb ipapython: Propagate KRB5Error exceptions on iterating ccache
`ipapython.session_storage.get_data` iterates over
credentials in a credential cache till `krb5_cc_next_cred` returns
an error. This function doesn't expect any error on calling
other kerberos foreign functions during iteration. But that can
actually happen and KRB5Error exceptions stop an iteration while
they should be propagated.

With this change iteration will exactly stop on `krb5_cc_next_cred`
error as it was supposed to be.

Fixes: https://pagure.io/freeipa/issue/9519
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-01-30 07:43:57 +01:00
Stanislav Levin 6cd04875de ipapython: Correct return type of krb5_free_cred_contents
According to https://web.mit.edu/kerberos/krb5-latest/doc/appdev/refs/api/krb5_free_cred_contents.html

> krb5_free_cred_contents - Free the contents of a krb5_creds structure.
>
> void krb5_free_cred_contents(krb5_context context, krb5_creds * val)
> param:
> [in] context - Library context
>
> [in] val - Credential structure to free contents of
>
> This function frees the contents of val , but not the structure itself.

https://github.com/krb5/krb5/blob/5b00197227231943bd2305328c8260dd0b0dbcf0/src/lib/krb5/krb/kfree.c#L166

This leads to undefined behavior and `krb5_free_cred_contents` can
raise KRB5Error (because of garbage data) while actually its foreign
function doesn't.

Fixes: https://pagure.io/freeipa/issue/9519
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-01-30 07:43:57 +01:00
Stanislav Levin d002a4d7c9 ipapython: Clean up krb5_error
`krb5_error` has different definition in MIT krb.
https://web.mit.edu/kerberos/krb5-latest/doc/appdev/refs/types/krb5_error.html

> Error message structure.
>
> Declaration:
> typedef struct _krb5_error krb5_error

While `krb5_error_code`
https://web.mit.edu/kerberos/www/krb5-latest/doc/appdev/refs/types/krb5_error_code.html#c.krb5_error_code

> krb5_error_code
> Used to convey an operation status.
>
> The value 0 indicates success; any other values are com_err codes. Use krb5_get_error_message() to obtain a string describing the error.
>
> Declaration
> typedef krb5_int32 krb5_error_code

And this is what was actually used.

To prevent confusion of types `krb5_error` was replaced with
`krb5_error_code`.

Fixes: https://pagure.io/freeipa/issue/9519
Signed-off-by: Stanislav Levin <slev@altlinux.org>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2024-01-30 07:43:57 +01:00
Christian Heimes 22875ea2c6 test_acme: Use ipalib.x509
Use IPA's x509 module instead of `cryptography.x509`. This fixes a
regression which was introduced in commit a45a7a20.

Related: https://pagure.io/freeipa/issue/9518
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Mohammad Rizwan Yusuf <myusuf@redhat.com>
2024-01-25 18:07:20 +01:00
Christian Heimes a45a7a20d9 Compatibility fix for PyCA cryptography 42.0.0
Cryptography 42.0.0 introduced two new abstract properties
`not_valid_before_utc` and `not_valid_after_utc`, which are non-naive UTC
variants of the `not_valid_before` and `not_valid_after` properties.

The old properties are deprecated. The changeset also modifies code and
tests to use the new `_utc` variants.

Fixes: https://pagure.io/freeipa/issue/9518
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-01-24 14:54:24 +01:00
Rob Crittenden e6014a5c19 Server affinity: call ca.install() if there is a CA in the topology
This should not have been gated on options.setup_ca because we need
the RA agent on all servers if there is a CA in the topology otherwise
the non-CA servers won't be able to communicate with the CA.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-01-23 16:32:58 +01:00
Alexander Bokovoy 5adc07ae55 doc/Makefile: run sphinx in serial mode
Unfortunately, using pydata_sphinx_theme extension generates warnings in
sphix processing. These warnings cause documentation build to be
considered a failure:

WARNING: the pydata_sphinx_theme extension is not safe for parallel writing
WARNING: doing serial write
....
build finished with problems, 2 warnings.
make: *** [Makefile:24: html] Error 1

Since the build is already doing a serial write, enforce it from start.

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2024-01-23 13:19:37 +01:00
Alexander Bokovoy e399232a78 ipasam: make krbtgt TDO principal canonical
For the trusted domain object for remote realm, we have to use
krbtgt/REMOTE-FLAT-NAME@OUR-REALM as a canonical name.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2024-01-23 13:19:37 +01:00
Masahiro Matsuya c740cb84ba ipatests: wait for replica update in test_dns_locations
test_ipa_ca_records and test_adtrust_system_records can fail with
NXDOMAIN, because it doesn't wait enough for the update on replica.
It can be resolved by waiting for the update with wait_for_replication.

Fixes: https://pagure.io/freeipa/issue/9504
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-01-23 07:57:56 +01:00
Rob Crittenden 3645543670 Server affinity: Don't rely just on [ca|kra]_enabled for installs
ca_enable and kra_enabled are intended to be used to identify that
a CA or KRA is available in the topology. It was also being used
to determine whether a CA or KRA service is desired on a replica
install, rather than options.setup_[ca|kra]

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-01-18 11:51:18 +01:00
Alexander Bokovoy 9b456101a3 adtrustinstance: make sure NetBIOS name defaults are set properly
Some tools may pass None as NetBIOS name if not put explicitly by a
user. This meant to use default NetBIOS name generator based on the
domain (realm) name. However, this wasn't done properly, so None is
passed later to python-ldap and it rejects such LDAP entry.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-01-17 19:32:47 +01:00
Florence Blanc-Renaud 717ae87a75 Nightly tests: test on f38 and f39
Fedora 39 is now officically available. Update the test definitions:
- lastest now uses f39
- previous now uses f38

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2024-01-12 18:46:41 -05:00
Alexander Bokovoy a5d38ca171 host: update System: Manage Host Keytab permission
Since commit 5c0e7a5fb4, a new extended
operation to get a keytab is supposed to be used. This keytab
setting/retrieval extended operation checks access rights of the bound
DN to write to a virtual attribute 'ipaProtectedOperation;write_keys'.

If the write isn't allowed, the operation is rejected and ipa-getkeytab
tool falls back to an older code that generates the keytab on the client
and forcibly sets to the LDAP entry. For the latter, a check is done to
make sure the bound DN is allowed to write to 'krbPrincipalKey' attribute.

This fallback should never happen for newer deployments. When enrollemnt
operation is delegated to non-administrative user with the help of 'Host
Enrollment' role, a host can be pre-created or created at enrollment
time, if this non-administrative user has 'Host Administrators' role. In
the latter case a system permission 'System: Manage Host Keytab' grants
write access to 'krbPrincipalKey' attribute but lacks any access to the
virtual attributes expected by the new extended operation.

There is a second virtual attribute, 'ipaProtectedOperation;read_keys',
that allows to retrieve existing keys for a host. However, during
initial enrollment we do not allow to retrieve and reuse existing
Kerberos key: while 'ipa-getkeytab -r' would give ability to retrieve
the existing key, 'ipa-join' has no way to trigger that operation.
Hence, permission 'System: Manage Host Keytab' will not grant the right
to read the Kerberos key via extended operation used by 'ipa-getkeytab
-r'. Such operation can be done later by utilizing 'ipa
service/host-allow-retrieve-keytab' commands.

Fix 'System: Manage Host Keytab' permission and extend a permission test
to see that we do not fallback to the old extended operation.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-01-12 18:41:01 -05:00
Carla Martinez 2874823c12 ipatests: test new columns in group details
Test for checking the new columns 'givenname', 'sn' and 'nsaccountlock'.

Signed-off-by: Carla Martinez <carlmart@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
Reviewed-By: Carla Martinez <carlmart@redhat.com>
2024-01-12 15:26:45 +01:00
007hacky007 49c090b976 webui: Unify user group members columns with users columns
Adds 'givenname', 'sn' and 'nsaccountlock' columns to the user group members
and makes columns in the users view and user group members unified.
i.e. Makes easy to see disabled users in the group.

Fixes: https://pagure.io/freeipa/issue/9390
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
Reviewed-By: Carla Martinez <carlmart@redhat.com>
2024-01-12 15:26:45 +01:00
zoedong 2c0fe1dd92 ipaplatform: add opencloudos/tencentos support
Fixes:https://pagure.io/freeipa/issue/9501

Signed-off-by: zoedong <zoedong@tencent.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-01-12 08:36:20 -05:00
Rob Crittenden e5a9e46138 get_directive: don't error out on substring mismatch
This function is designed to retrieve a value from an
ini-like file. In particular PKI CS.cfg.

In an attempt to be more efficient a substring search,
using startswith(), is used before calling a regular
expression match.

The problem is that if the requested directive is a
substring of a different one then it will pass the
startswith() and fail the regular expression match
with a ValueError, assuming it is malformed.

There is no need for this. The caller must be able to
handle None as a response anyway. So continue if
no match is found.

This was seen when PKI dropped storing certificate blobs
in CS.cfg. The CA certificate is stored in ca.signing.cert.
If it isn't present then ca.signing.certnickname will match
the substring but not the directive. This should not be
treated as an error.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-01-11 17:19:47 +01:00
Rob Crittenden 2a95a05f9e Server affinity: Retain user-requested remote server
We want to avoid splitting a replica server installation between
two hosts where possible so if a CA or KRA is requested then
we only try to install against a remote server that also provides
those capabilities. This avoids race conditions.

If a CA or KRA is not requested and the user has provided a
server to install against then use that instead of overriding it.

Extend the logic of picking the remote Custodia mode
(KRA, CA, *MASTER*) to include considering whether the
CA and KRA services are requested. If the service(s) are
not requested the the associated hostname may not be
reliable.

Fixes: https://pagure.io/freeipa/issue/9491
Related: https://pagure.io/freeipa/issue/9289

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2024-01-11 17:15:53 +01:00
Rob Crittenden 54fb1173f9 ipa-client-automount: Don't use deprecated ipadiscovery.IPADiscovery
This class was moved to ipaclient/discovery.py in e6d560af66 to make
it available to PyPI.

Related: https://pagure.io/freeipa/issue/9487

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
2024-01-11 17:13:35 +01:00
Rob Crittenden ce811db6be ipatests: Test client install/uninstall with automount enabled
The automount installation was failing. Confirm that it is fixed.

The uninstall was not restoring all files/configuration. Verify
that the index and state files are gone which means that all state
and files were restored.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
2024-01-11 17:13:35 +01:00
Rob Crittenden e4420624ff Fix ipa-client-automount install/uninstall with new install states
Issue 8384 introduced a new installation state for the statestore
to identify when client/server installation is completely finished
rather than relying on has_files().

The problem is that ipa-client-automount may be called during
ipa-client-install and since installation is not complete at that
point the automount install was failing with "IPA client not
configured".

Add a new state, 'automount', to designate that automount installation
is in process. If check_client_configuration() fails it checks to
see if [installation] automount is True. If so it continues with the
installation.

This also addresses an issue where the filestore and statestore are
shared between the client and automount installers but the client
wasn't refreshing state after automount completed. This resulted in
an incomplete state and index file of backed-up files which caused
files to not be restored on uninstall and the state file to be
orphaned.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
2024-01-11 17:13:35 +01:00
Sudhir Menon 8ef3d6ce5c ipatests: Skip ds_encryption tests on RHEL9 SUT.
test_ipahealthcheck_ds_encryption tests are failing
in RHEL9 SUT because in this test tls protocol version
is set to TLS1.0 using the below command, but its
reset to TLS1.2 causing the test to fail.

'dsconf', 'slapd-TESTREALM-TEST', 'security', 'set', '--tls-protocol-min=TLS1.0'

Hence the test is skipped to be run on RHEL9.0 SUT.

Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-01-10 14:58:49 -05:00
Rob Crittenden a44cb09713 ACME: Don't treat pki-server ca-config-show failures as fatal
Up to PKI 11.5.0 even when a pki-server call failed it had a
return value of 0. This was fixed in 11.5.0 which breaks
ipa-acme-manage pruning. If a configuration value is not set
then the call fails and the tool gives up with an error like:

ERROR: No such parameter: jobsScheduler.job.pruning.certRetentionUnit

In previous versions this resulted in an empty string so the tool
displayed the default value.

So now upon failure look in the stderr output for "No such parameter"
and return an empty string so the behavior is consistent between
both old and new PKI server versions.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-01-10 13:35:51 -05:00
Rob Crittenden 86b073a7f0 Integration tests for verifying Referer header in the UI
Validate that the change_password and login_password endpoints
verify the HTTP Referer header. There is some overlap in the
tests: belt and suspenders.

All endpoints except session/login_x509 are covered, sometimes
having to rely on expected bad results (see the i18n endpoint).

session/login_x509 is not tested yet as it requires significant
additional setup in order to associate a user certificate with
a user entry, etc.

This can be manually verified by modifying /etc/httpd/conf.d/ipa.conf
and adding:

Satisfy Any
Require all granted

Then comment out Auth and SSLVerify, etc. and restart httpd.

With a valid Referer will fail with a 401 and log that there is no
KRB5CCNAME. This comes after the referer check.

With an invalid Referer it will fail with a 400 Bad Request as
expected.

CVE-2023-5455

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
2024-01-10 10:27:06 +01:00
Rob Crittenden 13778d88ca Check the HTTP Referer header on all requests
The referer was only checked in WSGIExecutioner classes:

 - jsonserver
 - KerberosWSGIExecutioner
 - xmlserver
 - jsonserver_kerb

This left /i18n_messages, /session/login_kerberos,
/session/login_x509, /session/login_password,
/session/change_password and /session/sync_token unprotected
against CSRF attacks.

CVE-2023-5455

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
2024-01-10 10:26:51 +01:00
Rob Crittenden 11877d5903 Include supported migration scenarios in the ipa-to-ipa docs
Lay out the supported migration paths. Users are likely to get
creative with migration so we need to narrow the path for which
we can provide support.

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2024-01-09 16:15:23 -05:00
Florence Blanc-Renaud bf1110bda1 Tox: use sitepackages
Tox is creating a virtual environment before execution.
With python 3.12 the virtual env does not include any
more setuptools, so use setuptools from the globally
installed packages.

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-01-09 08:40:47 +01:00
Florence Blanc-Renaud 8d7bd6c6ab pylint: fix errors
Fix the following errors:
I0021(useless-suppression)
R1710(inconsistent-return-statements)
E1101(no-member)

Ignore the following errors:
E0601(used-before-assignment)
The variable is imported when the code is run in_server.

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-01-09 08:40:47 +01:00
Florence Blanc-Renaud 7f485ba7dc pylint: disable new checks
pylint 3.0 introduces new checks that raise too many errors:
    use-implicit-booleaness-not-comparison-to-string,
    use-implicit-booleaness-not-comparison-to-zero,
    broad-exception-raised,
Disable the new checks in pylintrc

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-01-09 08:40:47 +01:00
Florence Blanc-Renaud 020af153db pylint: updates related to deprecations
pylint 3.0 has deprectated a few functions:
- check_messages: Use utils.only_required_for_messages
- The config attribute of BaseChecker has been deprecated. You can
use checker.linter.config to access the global configuration object
instead of a checker-specific object
- Everything related to the __implements__ construct was removed.
- Checker should only inherit BaseChecker or any of the other checker
types from pylint.checkers.

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-01-09 08:40:47 +01:00
Florence Blanc-Renaud 8981ede1a2 azure tests: move to fedora 39
Update python3 to ensure the fix for BZ 2252567 is pulled.

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2024-01-09 08:40:47 +01:00
Alexander Bokovoy c3bc938650 ipatests: make sure PKINIT enrollment works with a strict policy
Previously, for a global policy which does not include
'password', krb5kdc restart was failing. Now it should succeed.

We set admin user authentication type to PASSWORD to simplify
configuration in the test.

What matters here is that global policy does not include PKINIT and that
means a code in the ticket policy check will allow PKINIT implicitly
rather than explicitly.

Related: https://pagure.io/freeipa/issue/9485

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2023-12-22 10:34:19 +01:00
Alexander Bokovoy 62c44c9e69 ipa-kdb: clarify user auth table mapping use of _AUTH_PASSWORD
Related: https://pagure.io/freeipa/issue/9485

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2023-12-22 10:34:19 +01:00
Alexander Bokovoy 69ae9febfb ipa-kdb: when applying ticket policy, do not deny PKINIT
PKINIT differs from other pre-authentication methods by the fact that it
can be matched indepedently of the user authentication types via certmap
plugin in KDC.

Since PKINIT is a strong authentication method, allow its authentication
indicator and only apply the ticket policy.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2023-12-22 10:34:19 +01:00
Alexander Bokovoy 00f8ddbfd2 ipa-kdb: add better detection of allowed user auth type
If default user authentication type is set to a list that does not
include a password or a hardened credential, the resulting configuration
might be incorrect for special service principals, including a krbtgt/..
one.

Add detection of special principals to avoid these situations and always
allow password or hardened for services.

Special handling is needed for the following principals:

 - krbtgt/..       -- TGT service principals
 - K/M             -- master key principal
 - kadmin/changepw -- service for changing passwords
 - kadmin/kadmin   -- kadmin service principal
 - kadmin/history  -- key used to encrypt history

Additionally, implicitly allow password or hardened credential use for
IPA services and IPA hosts since applications typically use keytabs for
that purpose.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2023-12-22 10:34:19 +01:00
Thorsten Scherf 821259f069 ipa-client: Check if IPA CA cert is empty
IPA CA file should not be used when file is empty.

Fixes: https://pagure.io/freeipa/issue/9499
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-12-19 16:24:19 +01:00
Florence Blanc-Renaud a177121af6 ipatests: disable dnssec validation in tests using dnf
The 2 following tests rely on dnf install and use
mirrors.fedoraproject.org which has a broken trust chain.
Disable dnssec validation so that dnf succeeds.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-12-19 14:59:42 +01:00
Rob Crittenden d1e09c68af ipatests: Verify that hbactest will return messages
Limit the sizelimit of the hbactest request to confirm that
the output includes a SearchResultTruncated message.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-12-19 12:58:50 +01:00
Rob Crittenden 48846e98e5 hbactest was not collecting or returning messages
hbactest does a number of internal searches, one of which
can exceed the configured sizelimit: hbacrule-find

Collect any messages returned from thsi call and display them
to the user on the cli.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-12-19 12:58:50 +01:00
Endi S. Dewata dc2ab91681 Remove unused pki_theme_* params
The pki_theme_enable and pki_theme_server_dir params are not
used by pkispawn so they can be removed.

Signed-off-by: Endi Sukma Dewata <edewata@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-12-19 12:51:46 +01:00
Mark Reynolds 6d3d191825 Issue 9497 - update debug logging in ipa_uuid
Fixes: https://pagure.io/freeipa/issue/9497

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-12-14 09:24:46 +01:00
Mark Reynolds 0007876f42 Issue 9497 - update debug logging in ipa-pwd-extop
Fixes: https://pagure.io/freeipa/issue/9497

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-12-14 09:24:46 +01:00
Mark Reynolds 6cd5a0847a Issue 9497 - update debug logging in ipa_otp_lasttoken
Fixes: https://pagure.io/freeipa/issue/9497

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-12-14 09:24:46 +01:00
Mark Reynolds 2a1d454c74 Issue 9497 - update debug logging in ipa_otp_counter
Fixes: https://pagure.io/freeipa/issue/9497

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-12-14 09:24:46 +01:00
Mark Reynolds 79b08556a4 Issue 9497 - update debug logging in ipa_modrdn
Fixes: https://pagure.io/freeipa/issue/9497

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-12-14 09:24:46 +01:00
Mark Reynolds 23ead1dc23 Issue 9497 - update debug logging in ipa_lockout
Fixes: https://pagure.io/freeipa/issue/9497

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-12-14 09:24:46 +01:00
Mark Reynolds 8a6361dc75 Issue 9497 - update debug logging in ipa_graceperiod
Fixes: https://pagure.io/freeipa/issue/9497

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-12-14 09:24:46 +01:00
Mark Reynolds 1a16130a9a Issue 9497 - Update logging in ipa_enrollment
Fixes: https://pagure.io/freeipa/issue/9497

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-12-14 09:24:46 +01:00
Mark Reynolds 3fd5d57ed6 Issue 9497 - Add new password policy logging function
Fixes: https://pagure.io/freeipa/issue/9497

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-12-14 09:24:46 +01:00
Florence Blanc-Renaud 25b58e6dea Webui: use service options to init Firefox driver
With selenium driver 4.10 and above, the API for Firefox driver
initialization has changed and does not use any more the
log_path argument.

The log path is now provided through a FirefoxService option
in the webdriver initialization.

Fixes: https://pagure.io/freeipa/issue/9492
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2023-12-11 11:51:43 +01:00
Florence Blanc-Renaud 9abb50eb1e test_install: restart services after date change
The test TestKRAinstallAfterCertRenew is moving the
date in the future in order to reach the grace period where
certmonger detects some certificates need to be renewed.
Restart the services after the date change.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2023-12-11 09:55:20 +01:00
Florence Blanc-Renaud 53951ca860 test_external_idp: update code for selenium 4.10
The integration test is using selenium web driver to simulate a
user authentication with an external IdP. The user performs kinit
and is provided with a URL where he needs to authenticate.

The test was written for selenium API 4.9 and must be adapted to
the changes introduced in 4.10:
- the headless method has been deprecated
- executable_path argument has been deprecated

Fixes: https://pagure.io/freeipa/issue/9493
Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2023-12-11 09:52:05 +01:00
Florence Blanc-Renaud d61d1b059c Make test_external_ca.py compatible with crypto 41.0.0
The integration test test_external_ca.py is not compatible with
python-cryptography 41.0.0+.

The test is installing ipa server with an externally-signed CA cert
using a Microsoft Certificate Service profile:
ipa-server-install --external-ca --external-ca-type ms-cs
                    --external-ca-profile "1.2.3.4:10:200"
The command generates a CSR in /root/ipa.csr. The test reads the CSR,
extracts the extensions and compares with the requested extension
for the Microsoft Template.
With python-cryptography 41.0.0+, the extension can be decoded as
cryptography.x509.MSCertificateTemplate while with older version
the extension is decoded as cryptography.x509.UnrecognizedExtension.

Handle both cases properly.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2023-12-11 09:49:47 +01:00
Florence Blanc-Renaud 5028b391f1 Integration tests: disable test_sso
Changes in ipa-tuura project are breaking the test
(removal of a script required for test preparation).
Disable the test until a solution is found in ipa-tuura.

Related: https://pagure.io/freeipa/issue/9476

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Antonio Torres <antorres@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2023-12-04 15:58:07 +01:00
Christian Heimes 5deeee31c0 Add 'cache_dir' option to api.env
`api.env` now has a `cache_dir` option, which defaults to
`os.path.join(USER_CACHE_PATH, 'ipa')`. Schema cache, server info, and
KRA key cache use `api.env.cache_dir` as base directory. The option
allows application to set a custom cache directory.

Related: https://pagure.io/freeipa/issue/9438
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1513934
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-12-01 09:46:31 +01:00
Mark Reynolds 5c8614157d Issue 3656 - Extend schema function to return MAY or MUST attrs
Add new paramters to get_allowed_attributes() to return just MAY or MUST
attributes

Related: https://pagure.io/freeipa/issue/3656

Signed-off-by: Mark Reynolds <mreynolds@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Christian Heimes <cheimes@redhat.com>
2023-11-28 17:09:32 +01:00
Alexander Bokovoy 7ee2d7d359 doc/designs: add description of identity mapping in IPA
Fixes: https://pagure.io/freeipa/issue/9477

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-11-28 17:02:47 +01:00
Alexander Bokovoy 6bc9e9d06e Remove upgrade test from Azure CI
It is already running in PR CI for all kinds of targets:

ipatests/prci_definitions/gating.yaml:        test_suite: test_integration/test_upgrade.py
ipatests/prci_definitions/nightly_latest.yaml:        test_suite: test_integration/test_upgrade.py
ipatests/prci_definitions/nightly_latest_389ds.yaml:        test_suite: test_integration/test_upgrade.py
ipatests/prci_definitions/nightly_latest_pki.yaml:        test_suite: test_integration/test_upgrade.py
ipatests/prci_definitions/nightly_latest_selinux.yaml:        test_suite: test_integration/test_upgrade.py
ipatests/prci_definitions/nightly_latest_testing.yaml:        test_suite: test_integration/test_upgrade.py
ipatests/prci_definitions/nightly_latest_testing_selinux.yaml:        test_suite: test_integration/test_upgrade.py
ipatests/prci_definitions/nightly_previous.yaml:        test_suite: test_integration/test_upgrade.py
ipatests/prci_definitions/nightly_rawhide.yaml:        test_suite: test_integration/test_upgrade.py

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-11-28 17:02:47 +01:00
Rafael Guterres Jeffman 60fe752da4 ipaserver/dcerpc: avoid logging stack trace in retrieve_anonymously
If an error occured when searching foc a DC a stack trace was logged,
and execution was aborted.

This patch allows execution to continue and log the error message that
caused the 'finddc' do fail.

Fixes: https://pagure.io/freeipa/issue/9484
Related: https://issues.redhat.com/browse/RHEL-12149

Signed-off-by: Rafael Guterres Jeffman <rjeffman@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-11-27 18:17:34 +01:00
Alexander Bokovoy 5e17c134aa Remove ipaserver.custodia.__init__.py
Use native Python namespaces instead.

Related: https://pagure.io/freeipa/issue/9467

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
2023-11-27 18:15:44 +01:00
Antonio Torres 519685823b Update translations to FreeIPA master state
Signed-off-by: Antonio Torres <antorres@redhat.com>
2023-11-20 14:44:56 +01:00
Christian Heimes d97d62dead docs: Mention that Keycloak requires openid scope
See: https://www.keycloak.org/docs/latest/upgrading/index.html#userinfo-endpoint-changes
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-11-17 11:56:19 -05:00
Rob Crittenden f00b52ce6d ipatests: fix expected output for ipahealthcheck.ipa.host
ipa-healthcheck commit e69589d5 changed the output when a service
keytab is missing to not report the GSSAPI error but to report
that the keytab doesn't exist at all. This distinguishes from real
Kerberos issues like kvno.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2023-11-16 15:51:03 -05:00
Rob Crittenden d659d21b43 ipatests: ignore nsslapd-accesslog-logbuffering WARN in healthcheck
Log buffering is disabled in the integration tests so we can have all
the logs at the end. This is causing a warning to show in the 389-ds
checks and causing tests to fail that expect all SUCCESS.

Add an exclude for this specific key so tests will pass again.

We may eventually want a more sophisiticated mechanism to handle
excludes, or updating the config in general, but this is fine for now.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
Reviewed-By: Michal Polovka <mpolovka@redhat.com>
2023-11-16 15:51:03 -05:00
Jeremy Frasier c63fe925fb Fixes: Python SyntaxWarnings about invalid escape sequences
Otherwise we get some SyntaxWarnings about invalid escape sequences
such as '\d' and '\{', e.g.:
  /usr/sbin/ipa-replica-manage:393: SyntaxWarning: invalid escape sequence '\{'
    data = re.match('\{replica (\d+) (ldap://.*:\d+)\}(\s+\w+\s+\w*){0,1}', ruv)
  /usr/sbin/ipa-replica-manage:721: SyntaxWarning: invalid escape sequence '\d'
    (re.sub(':\d+', '', x), y)
  /usr/sbin/ipa-replica-manage:726: SyntaxWarning: invalid escape sequence '\d'
    (re.sub(':\d+', '', x), y)

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

Signed-off-by: Jeremy Frasier <jeremy.frasier@gwe.cisa.dhs.gov>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2023-11-16 15:06:26 -05:00
Florence Blanc-Renaud 07e5637269 ipatests: fix expected output for ipahealthcheck.meta.services
ipa-healthcheck commit 31be12b introduced a change in the output
message when pki-tomcatd is not running.
With versions <= 0.12, the service name is displayed as
pki_tomcatd (with an underscore), but with 0.13+ it is
pki-tomcatd (with a dash).

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-11-13 16:39:52 -05:00
Rob Crittenden caccd6c693 WIP: Get the PKI version from the remote to determine the argument
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
2023-11-02 14:47:50 +01:00
Rob Crittenden 56a2bc5775 The PKI JSON API the revocation reason key may be case-sensitive
PKI 11.4.0 changed the reason keyword in the REST API from lower-case
to camel-case in https://github.com/dogtagpki/pki/commit/926eb221ce6

Use Reason instead of reason as the keyword for revocations
for PKI 11.4.0+

Related: https://pagure.io/freeipa/issue/9345

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
2023-11-02 14:47:50 +01:00
Florence Blanc-Renaud ed6fa6029d Handle samba changes in samba.security.dom_sid()
samba.security.dom_sid() in 4.19 now raises ValueError instead of
TypeError. Fix the expected exception.

Related: https://pagure.io/freeipa/issue/9466

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-10-23 13:35:01 +02:00
Florence Blanc-Renaud d50624dce9 group-add-member fails with an external member
The command ipa group-add-member --external aduser@addomain.test
fails with an internal error when used with samba 4.19.

The command internally calls samba.security.dom_sid(sid) which
used to raise a TypeError but now raises a ValueError
(commit 9abdd67 on https://github.com/samba-team/samba).

IPA source code needs to handle properly both exception types.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-10-19 13:57:40 -04:00
Sudhir Menon 9d49f403c2 ipatests: Skip the test failing due to FIPS policy
1. test_certmonger_reads_token_HSM test in test_installaton.py
is failing in FIPS/STIG mode with the below error.

SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY: Unable to import.
Error attempting to import private key in STIG mode

2. Adding the posfix config change, because there was a crash
seen in smtpd in FIPS mode.

ie. postconf -e smtpd_tls_fingerprint_digest=sha256

KCS: https://access.redhat.com/solutions/6958957

Signed-off-by: Sudhir Menon <sumenon@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-10-19 12:27:01 +02:00
Endi S. Dewata 1202d0149b Replace subsystem.select with CAInstance.is_crlgen_enabled()
The subsystem.select is not a reliable indicator to determine
whether the CA is a renewal master since there is no process in
PKI to update the param when the role of the instance changes
(from master to clone and vice versa) so the param has been
removed in PKI 11.5.

Instead, it's better to use CAInstance.is_crlgen_enabled() since
CRL generation is only enabled in a renewal master.

Signed-off-by: Endi Sukma Dewata <edewata@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-10-19 07:44:27 +02:00
Endi S. Dewata 44349cfa76 Remove unused hierarchy.select
The hierarchy.select param has been removed in PKI 11.5 so
it doesn't need to be updated in renew_ca_cert.in.

Signed-off-by: Endi Sukma Dewata <edewata@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-10-19 07:44:27 +02:00
Endi S. Dewata 5270d58a04 Enable LWCA monitor explicitly
Currently LWCA is only supported in IPA since the key
replication depends on Custodia, so LWCA is not actually
supported in regular PKI installation. However, currently
the AuthorityMonitor is enabled by default and it executes
a persistent search to monitor LWCA replication so it is
wasting resources in non-IPA environment.

To reduce unnecessary resource consumption the LWCA monitor
will be disabled by default in PKI, so IPA will need to
enable it explicitly for new and existing installations.

Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-10-19 07:42:28 +02:00
Rob Crittenden a8a923033b ipa-client: correct directory location by using constants instead
If something in the client sysrestore.state wasn't removed by
the installer a warning message was printed with an incorrect
location. Fix this by using constants instead.

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-10-19 07:40:47 +02:00
Florence Blanc-Renaud b6af3a43c7 ipalib: fix the IPACertificate validity dates
The class IPACertificate builds objects from x509 Certificate
objects and creates the not_valid_before and not_valid_after values
by converting to a timestamp + applying timezone delta to UTC + reading
from the timestamp. This results in applying twice the delta.

Use a simpler method that replaces the timezone info with UTC in the
datetime object.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-10-16 14:46:45 -04:00
Rob Crittenden 62454574a1 Allow password policy minlength to be removed like other values
This is a side-effect of adding the libpwquality options. It
imposes its own hardcoded minimum password length so some care
was needed to ensure that it isn't set too low.

So if there are no libpwquality options used then it's fine to
have no minlength in the policy.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2023-10-16 13:23:20 -04:00
Viktor Ashirov fe005dd388 WebUI: update favicon.ico
I noticed that FreeIPA favicon is a bit squished. I would like to unsquish it.
And resize it to 32x32 pixels as it would look a bit better on HiDPI screens.

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

Signed-off-by: Viktor Ashirov <vashirov@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Carla Martinez <carlmart@redhat.com>
2023-10-05 07:38:05 +02:00
Florence Blanc-Renaud 430054db41 ipatests: fix test_ipactl_scenario_check
The test is comparing the PID of services before and after
calling ipactl start, expecting to have the same value.
It should not compare the pid for ipa-dnskeysyncd as this service
is automatically restarted upon failure.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-10-04 09:20:44 -04:00
Florence Blanc-Renaud e459e5b8bc ipatests: fix healthcheck test for --indent option
ipa-healthcheck --indent option expects an integer. The error
message changed with ipa-healthcheck 0.13.
Recent versions also check that the value is in the range 0-32.

The test must be compatible with old and new versions.

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-10-04 09:17:52 -04:00
Florence Blanc-Renaud f9075f9f77 ipatests: fix healthcheck test without DNS
ipa-healthcheck has added a new check for ipa-ca record
missing. The test needs to be adapted to handle the new check.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-10-04 09:15:29 -04:00
Alexander Bokovoy b22605ee54 Azure CI: increase memory for forced reenrollment test
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-10-04 08:37:28 -04:00
Alexander Bokovoy 48cfe6848c Increase memory usage for Azure CI upgrade test
The test often fails when running in parallel to other tests as very
little memory is left. 389-ds memory autotuning causes database backend
to refuse working in such cases. 389-ds team suggested more memory has
to be made available.

Increate RAM for this test to 2.5GB instead of 2.2GB.

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-10-04 08:37:28 -04:00
Antonio Torres fe223cde95 Update list of contributors
Signed-off-by: Antonio Torres <antorres@redhat.com>
2023-10-03 14:57:20 +02:00
Antonio Torres 843f4a7458 Update translations to FreeIPA master state
Signed-off-by: Antonio Torres <antorres@redhat.com>
2023-10-03 14:56:42 +02:00
Alexander Bokovoy 1a2cd7f408 Use datetime.timezone.utc instead of newer datetime.UTC alias
datetime.UTC alias was added in Python 3.11:
https://docs.python.org/3/library/datetime.html#datetime.UTC

datetime.timezone.utc was present since Python 3.2.

Since RHEL 9 is using Python 3.9, use more compatible variant.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-09-29 15:06:33 -04:00
Christian Heimes 6aebfe74fb Add context manager to ipalib.API
`ipalib.API` instances like `ipalib.api` now provide a context manager
that connects and disconnects the API object. Users no longer have to
deal with different types of backends or finalize the API correctly.

```python
import ipalib

with ipalib.api as api:
    api.Commands.ping()
```

See: https://pagure.io/freeipa/issue/9443
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-09-29 12:57:06 +02:00
Florence Blanc-Renaud 8b70ee1ea8 Covscan issues: deadcode and Use after free
Covscan detected an unused value in ipa_kdb_principals.c
and a use-after-free in ipa-print-pac.c.

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

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-09-29 12:05:48 +02:00
Francisco Trivino 4af05dde48 Workshop: fix broken Sphinx cross-references.
Many of the workshop pages links are directing to URLs that end with
".rst" instead of ".html", as a result, these links are broken.

This commit introduces explicit targets and references to ensure that
the pages are correctly linked.

Signed-off-by: Francisco Trivino <ftrivino@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-09-26 11:30:33 +02:00
Mohammad Rizwan 496e3ace85 ipatests: restart ipa services after moving date
When system date is moved into future, it have unprecedented
behavior i.e CA becomes irresponsive or unexpected certificcate
state. Hence restart the ipa service after moving the date to
gracefully serve the request.

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

Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-09-18 17:51:30 +02:00
Christian Heimes 7ddf7711f3 Use find_spec() in meta importer
The `find_module()` method of meta importers has been deprecated for a
long time. Python 3.12 no longer falls back to `find_module()`.

See: https://docs.python.org/3.12/whatsnew/3.12.html#removed
Related: https://pagure.io/freeipa/issue/9437
Signed-off-by: Christian Heimes <cheimes@redhat.com>
Reviewed-By: Alexander Bokovoy <abbra@users.noreply.github.com>
2023-09-18 17:46:24 +02:00
Alexander Bokovoy 32721c4132 Allow ipa-otpd to access USB devices for passkeys
Main SELinux policy will allow transition of passkey_child (SSSD) to
ipa_otpd_t context to perform FIDO2 operations with USB devices.
This means ipa-otpd will need to be able to read data from sysfs and
connect to USB devices.

Add required permissions to IPA subpolicy as well. See rhbz#2238224 for
discussion.

Related: https://pagure.io/freeipa/issue/9434

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Zdenek Pytela <zpytela@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-09-18 17:36:40 +02:00
Rob Crittenden f248b22ef4 Don't assume KRB5CCNAME is in the environment in replica install
The replica install was unilaterally removing KRB5CCNAME from
os.environ in some cases. Instead check first to see if it is
present and only remove in that case.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
2023-09-14 07:59:44 +02:00
Alexandra Nikandrova dade02d5bb doc: typo in basic_usage.md
Reviewed-By: Antonio Torres <antorres@redhat.com>
2023-09-12 21:41:57 +02:00
Alexander Bokovoy 6aa3c3b628 Restore selinux states if they exist at uninstall time
Related: https://pagure.io/freeipa/issue/9434

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2023-09-12 14:32:00 -04:00
Alexander Bokovoy f123b01d81 updates: add ACIs for RBCD self-management
Fixes: https://pagure.io/freeipa/issue/9354

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Julien Rische <jrische@redhat.com>
2023-09-11 09:51:51 +02:00
Alexander Bokovoy d355761f23 ipa-client-install: enable SELinux for SSSD
For passkeys (FIDO2) support, SSSD uses libfido2 library which needs
access to USB devices. Add SELinux booleans handling to ipa-client-install
so that correct SELinux booleans can be enabled and disabled during
install and uninstall. Ignore and record a warning when SELinux policy
does not support the boolean.

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

Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-09-11 09:24:31 +02:00
Antonio Torres 2bc247d831 ipatests: rename 'ipatuura' directory to 'scim' in bridge tests
A recent commit [1] in ipa-tuura project renamed the 'ipatuura' django app
to 'scim'. Change it in IPA side as well to fix tests.

[1]: https://github.com/freeipa/ipa-tuura/commit/f12592cea496818af782f953e0e9643c9ea440b5

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

Signed-off-by: Antonio Torres <antorres@redhat.com>
Reviewed-By: Francisco Trivino <ftrivino@redhat.com>
2023-09-11 09:12:51 +02:00
Viktor Ashirov 953c7cc076 BDB tuning should be applied only when BDB backend is used
389DS supports BDB and LMDB backends. FreeIPA installation fails with
LMDB backend since it tries to apply tuning for BDB backend.

Instead, tuning for BDB should be applied only when 389DS uses BDB
backend.

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

Signed-off-by: Viktor Ashirov <vashirov@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-09-01 13:16:15 -04:00
Rob Crittenden 45fa43540f Configure affinity during server installation
Write a new krb5.conf in case any values changed finding the
right server to configure against (e.g. for CA, KRA) and
ensure the API connection is to the remote server that
will be installed against.

When finding a CA or KRA during initial replica installation
set the remote master as well. The order is:

 - existing server value in /etc/ipa/default.conf
 - the chosen CA host if the server doesn't provide one
 - the chosen KRA host if the server doesn't provide one

This is more or less heirarchical. If a server is provided
then that is considered first. If it provides all the
optional services needed (CA and/or KRA) then it will
be used. Otherwise it will fall back to a server that provides
all the required services.

In short, providing --server either at client install or
with ipa-replica-install is no guarantee that it will
define all topology. This may be unexpected behavior.

For the case of adding a CA or KRA things are effectively
unchanged. This type of install does not appear to be
impacted by affinity issues.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-09-01 13:13:02 -04:00
Christian Heimes 8f25b2a74a Refactor CA file handling in replica installer
Clean up and remove obsolete code from ipa-replica-install. For several
versions replica installer first ensures that a host is an IPA client,
then promotes the client to a replica. The client installer code sets up
CA stores like IPA_CA_CRT already.

Related: https://pagure.io/freeipa/issue/9272
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Rafael Guterres Jeffman <rjeffman@redhat.com>
Reviewed-By: Thomas Woerner <twoerner@redhat.com>
2023-08-30 09:18:17 -04:00
Florence Blanc-Renaud 0654fb3737 idp: add the ipaidpuser objectclass when needed
The ipaidpuser objectclass is required for the attribute ipaidpsub.
When a user is created or modified with --idp-user-id, the operation
must ensure that the objectclass is added if missing.

Add a test for user creation and user modification with --idp-user-id.
Fixes: https://pagure.io/freeipa/issue/9433

Signed-off-by: Florence Blanc-Renaud <flo@redhat.com>
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
2023-08-30 09:13:23 -04:00
Rob Crittenden 317e7061d0 Adjust test to handle revocation reason REMOVE_FROM_CRL
The dogtag REST API has a change of behavior regarding
revocation reason 8, REMOVE_FROM_CRL. The XML interface
accepts it blindly and marks the certifiate as revoked.

This is complicated within RFC 5280 but the jist is that
it only affects a certificate on hold and only for delta
CRLs.

So this modifies the behavior of revocation 8 so that
the certificate is put on hold (6) first.

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2023-08-28 10:21:48 -04:00
Rob Crittenden ed52142c40 Use the PKI REST API wherever possible instead of XML
The XML API is already deprecated and will be removed in some
future release.

All but the updateCRL API has an equivalent in REST. The upstream
dogtag project documents most of the API at
https://github.com/dogtagpki/pki/wiki/REST-API . I say most
because not every API includes sample input/output. The
pki ca-cert command is a good substitute for seeing how the API
is used by their own tooling.

This changes no pre-existing conventions. All serial numbers are
converted to decimal prior to transmission and are treated as
strings to avoid previous limitations with sizing (which would
have been exacerbated by random serial numbers).

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

Signed-off-by: Rob Crittenden <rcritten@redhat.com>
Reviewed-By: Florence Blanc-Renaud <frenaud@redhat.com>
2023-08-28 10:21:48 -04:00
Mohammad Rizwan 8d081ce894 ipatests: accommodate DST in ACME cert expiry
There is one hour time difference between expiry of ACME cert if
the certificate is issued while daylight saving is start and
expires after DST ends. For 2023 daylight saving time start at
Sunday 12 March and ends at Sunday 5 November. Every certificate
which is expiring after November 5th will have 1 hour difference in
expiry.

Fix is to use 90days+2hours to expire the cert.

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

Signed-off-by: Mohammad Rizwan <myusuf@redhat.com>
Reviewed-By: Rob Crittenden <rcritten@redhat.com>
2023-08-23 13:10:02 -04:00
Antonio Torres 1251c15fae Bump to IPA 4.12
Signed-off-by: Antonio Torres <antorres@redhat.com>
2023-08-21 16:39:16 +02:00
351 changed files with 34859 additions and 27147 deletions

No files matched your search

+1 -1
View File
@@ -120,7 +120,7 @@ extraction:
- lxml
- gssapi
- netaddr
- netifaces
- ifaddr
- polib
- requests
- python-augeas
+2 -2
View File
@@ -10,5 +10,5 @@ ipaserver == @VERSION@
ipatests == @VERSION@
# keep pylint version in sync with current Fedora release
# F37 has 2.15.5
pylint ~= 2.15.5
# F39 has 3.0.25
pylint ~= 3.0.2
+10 -2
View File
@@ -29,7 +29,7 @@ aci: (targetfilter = "(objectclass=ipaca)")(version 3.0;acl "permission:System:
dn: cn=cas,cn=ca,dc=ipa,dc=example
aci: (targetattr = "cn || description")(targetfilter = "(objectclass=ipaca)")(version 3.0;acl "permission:System: Modify CA";allow (write) groupdn = "ldap:///cn=System: Modify CA,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=cas,cn=ca,dc=ipa,dc=example
aci: (targetattr = "cn || createtimestamp || description || entryusn || ipacaid || ipacaissuerdn || ipacarandomserialnumberversion || ipacasubjectdn || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaca)")(version 3.0;acl "permission:System: Read CAs";allow (compare,read,search) userdn = "ldap:///all";)
aci: (targetattr = "cn || createtimestamp || description || entryusn || ipacahsmconfiguration || ipacaid || ipacaissuerdn || ipacarandomserialnumberversion || ipacasubjectdn || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipaca)")(version 3.0;acl "permission:System: Read CAs";allow (compare,read,search) userdn = "ldap:///all";)
dn: cn=caacls,cn=ca,dc=ipa,dc=example
aci: (targetfilter = "(objectclass=ipacaacl)")(version 3.0;acl "permission:System: Add CA ACL";allow (add) groupdn = "ldap:///cn=System: Add CA ACL,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=caacls,cn=ca,dc=ipa,dc=example
@@ -147,7 +147,7 @@ aci: (targetattr = "usercertificate")(targetfilter = "(objectclass=ipahost)")(ve
dn: cn=computers,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "userpassword")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Manage Host Enrollment Password";allow (write) groupdn = "ldap:///cn=System: Manage Host Enrollment Password,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=computers,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "krblastpwdchange || krbprincipalkey")(targetfilter = "(&(!(memberOf=cn=ipaservers,cn=hostgroups,cn=accounts,dc=ipa,dc=example))(objectclass=ipahost))")(version 3.0;acl "permission:System: Manage Host Keytab";allow (write) groupdn = "ldap:///cn=System: Manage Host Keytab,cn=permissions,cn=pbac,dc=ipa,dc=example";)
aci: (targetattr = "ipaprotectedoperation;write_keys || krblastpwdchange || krbprincipalkey")(targetfilter = "(&(!(memberOf=cn=ipaservers,cn=hostgroups,cn=accounts,dc=ipa,dc=example))(objectclass=ipahost))")(version 3.0;acl "permission:System: Manage Host Keytab";allow (write) groupdn = "ldap:///cn=System: Manage Host Keytab,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=computers,cn=accounts,dc=ipa,dc=example
aci: (targetattr = "createtimestamp || entryusn || ipaallowedtoperform;read_keys || ipaallowedtoperform;write_keys || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipahost)")(version 3.0;acl "permission:System: Manage Host Keytab Permissions";allow (compare,read,search,write) groupdn = "ldap:///cn=System: Manage Host Keytab Permissions,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=computers,cn=accounts,dc=ipa,dc=example
@@ -374,6 +374,14 @@ dn: cn=sudorules,cn=sudo,dc=ipa,dc=example
aci: (targetattr = "cmdcategory || cn || createtimestamp || description || entryusn || externalhost || externaluser || hostcategory || hostmask || ipaenabledflag || ipasudoopt || ipasudorunas || ipasudorunasextgroup || ipasudorunasextuser || ipasudorunasextusergroup || ipasudorunasgroup || ipasudorunasgroupcategory || ipasudorunasusercategory || ipauniqueid || member || memberallowcmd || memberdenycmd || memberhost || memberuser || modifytimestamp || objectclass || sudonotafter || sudonotbefore || sudoorder || usercategory")(targetfilter = "(objectclass=ipasudorule)")(version 3.0;acl "permission:System: Read Sudo Rules";allow (compare,read,search) userdn = "ldap:///all";)
dn: dc=ipa,dc=example
aci: (targetattr = "cn || createtimestamp || description || entryusn || modifytimestamp || objectclass || ou || sudocommand || sudohost || sudonotafter || sudonotbefore || sudooption || sudoorder || sudorunas || sudorunasgroup || sudorunasuser || sudouser")(target = "ldap:///ou=sudoers,dc=ipa,dc=example")(version 3.0;acl "permission:System: Read Sudoers compat tree";allow (compare,read,search) userdn = "ldap:///anyone";)
dn: cn=topology,cn=ipa,cn=etc,dc=ipa,dc=example
aci: (targetfilter = "(|(objectclass=iparepltopoconf)(objectclass=iparepltoposegment))")(version 3.0;acl "permission:System: Add Topology Segments";allow (add) groupdn = "ldap:///cn=System: Add Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=topology,cn=ipa,cn=etc,dc=ipa,dc=example
aci: (targetattr = "iparepltoposegmentdirection || iparepltoposegmentleftnode || iparepltoposegmentrightnode || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal")(targetfilter = "(|(objectclass=iparepltopoconf)(objectclass=iparepltoposegment))")(version 3.0;acl "permission:System: Modify Topology Segments";allow (write) groupdn = "ldap:///cn=System: Modify Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=topology,cn=ipa,cn=etc,dc=ipa,dc=example
aci: (targetattr = "cn || createtimestamp || entryusn || iparepltopoconfroot || iparepltoposegmentdirection || iparepltoposegmentleftnode || iparepltoposegmentrightnode || iparepltoposegmentstatus || modifytimestamp || nsds5replicastripattrs || nsds5replicatedattributelist || nsds5replicatedattributelisttotal || objectclass")(targetfilter = "(|(objectclass=iparepltopoconf)(objectclass=iparepltoposegment))")(version 3.0;acl "permission:System: Read Topology Segments";allow (compare,read,search) groupdn = "ldap:///cn=System: Read Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=topology,cn=ipa,cn=etc,dc=ipa,dc=example
aci: (targetfilter = "(|(objectclass=iparepltopoconf)(objectclass=iparepltoposegment))")(version 3.0;acl "permission:System: Remove Topology Segments";allow (delete) groupdn = "ldap:///cn=System: Remove Topology Segments,cn=permissions,cn=pbac,dc=ipa,dc=example";)
dn: cn=trusts,dc=ipa,dc=example
aci: (targetattr = "cn || createtimestamp || entryusn || ipantadditionalsuffixes || ipantflatname || ipantsecurityidentifier || ipantsidblacklistincoming || ipantsidblacklistoutgoing || ipanttrustdirection || ipanttrusteddomainsid || ipanttrustpartner || modifytimestamp || objectclass")(version 3.0;acl "permission:System: Read Trust Information";allow (compare,read,search) userdn = "ldap:///all";)
dn: cn=trusts,dc=ipa,dc=example
+3 -2
View File
@@ -451,8 +451,9 @@ output: Entry('result')
output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
output: PrimaryKey('value')
command: batch/1
args: 1,1,2
args: 1,2,2
arg: Dict('methods*')
option: Str('keeponly*')
option: Str('version?')
output: Output('count', type=[<type 'int'>])
output: Output('results', type=[<type 'list'>, <type 'tuple'>])
@@ -1082,7 +1083,7 @@ option: Flag('all', autofill=True, cli_name='all', default=False)
option: Str('ca_renewal_master_server?', autofill=False)
option: Str('delattr*', cli_name='delattr')
option: Flag('enable_sid?', autofill=True, default=False)
option: StrEnum('ipaconfigstring*', autofill=False, cli_name='ipaconfigstring', values=[u'AllowNThash', u'KDC:Disable Last Success', u'KDC:Disable Lockout', u'KDC:Disable Default Preauth for SPNs'])
option: StrEnum('ipaconfigstring*', autofill=False, cli_name='ipaconfigstring', values=[u'AllowNThash', u'KDC:Disable Last Success', u'KDC:Disable Lockout', u'KDC:Disable Default Preauth for SPNs', u'EnforceLDAPOTP'])
option: Str('ipadefaultemaildomain?', autofill=False, cli_name='emaildomain')
option: Str('ipadefaultloginshell?', autofill=False, cli_name='defaultshell')
option: Str('ipadefaultprimarygroup?', autofill=False, cli_name='defaultgroup')
+5
View File
@@ -4,6 +4,7 @@ The following people have contributed to the FreeIPA project.
(Listed in alphabetical order within category)
Developers:
007hacky007
Abhijeet
Abhijeet Kasurde
Adam Misnyovszki
@@ -16,6 +17,7 @@ Developers:
Alexander Bokovoy
Alexander Koksharov
Alexander Scheel
Alexandra Nikandrova
Alexandre Mulatinho
Alexey Slaykovsky
Alexey Tikhonov
@@ -126,6 +128,7 @@ Developers:
Martin Bašti
Martin Košek
Martin Nagy
Masahiro Matsuya
Matt Rogers
Matthew Davis
mbhalodi
@@ -219,12 +222,14 @@ Developers:
Vit Mojzis
W. Michael Petullo
Weblate
Weblate Translation Memory
William Brown
William Jon McCann
Xiao-Long Chen
Yuri Chornoivan
Zdenek Pytela
zdover
zoedong
김인수
Documentation:
+2
View File
@@ -36,6 +36,8 @@ SUBDIRS = \
po \
pypi \
selinux \
selinux/nfast \
selinux/luna \
$(PYTHON_SUBDIRS) \
$(SERVER_SUBDIRS) \
$(NULL)
+5 -5
View File
@@ -20,8 +20,8 @@
# -> "1.0.0" #
########################################################
define(IPA_VERSION_MAJOR, 4)
define(IPA_VERSION_MINOR, 11)
define(IPA_VERSION_RELEASE, 0)
define(IPA_VERSION_MINOR, 12)
define(IPA_VERSION_RELEASE, 5)
########################################################
# For 'pre' releases the version will be #
@@ -49,7 +49,7 @@ define(IPA_VERSION_PRE_RELEASE, )
# This option works only with GNU m4: #
# it requires esyscmd m4 macro. #
########################################################
define(IPA_VERSION_IS_GIT_SNAPSHOT, yes)
define(IPA_VERSION_IS_GIT_SNAPSHOT, no)
########################################################
# git development branch: #
@@ -86,8 +86,8 @@ define(IPA_DATA_VERSION, 20100614120000)
# #
########################################################
define(IPA_API_VERSION_MAJOR, 2)
# Last change: add passkey support
define(IPA_API_VERSION_MINOR, 253)
# Last change: add keeponly option to batch command
define(IPA_API_VERSION_MINOR, 254)
########################################################
# Following values are auto-generated from values above
+1
View File
@@ -266,6 +266,7 @@ static int ldap_sasl_interact(LDAP *ld, unsigned flags, void *priv_data, void *s
error_message(krberr), krberr);
in->result = NULL;
in->len = 0;
krb5_free_context(krbctx);
ret = LDAP_LOCAL_ERROR;
break;
}
+7 -1
View File
@@ -29,6 +29,11 @@
#include "ipa-client-common.h"
#include "config.h"
int remove_principal(krb5_context context, krb5_keytab ktid,
const char *principal, int debug);
int remove_realm(krb5_context context, krb5_keytab ktid,
const char *realm, int debug);
#define KERBEROS_ERROR 1
#define OOM_ERROR 2
#define KEYTAB_ERROR 3
@@ -171,7 +176,8 @@ remove_realm(krb5_context context, krb5_keytab ktid, const char *realm, int debu
}
done:
krb5_kt_end_seq_get(context, ktid, &kt_cursor);
krb5_free_unparsed_name(context, entry_princ_s);
return rval;
}
+52 -1
View File
@@ -132,6 +132,56 @@ c \- compare\p
W \- self\-write\p
O \- self\-obliterate
.SH "AUDIT AND LOGGING"
The IPA API logs audit messages to systemd journal about each command executed
through IPA API on the IPA server. These messages can be found by grepping
systemd journal with \fBjournalctl -g IPA.API\fR command. The message includes
following information:
May 21 11:31:33 master1.ipa1.test /usr/bin/ipa[247422]: [IPA.API] [autobind]: user_del: SUCCESS [ldap2_140328582446688] {"uid": ["foobar"], "continue": false, "version": "2.253"}
.TP
\fB/usr/bin/ipa[247422]\fR
executable name and PID (`/mod_wsgi` for HTTP end-point)
.TP
\fB[IPA.API]\fR
marker to allow searches with \fBjournalctl -g IPA.API\R
.TP
\fBusername@REALM\fR
authenticated Kerberos principal or \fB[autobind]\fR marker for LDAP-based operations done as root
.TP
\fBuser_del\fR
name of the command executed
.TP
\fBSUCCESS\fR
result of execution: \fBSUCCESS\fR or an exception name
.TP
\fB[ldap2_140328582446688]\fR
LDAP backend connection instance identifier. The identifier will be the same for all
operations performed under the same request. This allows to identify operations
which were executed using the same LDAP connection. For API operations that
didn't result in LDAP access, there will be \fB[no_connection_id]\fR marker.
.TP
\fB{"uid": ["foobar"], "continue": false, "version": "2.253"}\fR
a list of arguments and options passed to the IPA API command, provided in JSON
format. Credentials are filtered out.
.LP
All explicitly requested operations logged. Internal operations, initiated as
part of execution of the explicitly requested IPA API calls, aren't logged. For
HTTP end-point operations will be logged as performed by the '/mod_wsgi'
executable binary. Remaining details can be inspected through the systemd
journal as journald records execution context. See systemd.journal\-fields(7)
for details.
The details of the individual logged messages can be explained with the help of
'\fBjournalctl -x\fR' command, while full set of logged properties can be
retrieved with '\fBjournalctl -o json-pretty\fR'. See journalctl(1) for details
on the systemd journal viewer.
For the sample message above, an explanation could be requested with '\fBjournalctl -x -g ldap2_140328582446688\fR' where LDAP backend connection instance identifier can be used to uniquely fetch that individual message.
.SH "EXAMPLES"
.TP
\fBipa help commands\fR
@@ -206,4 +256,5 @@ IPA default configuration file.
ipa\-client\-install(1), ipa\-compat\-manage(1), ipactl(1), ipa\-dns\-install(1),
ipa\-getcert(1), ipa\-getkeytab(1), ipa\-join(1), ipa\-ldap\-updater(1),
ipa\-nis\-manage(1), ipa\-replica\-install(1), ipa\-replica\-manage(1), ipa\-replica\-prepare(1),
ipa\-rmkeytab(1), ipa\-server\-certinstall(2), ipa\-server\-install(1), ipa\-server\-upgrade(1)
ipa\-rmkeytab(1), ipa\-server\-certinstall(2), ipa\-server\-install(1), ipa\-server\-upgrade(1),
systemd.journal\-fields(7), journalctl(1)
+7 -1
View File
@@ -4,7 +4,13 @@ PubkeyAuthentication yes
${ENABLEPROXY}GlobalKnownHostsFile $KNOWNHOSTS
${VERIFYHOSTKEYDNS}VerifyHostKeyDNS yes
# use sss_ssh_knownhosts if available
# assumes that if a user does not have shell (/sbin/nologin),
# this will return nonzero exit code and proxy command will be ignored
${ENABLEPROXY}Match exec true
${ENABLEKNOWNHOSTS}Match exec true
${ENABLEKNOWNHOSTS} KnownHostsCommand $KNOWNHOSTSCOMMAND %H
# assumes that if a user does not have shell (/sbin/nologin),
# this will return nonzero exit code and proxy command will be ignored
${ENABLEPROXY}Match exec true
${ENABLEPROXY} ProxyCommand $KNOWNHOSTSPROXY -p %p %h
+9
View File
@@ -267,6 +267,13 @@ AC_ARG_WITH([systemdtmpfilesdir],
[systemdtmpfilesdir=$($PKG_CONFIG --define-variable=prefix='${prefix}' --variable=tmpfilesdir systemd)])
AC_SUBST([systemdtmpfilesdir])
AC_ARG_WITH([systemdcatalogdir],
AS_HELP_STRING([--with-systemdcatalogdir=DIR],
[Directory for systemd journal catalog files]),
[systemdcatalogdir=$with_systemdcatalogdir],
[systemdcatalogdir=$($PKG_CONFIG --define-variable=prefix='${prefix}' --variable=catalogdir systemd)])
AC_SUBST([systemdcatalogdir])
dnl ---------------------------------------------------------------------------
dnl - Server-only configuration
dnl ---------------------------------------------------------------------------
@@ -688,6 +695,8 @@ AC_CONFIG_FILES([
po/Makefile.in
po/Makefile.hack
selinux/Makefile
selinux/nfast/Makefile
selinux/luna/Makefile
util/Makefile
])
+1 -1
View File
@@ -116,7 +116,7 @@ ipa_kdb_tests_LDADD = \
$(top_builddir)/util/libutil.la \
-lkdb5 \
-lsss_idmap \
-lsamba-security-samba4 \
-l$(SAMBA_SECURITY_LIBS)\
-lsamba-errors \
$(NULL)
+14 -5
View File
@@ -12,9 +12,7 @@ much more easily managed.
The grouping mechanism has been built so that lookup is highly optimized
and is basically reduced to a single search that uses the derefernce
control. Speed is very important in this case because KDC operations
time out very quickly and unless we add a caching layer in ipa-kdb we
must keep the number of searches down to avoid client timeouts.
control.
The grouping mechanism is very simple a groupOfPrincipals object is
introduced, this Auxiliary class have a single optional attribute called
@@ -112,8 +110,7 @@ kinit -kt /etc/httpd/conf/ipa.keytab HTTP/ipaserver.example.com
kvno -U admin HTTP/ipaserver.example.com
# Perform S4U2Proxy
kvno -k /etc/httpd/conf/ipa.keytab -U admin -P HTTP/ipaserver.example.com
ldap/ipaserver.example.com
kvno -U admin -P ldap/ipaserver.example.com
If this works it means you successfully impersonated the admin user with
@@ -125,6 +122,18 @@ modprinc -ok_to_auth_as_delegate HTTP/ipaserver.example.com
Simo.
If IPA is compiled with krb5 1.20 and newer (KDB DAL >= 9), then the
behavior of S4U2Self changes: S4U2Self TGS-REQs produce forwardable
tickets for all requesters, except if the requester principal is set as
the proxy (impersonating service) in at least one `servicedelegation`
rule. In this case, even if the rule has no target, the KDC will
response to S4U2Self requests with a non-forwardable ticket. Hence,
granting the `ok_to_auth_as_delegate` permission to the proxy service
remains the only way for this service to obtain the evidence ticket
required for general constrained delegation requests if this ticket is
not provided by the client.
[1]
Note that here I use the term proxy in a different way than it is used in
the krb interfaces. It may seem a bit confusing but I think people will
+1 -1
View File
@@ -494,7 +494,7 @@ init_with_password(const char *name, const char *password)
done:
if (service_creds != GSS_C_NO_CREDENTIAL)
gss_release_cred(&min, &client_creds);
gss_release_cred(&min, &service_creds);
if (client_creds != GSS_C_NO_CREDENTIAL)
gss_release_cred(&min, &client_creds);
+79 -19
View File
@@ -26,6 +26,7 @@
#include "ipa_kdb.h"
#include "ipa_krb5.h"
#include "ipa_hostname.h"
#include <kadm5/admin.h>
#define IPADB_GLOBAL_CONFIG_CACHE_TIME 60
@@ -194,6 +195,9 @@ done:
return base;
}
/* In this table all _AUTH_PASSWORD entries will be
* expanded to include _AUTH_HARDENED in ipadb_parse_user_auth()
* which means there is no need to explicitly add it here */
static const struct {
const char *name;
enum ipadb_user_auth flag;
@@ -207,6 +211,19 @@ static const struct {
{ "idp", IPADB_USER_AUTH_IDP },
{ "passkey", IPADB_USER_AUTH_PASSKEY },
{ }
},
objclass_table[] = {
{ "ipaservice", IPADB_USER_AUTH_PASSWORD },
{ "ipahost", IPADB_USER_AUTH_PASSWORD },
{ }
},
princname_table[] = {
{ KRB5_TGS_NAME, IPADB_USER_AUTH_PASSWORD },
{ KRB5_KDB_M_NAME, IPADB_USER_AUTH_PASSWORD },
{ KADM5_ADMIN_SERVICE, IPADB_USER_AUTH_PASSWORD },
{ KADM5_CHANGEPW_SERVICE, IPADB_USER_AUTH_PASSWORD },
{ KADM5_HIST_PRINCIPAL, IPADB_USER_AUTH_PASSWORD },
{ }
};
void ipadb_parse_user_auth(LDAP *lcontext, LDAPMessage *le,
@@ -217,16 +234,48 @@ void ipadb_parse_user_auth(LDAP *lcontext, LDAPMessage *le,
*userauth = IPADB_USER_AUTH_NONE;
vals = ldap_get_values_len(lcontext, le, IPA_USER_AUTH_TYPE);
if (!vals)
return;
if (!vals) {
/* if there is no explicit ipaUserAuthType set, use objectclass */
vals = ldap_get_values_len(lcontext, le, "objectclass");
if (!vals)
return;
for (i = 0; vals[i]; i++) {
for (j = 0; userauth_table[j].name; j++) {
if (strcasecmp(vals[i]->bv_val, userauth_table[j].name) == 0) {
*userauth |= userauth_table[j].flag;
break;
for (i = 0; vals[i]; i++) {
for (j = 0; objclass_table[j].name; j++) {
if (strcasecmp(vals[i]->bv_val, objclass_table[j].name) == 0) {
*userauth |= objclass_table[j].flag;
break;
}
}
}
} else {
for (i = 0; vals[i]; i++) {
for (j = 0; userauth_table[j].name; j++) {
if (strcasecmp(vals[i]->bv_val, userauth_table[j].name) == 0) {
*userauth |= userauth_table[j].flag;
break;
}
}
}
}
/* If neither ipaUserAuthType nor objectClass were definitive,
* check the krbPrincipalName to see if it is krbtgt/ or K/M one */
if (*userauth == IPADB_USER_AUTH_NONE) {
ldap_value_free_len(vals);
vals = ldap_get_values_len(lcontext, le, "krbprincipalname");
if (!vals)
return;
for (i = 0; vals[i]; i++) {
for (j = 0; princname_table[j].name; j++) {
if (strncmp(vals[i]->bv_val, princname_table[j].name,
strlen(princname_table[j].name)) == 0) {
*userauth |= princname_table[j].flag;
break;
}
}
}
}
/* If password auth is enabled, enable hardened policy too. */
if (*userauth & IPADB_USER_AUTH_PASSWORD) {
@@ -400,6 +449,7 @@ int ipadb_get_connection(struct ipadb_context *ipactx)
struct timeval tv = { 5, 0 };
LDAPMessage *res = NULL;
LDAPMessage *first;
const char *stmsg;
int ret;
int v3;
@@ -479,13 +529,14 @@ int ipadb_get_connection(struct ipadb_context *ipactx)
}
/* get adtrust options using default refresh interval */
ret = ipadb_reinit_mspac(ipactx, false);
if (ret && ret != ENOENT) {
/* TODO: log that there is an issue with adtrust settings */
if (ipactx->lcontext == NULL) {
/* for some reason ldap connection was reset in ipadb_reinit_mspac
* and is no longer established => failure of ipadb_get_connection
*/
ret = ipadb_reinit_mspac(ipactx, false, &stmsg);
if (ret) {
if (stmsg) {
krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg);
}
/* Initialization of the MS-PAC generator is an optional dependency.
* Fail only if the connection was lost. */
if (!ipactx->lcontext) {
goto done;
}
}
@@ -495,18 +546,27 @@ int ipadb_get_connection(struct ipadb_context *ipactx)
done:
ldap_msgfree(res);
/* LDAP context should never be null on success, but keep this test out of
* security to make sure we do not return an invalid context. */
if (ret == 0 && !ipactx->lcontext) {
krb5_klog_syslog(LOG_WARNING, "Internal malfunction: LDAP connection "
"process resulted in an invalid context "
"(please report this incident)");
ret = LDAP_SERVER_DOWN;
}
if (ret) {
/* Cleanup LDAP context if connection failed. */
if (ipactx->lcontext) {
ldap_unbind_ext_s(ipactx->lcontext, NULL, NULL);
ipactx->lcontext = NULL;
}
if (ret == LDAP_SERVER_DOWN) {
return ETIMEDOUT;
}
return EIO;
/* Replace LDAP error code by POSIX error code. */
ret = ret == LDAP_SERVER_DOWN ? ETIMEDOUT : EIO;
}
return 0;
return ret;
}
static krb5_principal ipadb_create_local_tgs(krb5_context kcontext,
+55 -1
View File
@@ -94,6 +94,34 @@
#define IPA_KRB_AUTHZ_DATA_ATTR "ipaKrbAuthzData"
#define IPA_USER_AUTH_TYPE "ipaUserAuthType"
/* Virtual managed ticket flags like "-allow_tix", are always controlled by the
* "nsAccountLock" attribute, such flags should never be set in the database.
* The following expression combine all of them, and is used to filter them
* out. */
#define IPA_KDB_TKTFLAGS_VIRTUAL_MANAGED_ALL (KRB5_KDB_DISALLOW_ALL_TIX)
/* Virtual static ticket flags are hard-coded in the KDB driver. */
/* Virtual static mandatory flags are set systematically and implicitly for all
* principals. They are filtered out from database ticket flags updates.
* (However, "KRB5_KDB_REQUIRES_PRE_AUTH" can still be unset by the
* "KDC:Disable Default Preauth for SPNs" global setting) */
#define IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_MANDATORY (KRB5_KDB_REQUIRES_PRE_AUTH)
/* Virtual static default ticket flags are implicitly set for user and non-user
* (SPN) principals, and not stored in the database.
* (Except if the "IPA_KDB_STRATTR_FINAL_TKTFLAGS" string attribute is "true"
* the principal) */
/* Virtual static default user ticket flags are set for users only. The
* "-allow_svr" flag is set to protect them from CVE-2024-3183. */
#define IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_DEFAULTS_USER (KRB5_KDB_DISALLOW_SVR)
#define IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_DEFAULTS_SPN (0)
/* If this string attribute is set to "true", then only the virtual managed and
* virtual static mandatory ticket flags are applied and filtered out from
* database read and write operations for the concerned user principal.
* Configurable principal ticket flags are applied, but not the configurable
* global ticket policy flags. */
#define IPA_KDB_STRATTR_FINAL_USER_TKTFLAGS "final_user_tkt_flags"
struct ipadb_mspac;
struct dom_sid;
@@ -187,6 +215,21 @@ struct ipadb_e_data {
struct dom_sid *sid;
};
inline static krb5_error_code
ipadb_get_edata(krb5_db_entry *entry, struct ipadb_e_data **ied)
{
struct ipadb_e_data *in_ied;
in_ied = (struct ipadb_e_data *)entry->e_data;
if (!in_ied || in_ied->magic != IPA_E_DATA_MAGIC)
return EINVAL;
if (ied)
*ied = in_ied;
return 0;
}
struct ipadb_context *ipadb_get_context(krb5_context kcontext);
int ipadb_get_connection(struct ipadb_context *ipactx);
@@ -371,7 +414,9 @@ krb5_error_code ipadb_v9_issue_pac(krb5_context context, unsigned int flags,
krb5_data ***auth_indicators);
#endif
krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit);
krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx,
bool force_reinit,
const char **stmsg);
void ipadb_mspac_struct_free(struct ipadb_mspac **mspac);
krb5_error_code ipadb_check_transited_realms(krb5_context kcontext,
@@ -386,6 +431,14 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
const char *test_realm, size_t size,
char **trusted_realm);
/* Check the ticket provided in a TGS-REQ. In some situations, the ticket is
* expected to contain a PAC. If it is not the case, or if the function is
* enable to decode an authorization-data element, it fails.
* Any failure should result in the TGS-REQ to be rejected. */
krb5_error_code ipadb_enforce_pac(krb5_context kcontext,
const krb5_ticket *ticket,
const char **status);
/* DELEGATION CHECKS */
krb5_error_code ipadb_check_allowed_to_delegate(krb5_context kcontext,
@@ -430,3 +483,4 @@ int ipadb_string_to_sid(const char *str, struct dom_sid *sid);
void alloc_sid(struct dom_sid **sid);
void free_sid(struct dom_sid **sid);
bool dom_sid_check(const struct dom_sid *sid1, const struct dom_sid *sid2, bool exact_check);
bool ipadb_is_tgs_princ(krb5_context kcontext, krb5_const_principal princ);
+18
View File
@@ -767,3 +767,21 @@ krb5_error_code ipadb_multibase_search(struct ipadb_context *ipactx,
return ipadb_simple_ldap_to_kerr(ret);
}
bool
ipadb_is_tgs_princ(krb5_context kcontext, krb5_const_principal princ)
{
krb5_data *primary;
size_t l_tgs_name;
if (2 != krb5_princ_size(kcontext, princ))
return false;
primary = krb5_princ_component(kcontext, princ, 0);
l_tgs_name = strlen(KRB5_TGS_NAME);
if (l_tgs_name != primary->length)
return false;
return 0 == memcmp(primary->data, KRB5_TGS_NAME, l_tgs_name);
}
+104 -87
View File
@@ -99,120 +99,110 @@ static bool ipadb_match_member(char *princ, LDAPDerefRes *dres)
return false;
}
static krb5_error_code ipadb_match_acl(krb5_context kcontext,
LDAPMessage *results,
krb5_const_principal client,
krb5_const_principal target)
#if KRB5_KDB_DAL_MAJOR_VERSION >= 9
static krb5_error_code
ipadb_has_acl(krb5_context kcontext, LDAPMessage *ldap_acl, bool *res)
{
struct ipadb_context *ipactx;
krb5_error_code kerr;
LDAPMessage *lentry;
LDAPDerefRes *deref_results;
LDAPDerefRes *dres;
char *client_princ = NULL;
char *target_princ = NULL;
bool client_missing;
bool client_found;
bool target_found;
bool is_constraint_delegation = false;
size_t nrules = 0;
int ret;
bool in_res = false;
krb5_error_code kerr = 0;
ipactx = ipadb_get_context(kcontext);
if (!ipactx) {
if (!ipactx)
return KRB5_KDB_DBNOTINITED;
switch (ldap_count_entries(ipactx->lcontext, ldap_acl)) {
case 0:
break;
case -1:
kerr = EINVAL;
goto end;
default:
in_res = true;
goto end;
}
if ((client != NULL) && (target != NULL)) {
kerr = krb5_unparse_name(kcontext, client, &client_princ);
if (kerr != 0) {
goto done;
}
kerr = krb5_unparse_name(kcontext, target, &target_princ);
if (kerr != 0) {
goto done;
}
} else {
is_constraint_delegation = true;
}
end:
if (res)
*res = in_res;
lentry = ldap_first_entry(ipactx->lcontext, results);
if (!lentry) {
kerr = ENOENT;
goto done;
}
return kerr;
}
#endif
static krb5_error_code
ipadb_match_acl(krb5_context kcontext, LDAPMessage *ldap_acl,
krb5_const_principal client, krb5_const_principal target)
{
struct ipadb_context *ipactx;
LDAPMessage *rule;
LDAPDerefRes *acis, *aci;
char *client_princ = NULL, *target_princ= NULL;
bool client_missing, client_found, target_found;
int lerr;
krb5_error_code kerr;
ipactx = ipadb_get_context(kcontext);
if (!ipactx)
return KRB5_KDB_DBNOTINITED;
kerr = krb5_unparse_name(kcontext, client, &client_princ);
if (kerr)
goto end;
kerr = krb5_unparse_name(kcontext, target, &target_princ);
if (kerr)
goto end;
/* the default is that we fail */
kerr = ENOENT;
kerr = KRB5KDC_ERR_BADOPTION;
while (lentry) {
for (rule = ldap_first_entry(ipactx->lcontext, ldap_acl);
rule;
rule = ldap_next_entry(ipactx->lcontext, rule))
{
/* both client and target must be found in the same ACI */
client_missing = true;
client_found = false;
target_found = false;
ret = ipadb_ldap_deref_results(ipactx->lcontext, lentry,
&deref_results);
switch (ret) {
lerr = ipadb_ldap_deref_results(ipactx->lcontext, rule, &acis);
switch (lerr) {
case 0:
for (dres = deref_results; dres; dres = dres->next) {
nrules++;
if (is_constraint_delegation) {
/*
Microsoft revised the S4U2Proxy rules for forwardable
tickets. All S4U2Proxy operations require forwardable
evidence tickets, but S4U2Self should issue a
forwardable ticket if the requesting service has no
ok-to-auth-as-delegate bit but also no constrained
delegation privileges for traditional S4U2Proxy.
Implement these rules, extending the
check_allowed_to_delegate() DAL method so that the KDC
can ask if a principal has any delegation privileges.
Since target principal is NULL and client principal is
NULL in this case, we simply calculate number of rules associated
with the server principal to decide whether to deny forwardable bit
*/
continue;
}
if (client_found == false &&
strcasecmp(dres->derefAttr, "ipaAllowToImpersonate") == 0) {
for (aci = acis; aci; aci = aci->next) {
if (!client_found &&
0 == strcasecmp(aci->derefAttr, "ipaAllowToImpersonate"))
{
/* NOTE: client_missing is used to signal that the
* attribute was completely missing. This signals that
* ANY client is allowed to be impersonated.
* This logic is valid only for clients, not for targets */
client_missing = false;
client_found = ipadb_match_member(client_princ, dres);
client_found = ipadb_match_member(client_princ, aci);
}
if (target_found == false &&
strcasecmp(dres->derefAttr, "ipaAllowedTarget") == 0) {
target_found = ipadb_match_member(target_princ, dres);
if (!target_found &&
0 == strcasecmp(aci->derefAttr, "ipaAllowedTarget"))
{
target_found = ipadb_match_member(target_princ, aci);
}
}
ldap_derefresponse_free(deref_results);
ldap_derefresponse_free(acis);
break;
case ENOENT:
break;
default:
kerr = ret;
goto done;
kerr = lerr;
goto end;
}
if ((client_found == true || client_missing == true) &&
target_found == true) {
if ((client_found || client_missing) && target_found) {
kerr = 0;
goto done;
goto end;
}
lentry = ldap_next_entry(ipactx->lcontext, lentry);
}
if (nrules > 0) {
kerr = 0;
}
done:
end:
krb5_free_unparsed_name(kcontext, client_princ);
krb5_free_unparsed_name(kcontext, target_princ);
return kerr;
@@ -231,7 +221,7 @@ krb5_error_code ipadb_check_allowed_to_delegate(krb5_context kcontext,
char *srv_principal = NULL;
krb5_db_entry *proxy_entry = NULL;
struct ipadb_e_data *ied_server, *ied_proxy;
LDAPMessage *res = NULL;
LDAPMessage *ldap_gcd_acl = NULL;
if (proxy != NULL) {
/* Handle the case where server == proxy, this is allowed in S4U */
@@ -269,27 +259,54 @@ krb5_error_code ipadb_check_allowed_to_delegate(krb5_context kcontext,
goto done;
}
kerr = ipadb_get_delegation_acl(kcontext, srv_principal, &res);
/* Load general constrained delegation rules */
kerr = ipadb_get_delegation_acl(kcontext, srv_principal, &ldap_gcd_acl);
if (kerr) {
goto done;
}
kerr = ipadb_match_acl(kcontext, res, client, proxy);
if (kerr) {
goto done;
#if KRB5_KDB_DAL_MAJOR_VERSION >= 9
/*
* Microsoft revised the S4U2Proxy rules for forwardable tickets. All
* S4U2Proxy operations require forwardable evidence tickets, but
* S4U2Self should issue a forwardable ticket if the requesting service
* has no ok-to-auth-as-delegate bit but also no constrained delegation
* privileges for traditional S4U2Proxy. Implement these rules,
* extending the check_allowed_to_delegate() DAL method so that the KDC
* can ask if a principal has any delegation privileges.
*
* If target service principal is NULL, and the impersonating service has
* at least one GCD rule, then succeed.
*/
if (!proxy) {
bool has_gcd_rules;
kerr = ipadb_has_acl(kcontext, ldap_gcd_acl, &has_gcd_rules);
if (!kerr)
kerr = has_gcd_rules ? 0 : KRB5KDC_ERR_BADOPTION;
} else if (client) {
#else
if (client && proxy) {
#endif
kerr = ipadb_match_acl(kcontext, ldap_gcd_acl, client, proxy);
} else {
/* client and/or proxy is missing */
kerr = KRB5KDC_ERR_BADOPTION;
}
if (kerr)
goto done;
done:
if (kerr) {
#if KRB5_KDB_DAL_MAJOR_VERSION < 9
kerr = KRB5KDC_ERR_POLICY;
#else
#if KRB5_KDB_DAL_MAJOR_VERSION >= 9
kerr = KRB5KDC_ERR_BADOPTION;
#else
kerr = KRB5KDC_ERR_POLICY;
#endif
}
ipadb_free_principal(kcontext, proxy_entry);
krb5_free_unparsed_name(kcontext, srv_principal);
ldap_msgfree(res);
ldap_msgfree(ldap_gcd_acl);
return kerr;
}
+3 -6
View File
@@ -119,11 +119,8 @@ ipa_kdcpolicy_check_as(krb5_context context, krb5_kdcpolicy_moddata moddata,
pol_limits = &(ied->pol_limits[IPADB_USER_AUTH_IDX_RADIUS]);
} else if (strcmp(auth_indicator, "pkinit") == 0) {
valid_auth_indicators++;
if (!(ua & IPADB_USER_AUTH_PKINIT)) {
*status = "PKINIT pre-authentication not allowed for this user.";
kerr = KRB5KDC_ERR_POLICY;
goto done;
}
/* allow PKINIT unconditionally -- it has passed already at this
* point so some certificate was useful, only apply the limits */
pol_limits = &(ied->pol_limits[IPADB_USER_AUTH_IDX_PKINIT]);
} else if (strcmp(auth_indicator, "hardened") == 0) {
valid_auth_indicators++;
@@ -198,7 +195,7 @@ ipa_kdcpolicy_check_tgs(krb5_context context, krb5_kdcpolicy_moddata moddata,
*lifetime_out = 0;
*renew_lifetime_out = 0;
return 0;
return ipadb_enforce_pac(context, ticket, status);
}
krb5_error_code kdcpolicy_ipakdb_initvt(krb5_context context,
+302 -170
View File
@@ -496,8 +496,16 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
"krbCanonicalName", &strres);
if (ret) {
/* krbCanonicalName is mandatory for services */
return ret;
/* krbCanonicalName is mandatory for services but IPA services
* created before commit e6ff83e (FreeIPA 4.4.0, ~2016) had no
* normalization to set krbCanonicalName; services created after
* that version were upgraded to do have krbCanonicalName.
*
* Accept krbPrincipalName alone since they have no alias either */
ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
"krbPrincipalName", &strres);
if (ret)
return ret;
}
ret = krb5_parse_name(ipactx->kcontext, strres, &princ);
@@ -785,16 +793,16 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
return ret;
}
if (!ipactx->mspac) {
/* can't give a PAC without server NetBIOS name or primary group RID */
return ENOENT;
}
if (info3->base.primary_gid == 0) {
if (is_host || is_service) {
info3->base.primary_gid = 515; /* Well known RID for domain computers group */
} else {
if (ipactx->mspac->fallback_rid) {
info3->base.primary_gid = ipactx->mspac->fallback_rid;
} else {
/* can't give a pack without a primary group rid */
return ENOENT;
}
info3->base.primary_gid = ipactx->mspac->fallback_rid;
}
}
@@ -804,26 +812,16 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
/* always zero out, not used for Krb, only NTLM */
memset(&info3->base.key, '\0', sizeof(info3->base.key));
if (ipactx->mspac->flat_server_name) {
info3->base.logon_server.string =
talloc_strdup(memctx, ipactx->mspac->flat_server_name);
if (!info3->base.logon_server.string) {
return ENOMEM;
}
} else {
/* can't give a pack without Server NetBIOS Name :-| */
return ENOENT;
info3->base.logon_server.string =
talloc_strdup(memctx, ipactx->mspac->flat_server_name);
if (!info3->base.logon_server.string) {
return ENOMEM;
}
if (ipactx->mspac->flat_domain_name) {
info3->base.logon_domain.string =
talloc_strdup(memctx, ipactx->mspac->flat_domain_name);
if (!info3->base.logon_domain.string) {
return ENOMEM;
}
} else {
/* can't give a pack without Domain NetBIOS Name :-| */
return ENOENT;
info3->base.logon_domain.string =
talloc_strdup(memctx, ipactx->mspac->flat_domain_name);
if (!info3->base.logon_domain.string) {
return ENOMEM;
}
if (is_host || is_service) {
@@ -1036,6 +1034,11 @@ krb5_error_code ipadb_get_pac(krb5_context kcontext,
return KRB5_KDB_DBNOTINITED;
}
/* Check if PAC generator is initialized */
if (!ipactx->mspac) {
return ENOENT;
}
ied = (struct ipadb_e_data *)client->e_data;
if (ied->magic != IPA_E_DATA_MAGIC) {
return EINVAL;
@@ -1618,14 +1621,14 @@ static struct ipadb_adtrusts *get_domain_from_realm(krb5_context context,
{
struct ipadb_context *ipactx;
struct ipadb_adtrusts *domain;
int i;
size_t i;
ipactx = ipadb_get_context(context);
if (!ipactx) {
return NULL;
}
if (ipactx->mspac == NULL) {
if (!ipactx->mspac) {
return NULL;
}
@@ -1647,6 +1650,7 @@ static struct ipadb_adtrusts *get_domain_from_realm_update(krb5_context context,
{
struct ipadb_context *ipactx;
struct ipadb_adtrusts *domain;
const char *stmsg = NULL;
krb5_error_code kerr;
ipactx = ipadb_get_context(context);
@@ -1655,8 +1659,10 @@ static struct ipadb_adtrusts *get_domain_from_realm_update(krb5_context context,
}
/* re-init MS-PAC info using default update interval */
kerr = ipadb_reinit_mspac(ipactx, false);
kerr = ipadb_reinit_mspac(ipactx, false, &stmsg);
if (kerr != 0) {
if (stmsg)
krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg);
return NULL;
}
domain = get_domain_from_realm(context, realm);
@@ -1709,6 +1715,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
struct ipadb_e_data *ied = NULL;
int flags = 0;
struct dom_sid client_sid;
const char *stmsg = NULL;
#ifdef KRB5_KDB_FLAG_ALIAS_OK
flags = KRB5_KDB_FLAG_ALIAS_OK;
#endif
@@ -1722,10 +1729,14 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
* check that our own view on the PAC details is up to date */
if (ipactx->mspac->domsid.num_auths == 0) {
/* Force re-init of KDB's view on our domain */
kerr = ipadb_reinit_mspac(ipactx, true);
kerr = ipadb_reinit_mspac(ipactx, true, &stmsg);
if (kerr != 0) {
krb5_klog_syslog(LOG_ERR,
"PAC issue: unable to update realm's view on PAC info");
if (stmsg) {
krb5_klog_syslog(LOG_ERR, "MS-PAC generator: %s", stmsg);
} else {
krb5_klog_syslog(LOG_ERR, "PAC issue: unable to update " \
"realm's view on PAC info");
}
return KRB5KDC_ERR_POLICY;
}
}
@@ -1738,7 +1749,7 @@ static krb5_error_code check_logon_info_consistent(krb5_context context,
if (is_s4u && (ipactx->mspac->trusts != NULL)) {
/* Iterate through list of trusts and check if this SID belongs to
* one of the domains we trust */
for(int i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
for(size_t i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
result = dom_sid_check(&ipactx->mspac->trusts[i].domsid,
info->info->info3.base.domain_sid, true);
if (result) {
@@ -1850,11 +1861,11 @@ krb5_error_code filter_logon_info(krb5_context context,
struct ipadb_mspac *mspac_ctx = ipactx->mspac;
result = FALSE;
/* Didn't match but perhaps the original PAC was issued by a child domain's DC? */
for (k = 0; k < mspac_ctx->num_trusts; k++) {
result = dom_sid_check(&mspac_ctx->trusts[k].domsid,
for (size_t m = 0; m < mspac_ctx->num_trusts; m++) {
result = dom_sid_check(&mspac_ctx->trusts[m].domsid,
info->info->info3.base.domain_sid, true);
if (result) {
domain = &mspac_ctx->trusts[k];
domain = &mspac_ctx->trusts[m];
break;
}
}
@@ -2083,10 +2094,10 @@ static krb5_error_code ipadb_check_logon_info(krb5_context context,
return KRB5_KDB_DBNOTINITED;
}
/* In S4U case we might be dealing with the PAC issued by the trusted domain */
if ((ipactx->mspac->trusts != NULL)) {
if (ipactx->mspac->trusts) {
/* Iterate through list of trusts and check if this SID belongs to
* one of the domains we trust */
for(int i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
for(size_t i = 0 ; i < ipactx->mspac->num_trusts ; i++) {
result = dom_sid_check(&ipactx->mspac->trusts[i].domsid,
&client_sid, false);
if (result) {
@@ -2316,6 +2327,7 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context,
size_t i;
struct dom_sid *requester_sid = NULL;
struct dom_sid req_sid;
TALLOC_CTX *tmpctx = NULL;
if (signing_krbtgt != NULL &&
ipadb_is_cross_realm_krbtgt(signing_krbtgt->princ)) {
@@ -2371,6 +2383,12 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context,
goto done;
}
tmpctx = talloc_new(NULL);
if (tmpctx == NULL) {
kerr = ENOMEM;
goto done;
}
for (i = 0; i < num_buffers; i++) {
if (types[i] == KRB5_PAC_SERVER_CHECKSUM ||
types[i] == KRB5_PAC_PRIVSVR_CHECKSUM ||
@@ -2398,32 +2416,21 @@ krb5_error_code ipadb_common_verify_pac(krb5_context context,
DATA_BLOB pac_attrs_data;
krb5_boolean pac_requested;
TALLOC_CTX *tmpctx = talloc_new(NULL);
if (tmpctx == NULL) {
kerr = ENOMEM;
goto done;
}
kerr = ipadb_client_requested_pac(context, old_pac, tmpctx, &pac_requested);
if (kerr != 0) {
talloc_free(tmpctx);
if (kerr)
goto done;
}
kerr = ipadb_get_pac_attrs_blob(tmpctx, &pac_requested, &pac_attrs_data);
if (kerr) {
talloc_free(tmpctx);
if (kerr)
goto done;
}
data.magic = KV5M_DATA;
data.data = (char *)pac_attrs_data.data;
data.length = pac_attrs_data.length;
kerr = krb5_pac_add_buffer(context, new_pac, PAC_TYPE_ATTRIBUTES_INFO, &data);
if (kerr) {
talloc_free(tmpctx);
if (kerr)
goto done;
}
continue;
}
@@ -2470,6 +2477,8 @@ done:
if (kerr != 0 && (new_pac != *pac)) {
krb5_pac_free(context, new_pac);
}
if (tmpctx)
talloc_free(tmpctx);
krb5_free_data_contents(context, &pac_blob);
free(types);
return kerr;
@@ -2628,7 +2637,7 @@ static char *get_server_netbios_name(struct ipadb_context *ipactx)
void ipadb_mspac_struct_free(struct ipadb_mspac **mspac)
{
int i, j;
size_t i, j;
if (!*mspac) return;
@@ -2783,7 +2792,8 @@ ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx)
LDAPDN dn = NULL;
char **sid_blocklist_incoming = NULL;
char **sid_blocklist_outgoing = NULL;
int ret, n, i;
size_t i, n;
int ret;
ret = asprintf(&base, "cn=ad,cn=trusts,%s", ipactx->base);
if (ret == -1) {
@@ -2868,7 +2878,7 @@ ipadb_mspac_get_trusted_domains(struct ipadb_context *ipactx)
t[n].upn_suffixes_len = NULL;
if (t[n].upn_suffixes != NULL) {
int len = 0;
size_t len = 0;
for (; t[n].upn_suffixes[len] != NULL; len++);
@@ -2983,108 +2993,115 @@ done:
return ret;
}
krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit)
krb5_error_code
ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_reinit,
const char **stmsg)
{
char *dom_attrs[] = { "ipaNTFlatName",
"ipaNTFallbackPrimaryGroup",
"ipaNTSecurityIdentifier",
NULL };
char *grp_attrs[] = { "ipaNTSecurityIdentifier", NULL };
krb5_error_code kerr;
LDAPMessage *result = NULL;
LDAPMessage *lentry;
struct dom_sid gsid;
char *resstr;
int ret;
struct dom_sid gsid, domsid;
char *resstr = NULL;
char *flat_domain_name = NULL;
char *flat_server_name = NULL;
char *fallback_group = NULL;
uint32_t fallback_rid;
time_t now;
const char *in_stmsg = NULL;
int err;
krb5_error_code trust_kerr = 0;
/* Do not update the mspac struct more than once a minute. This would
* avoid heavy load on the directory server if there are lots of requests
* from domains which we do not trust. */
now = time(NULL);
if (ipactx->mspac != NULL &&
(force_reinit == false) &&
(now > ipactx->mspac->last_update) &&
(now - ipactx->mspac->last_update) < 60) {
return 0;
}
if (ipactx->mspac) {
if (!force_reinit &&
(now > ipactx->mspac->last_update) &&
(now - ipactx->mspac->last_update) < 60) {
/* SKIP */
err = 0;
goto end;
}
if (ipactx->mspac && ipactx->mspac->num_trusts == 0) {
/* Check if there is any trust configured. If not, just return
* and do not re-initialize the MS-PAC structure. */
kerr = ipadb_mspac_check_trusted_domains(ipactx);
if (kerr == KRB5_KDB_NOENTRY) {
kerr = 0;
goto done;
} else if (kerr != 0) {
goto done;
if (ipactx->mspac->num_trusts == 0) {
/* Check if there is any trust configured. If not, just return
* and do not re-initialize the MS-PAC structure. */
err = ipadb_mspac_check_trusted_domains(ipactx);
if (err) {
if (err == KRB5_KDB_NOENTRY) {
/* SKIP */
err = 0;
} else {
in_stmsg = "Failed to fetch trusted domains information";
}
goto end;
}
}
}
/* clean up in case we had old values around */
ipadb_mspac_struct_free(&ipactx->mspac);
ipactx->mspac = calloc(1, sizeof(struct ipadb_mspac));
if (!ipactx->mspac) {
kerr = ENOMEM;
goto done;
}
ipactx->mspac->last_update = now;
kerr = ipadb_simple_search(ipactx, ipactx->base, LDAP_SCOPE_SUBTREE,
"(objectclass=ipaNTDomainAttrs)", dom_attrs,
&result);
if (kerr == KRB5_KDB_NOENTRY) {
return ENOENT;
} else if (kerr != 0) {
return EIO;
err = ipadb_simple_search(ipactx, ipactx->base, LDAP_SCOPE_SUBTREE,
"(objectclass=ipaNTDomainAttrs)", dom_attrs,
&result);
if (err == KRB5_KDB_NOENTRY) {
err = ENOENT;
in_stmsg = "Local domain NT attributes not configured";
goto end;
} else if (err) {
err = EIO;
in_stmsg = "Failed to fetch local domain NT attributes";
goto end;
}
lentry = ldap_first_entry(ipactx->lcontext, result);
if (!lentry) {
kerr = ENOENT;
goto done;
err = ENOENT;
in_stmsg = "Local domain NT attributes not configured";
goto end;
}
ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
"ipaNTFlatName",
&ipactx->mspac->flat_domain_name);
if (ret) {
kerr = ret;
goto done;
err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry, "ipaNTFlatName",
&flat_domain_name);
if (err) {
in_stmsg = "Local domain NT flat name not configured";
goto end;
}
ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
"ipaNTSecurityIdentifier",
&resstr);
if (ret) {
kerr = ret;
goto done;
err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
"ipaNTSecurityIdentifier", &resstr);
if (err) {
in_stmsg = "Local domain SID not configured";
goto end;
}
ret = ipadb_string_to_sid(resstr, &ipactx->mspac->domsid);
if (ret) {
kerr = ret;
free(resstr);
goto done;
err = ipadb_string_to_sid(resstr, &domsid);
if (err) {
in_stmsg = "Malformed local domain SID";
goto end;
}
free(resstr);
resstr = NULL;
free(ipactx->mspac->flat_server_name);
ipactx->mspac->flat_server_name = get_server_netbios_name(ipactx);
if (!ipactx->mspac->flat_server_name) {
kerr = ENOMEM;
goto done;
flat_server_name = get_server_netbios_name(ipactx);
if (!flat_server_name) {
err = ENOMEM;
goto end;
}
ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
"ipaNTFallbackPrimaryGroup",
&ipactx->mspac->fallback_group);
if (ret && ret != ENOENT) {
kerr = ret;
goto done;
err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
"ipaNTFallbackPrimaryGroup", &fallback_group);
if (err) {
in_stmsg = (err == ENOENT)
? "Local fallback primary group not configured"
: "Failed to fetch local fallback primary group";
goto end;
}
/* result and lentry not valid any more from here on */
@@ -3092,53 +3109,81 @@ krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx, bool force_rein
result = NULL;
lentry = NULL;
if (ret != ENOENT) {
kerr = ipadb_simple_search(ipactx, ipactx->mspac->fallback_group,
LDAP_SCOPE_BASE,
"(objectclass=posixGroup)",
grp_attrs, &result);
if (kerr && kerr != KRB5_KDB_NOENTRY) {
kerr = ret;
goto done;
}
lentry = ldap_first_entry(ipactx->lcontext, result);
if (!lentry) {
kerr = ENOENT;
goto done;
}
if (kerr == 0) {
ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
"ipaNTSecurityIdentifier",
&resstr);
if (ret && ret != ENOENT) {
kerr = ret;
goto done;
}
if (ret == 0) {
ret = ipadb_string_to_sid(resstr, &gsid);
if (ret) {
free(resstr);
kerr = ret;
goto done;
}
ret = sid_split_rid(&gsid, &ipactx->mspac->fallback_rid);
if (ret) {
free(resstr);
kerr = ret;
goto done;
}
free(resstr);
}
}
err = ipadb_simple_search(ipactx, fallback_group, LDAP_SCOPE_BASE,
"(objectclass=posixGroup)", grp_attrs, &result);
if (err) {
in_stmsg = (err == KRB5_KDB_NOENTRY)
? "Local fallback primary group has no POSIX definition"
: "Failed to fetch SID of POSIX group mapped as local fallback " \
"primary group";
goto end;
}
kerr = ipadb_mspac_get_trusted_domains(ipactx);
lentry = ldap_first_entry(ipactx->lcontext, result);
if (!lentry) {
err = ENOENT;
goto end;
}
done:
err = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
"ipaNTSecurityIdentifier", &resstr);
if (err) {
in_stmsg = (err == ENOENT)
? "The POSIX group set as fallback primary group has no SID " \
"configured"
: "Failed to fetch SID of POSIX group set as local fallback " \
"primary group";
goto end;
}
err = ipadb_string_to_sid(resstr, &gsid);
if (err) {
in_stmsg = "Malformed SID of POSIX group set as local fallback " \
"primary group";
goto end;
}
err = sid_split_rid(&gsid, &fallback_rid);
if (err) {
in_stmsg = "Malformed SID of POSIX group mapped as local fallback " \
"primary group";
goto end;
}
/* clean up in case we had old values around */
ipadb_mspac_struct_free(&ipactx->mspac);
ipactx->mspac = calloc(1, sizeof(struct ipadb_mspac));
if (!ipactx->mspac) {
err = ENOMEM;
goto end;
}
ipactx->mspac->last_update = now;
ipactx->mspac->flat_domain_name = flat_domain_name;
ipactx->mspac->flat_server_name = flat_server_name;
ipactx->mspac->domsid = domsid;
ipactx->mspac->fallback_group = fallback_group;
ipactx->mspac->fallback_rid = fallback_rid;
trust_kerr = ipadb_mspac_get_trusted_domains(ipactx);
if (trust_kerr)
in_stmsg = "Failed to assemble trusted domains information";
end:
if (stmsg)
*stmsg = in_stmsg;
if (resstr) free(resstr);
ldap_msgfree(result);
return kerr;
if (err) {
if (flat_domain_name) free(flat_domain_name);
if (flat_server_name) free(flat_server_name);
if (fallback_group) free(fallback_group);
}
return err ? (krb5_error_code)err : trust_kerr;
}
krb5_error_code ipadb_check_transited_realms(krb5_context kcontext,
@@ -3148,11 +3193,11 @@ krb5_error_code ipadb_check_transited_realms(krb5_context kcontext,
{
struct ipadb_context *ipactx;
bool has_transited_contents, has_client_realm, has_server_realm;
int i;
size_t i;
krb5_error_code ret;
ipactx = ipadb_get_context(kcontext);
if (!ipactx || !ipactx->mspac) {
if (!ipactx) {
return KRB5_KDB_DBNOTINITED;
}
@@ -3214,7 +3259,7 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
char **trusted_realm)
{
struct ipadb_context *ipactx;
int i, j, length;
size_t i, j, length;
const char *name;
bool result = false;
@@ -3301,3 +3346,90 @@ krb5_error_code ipadb_is_princ_from_trusted_realm(krb5_context kcontext,
return KRB5_KDB_NOENTRY;
}
static krb5_error_code
check_for_pac(krb5_context kcontext, krb5_authdata **authdata, bool *pac_present)
{
krb5_error_code kerr = ENOENT;
size_t i, j;
krb5_authdata **ifrel = NULL;
for (i = 0; authdata && authdata[i]; ++i) {
if (authdata[i]->ad_type != KRB5_AUTHDATA_IF_RELEVANT) {
continue;
}
kerr = krb5_decode_authdata_container(kcontext,
KRB5_AUTHDATA_IF_RELEVANT,
authdata[i], &ifrel);
if (kerr) {
goto end;
}
for (j = 0; ifrel[j]; ++j) {
if (ifrel[j]->ad_type == KRB5_AUTHDATA_WIN2K_PAC) {
break;
}
}
if (ifrel[j]) {
break;
}
krb5_free_authdata(kcontext, ifrel);
ifrel = NULL;
}
*pac_present = ifrel;
kerr = 0;
end:
krb5_free_authdata(kcontext, ifrel);
return kerr;
}
krb5_error_code
ipadb_enforce_pac(krb5_context kcontext, const krb5_ticket *ticket,
const char **status)
{
struct ipadb_context *ipactx;
bool pac_present;
krb5_error_code kerr;
/* Filter TGTs only */
if (!ipadb_is_tgs_princ(kcontext, ticket->server)) {
kerr = 0;
goto end;
}
/* Get IPA context */
ipactx = ipadb_get_context(kcontext);
if (!ipactx) {
kerr = KRB5_KDB_DBNOTINITED;
goto end;
}
/* If local TGT but PAC generator not initialized, skip PAC enforcement */
if (krb5_realm_compare(kcontext, ipactx->local_tgs, ticket->server) &&
!ipactx->mspac)
{
krb5_klog_syslog(LOG_WARNING, "MS-PAC not available. This makes "
"FreeIPA vulnerable to privilege escalation exploit "
"(CVE-2025-7493). Please generate SIDs to enable PAC "
"support.");
kerr = 0;
goto end;
}
/* Search for the PAC, fail if it cannot be found */
kerr = check_for_pac(kcontext, ticket->enc_part2->authorization_data,
&pac_present);
if (kerr) {
*status = "PAC_ENFORCEMENT_CANNOT_DECODE_TGT_AUTHDATA";
} else if (!pac_present) {
kerr = ENOENT;
*status = "PAC_ENFORCEMENT_TGT_WITHOUT_PAC";
}
end:
return kerr;
}
+1 -1
View File
@@ -31,7 +31,7 @@ struct ipadb_mspac {
char *fallback_group;
uint32_t fallback_rid;
int num_trusts;
size_t num_trusts;
struct ipadb_adtrusts *trusts;
time_t last_update;
};
+4 -1
View File
@@ -233,6 +233,7 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
krb5_db_entry *client_entry = NULL;
krb5_boolean is_equal;
bool force_reinit_mspac = false;
const char *stmsg = NULL;
is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
@@ -309,7 +310,9 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
force_reinit_mspac = true;
}
(void)ipadb_reinit_mspac(ipactx, force_reinit_mspac);
kerr = ipadb_reinit_mspac(ipactx, force_reinit_mspac, &stmsg);
if (kerr && stmsg)
krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg);
kerr = ipadb_get_pac(context, flags, client, server, NULL, authtime, &pac);
if (kerr != 0 && kerr != ENOENT) {
+12 -4
View File
@@ -46,6 +46,7 @@ ipadb_v9_issue_pac(krb5_context context, unsigned int flags,
bool with_pad;
krb5_error_code kerr = 0;
bool is_as_req = flags & CLIENT_REFERRALS_FLAGS;
const char *stmsg = NULL;
if (is_as_req) {
get_authz_data_types(context, client, &with_pac, &with_pad);
@@ -110,12 +111,19 @@ ipadb_v9_issue_pac(krb5_context context, unsigned int flags,
force_reinit_mspac = TRUE;
}
}
(void)ipadb_reinit_mspac(ipactx, force_reinit_mspac);
/* MS-PAC needs proper configuration and if it is missing, we simply skip issuing one */
if (ipactx->mspac->flat_server_name == NULL) {
/* MS-PAC generator has to be initalized */
kerr = ipadb_reinit_mspac(ipactx, force_reinit_mspac, &stmsg);
if (kerr && stmsg)
krb5_klog_syslog(LOG_ERR, "MS-PAC generator: %s", stmsg);
/* Continue even if initilization of PAC generator failed.
* It may caused by the trust objects part only. */
/* At least the core part of the PAC generator is required. */
if (!ipactx->mspac)
return KRB5_PLUGIN_OP_NOTSUPP;
}
kerr = ipadb_get_pac(context, flags,
client, server, replaced_reply_key,
authtime, &new_pac);
+310 -74
View File
@@ -188,25 +188,6 @@ done:
return ret;
}
static bool
is_tgs_princ(krb5_context kcontext, krb5_const_principal princ)
{
krb5_data *primary;
size_t l_tgs_name;
if (2 != krb5_princ_size(kcontext, princ))
return false;
primary = krb5_princ_component(kcontext, princ, 0);
l_tgs_name = strlen(KRB5_TGS_NAME);
if (l_tgs_name != primary->length)
return false;
return 0 == memcmp(primary->data, KRB5_TGS_NAME, l_tgs_name);
}
static krb5_error_code
cmp_local_tgs_princ(krb5_context kcontext, const char *local_realm,
krb5_const_principal princ, bool *result)
@@ -765,9 +746,12 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
"krbTicketFlags", &result);
if (ret == 0) {
entry->attributes = result;
} else {
*polmask |= TKTFLAGS_BIT;
}
/* Since principal, global policy, and virtual ticket flags are combined,
* they must always be resolved, except if we are in IPA setup mode (because
* ticket policies and virtual ticket flags are irrelevant in this case). */
if (!ipactx->override_restrictions)
*polmask |= TKTFLAGS_BIT;
ret = ipadb_ldap_attr_to_int(lcontext, lentry,
"krbMaxTicketLife", &result);
@@ -971,7 +955,12 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
goto done;
}
if (ret == 0) {
ied->ipa_user = true;
if (1 == krb5_princ_size(kcontext, entry->princ)) {
/* A principal must be a POSIX account AND have only one element to
* be considered a user (this is to filter out CIFS principals). */
ied->ipa_user = true;
}
ret = ipadb_ldap_attr_to_str(lcontext, lentry,
"uid", &uidstring);
if (ret != 0 && ret != ENOENT) {
@@ -1339,23 +1328,150 @@ done:
return ret;
}
static krb5_flags maybe_require_preauth(struct ipadb_context *ipactx,
krb5_db_entry *entry)
static krb5_error_code
are_final_tktflags(struct ipadb_context *ipactx, krb5_db_entry *entry,
bool *final_tktflags)
{
const struct ipadb_global_config *config;
krb5_error_code kerr;
struct ipadb_e_data *ied;
char *str = NULL;
bool in_final_tktflags = false;
config = ipadb_get_global_config(ipactx);
if (config && config->disable_preauth_for_spns) {
ied = (struct ipadb_e_data *)entry->e_data;
if (ied && ied->ipa_user != true) {
/* not a user, assume SPN */
return 0;
}
kerr = ipadb_get_edata(entry, &ied);
if (kerr)
goto end;
if (!ied->ipa_user) {
kerr = 0;
goto end;
}
/* By default require preauth for all principals */
return KRB5_KDB_REQUIRES_PRE_AUTH;
kerr = krb5_dbe_get_string(ipactx->kcontext, entry,
IPA_KDB_STRATTR_FINAL_USER_TKTFLAGS, &str);
if (kerr)
goto end;
in_final_tktflags = str && ipa_krb5_parse_bool(str);
end:
if (final_tktflags)
*final_tktflags = in_final_tktflags;
krb5_dbe_free_string(ipactx->kcontext, str);
return kerr;
}
static krb5_error_code
add_virtual_static_tktflags(struct ipadb_context *ipactx, krb5_db_entry *entry,
krb5_flags *tktflags)
{
krb5_error_code kerr;
krb5_flags vsflg;
bool final_tktflags;
const struct ipadb_global_config *gcfg;
struct ipadb_e_data *ied;
vsflg = IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_MANDATORY;
kerr = ipadb_get_edata(entry, &ied);
if (kerr)
goto end;
kerr = are_final_tktflags(ipactx, entry, &final_tktflags);
if (kerr)
goto end;
/* In practice, principal ticket flags cannot be final for SPNs. */
if (!final_tktflags)
vsflg |= ied->ipa_user ? IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_DEFAULTS_USER
: IPA_KDB_TKTFLAGS_VIRTUAL_STATIC_DEFAULTS_SPN;
if (!ied->ipa_user) {
gcfg = ipadb_get_global_config(ipactx);
if (gcfg && gcfg->disable_preauth_for_spns)
vsflg &= ~KRB5_KDB_REQUIRES_PRE_AUTH;
}
if (tktflags)
*tktflags |= vsflg;
end:
return kerr;
}
static krb5_error_code
get_virtual_static_tktflags_mask(struct ipadb_context *ipactx,
krb5_db_entry *entry, krb5_flags *mask)
{
krb5_error_code kerr;
krb5_flags flags = IPA_KDB_TKTFLAGS_VIRTUAL_MANAGED_ALL;
kerr = add_virtual_static_tktflags(ipactx, entry, &flags);
if (kerr)
goto end;
if (mask)
*mask = ~flags;
kerr = 0;
end:
return kerr;
}
/* Add ticket flags from the global ticket policy if it exists, otherwise
* succeed. If the global ticket policy is set, the "exists" parameter is set to
* true. */
static krb5_error_code
add_global_ticket_policy_flags(struct ipadb_context *ipactx,
bool *gtpol_exists, krb5_flags *tktflags)
{
krb5_error_code kerr;
char *policy_dn;
char *tktflags_attr[] = { "krbticketflags", NULL };
LDAPMessage *res = NULL, *first;
int ec, ldap_tktflags;
bool in_gtpol_exists = false;
ec = asprintf(&policy_dn, "cn=%s,cn=kerberos,%s", ipactx->realm,
ipactx->base);
if (-1 == ec) {
kerr = ENOMEM;
goto end;
}
kerr = ipadb_simple_search(ipactx, policy_dn, LDAP_SCOPE_BASE,
"(objectclass=krbticketpolicyaux)",
tktflags_attr, &res);
if (kerr) {
if (KRB5_KDB_NOENTRY == kerr)
kerr = 0;
goto end;
}
first = ldap_first_entry(ipactx->lcontext, res);
if (!first) {
kerr = 0;
goto end;
}
in_gtpol_exists = true;
ec = ipadb_ldap_attr_to_int(ipactx->lcontext, first, "krbticketflags",
&ldap_tktflags);
if (0 == ec && tktflags) {
*tktflags |= (krb5_flags)ldap_tktflags;
}
kerr = 0;
end:
if (gtpol_exists)
*gtpol_exists = in_gtpol_exists;
ldap_msgfree(res);
free(policy_dn);
return kerr;
}
static krb5_error_code ipadb_fetch_tktpolicy(krb5_context kcontext,
@@ -1368,6 +1484,7 @@ static krb5_error_code ipadb_fetch_tktpolicy(krb5_context kcontext,
char *policy_dn = NULL;
LDAPMessage *res = NULL;
LDAPMessage *first;
bool final_tktflags, has_local_tktpolicy = true;
int result;
int ret;
@@ -1376,12 +1493,18 @@ static krb5_error_code ipadb_fetch_tktpolicy(krb5_context kcontext,
return KRB5_KDB_DBNOTINITED;
}
kerr = are_final_tktflags(ipactx, entry, &final_tktflags);
if (kerr)
goto done;
ret = ipadb_ldap_attr_to_str(ipactx->lcontext, lentry,
"krbticketpolicyreference", &policy_dn);
switch (ret) {
case 0:
break;
case ENOENT:
/* If no principal ticket policy, fallback to the global one. */
has_local_tktpolicy = false;
ret = asprintf(&policy_dn, "cn=%s,cn=kerberos,%s",
ipactx->realm, ipactx->base);
if (ret == -1) {
@@ -1425,12 +1548,13 @@ static krb5_error_code ipadb_fetch_tktpolicy(krb5_context kcontext,
}
}
if (polmask & TKTFLAGS_BIT) {
ret = ipadb_ldap_attr_to_int(ipactx->lcontext, first,
"krbticketflags", &result);
if (ret == 0) {
entry->attributes |= result;
} else {
entry->attributes |= maybe_require_preauth(ipactx, entry);
/* If global ticket policy is being applied, set flags only if
* user principal ticket flags are not final. */
if (has_local_tktpolicy || !final_tktflags) {
ret = ipadb_ldap_attr_to_int(ipactx->lcontext, first,
"krbticketflags", &result);
if (ret == 0)
entry->attributes |= result;
}
}
@@ -1454,13 +1578,27 @@ static krb5_error_code ipadb_fetch_tktpolicy(krb5_context kcontext,
if (polmask & MAXRENEWABLEAGE_BIT) {
entry->max_renewable_life = 604800;
}
if (polmask & TKTFLAGS_BIT) {
entry->attributes |= maybe_require_preauth(ipactx, entry);
}
kerr = 0;
}
if (polmask & TKTFLAGS_BIT) {
/* If the principal ticket flags were applied, then flags from the
* global ticket policy has to be applied atop of them if user principal
* ticket flags are not final. */
if (has_local_tktpolicy && !final_tktflags) {
kerr = add_global_ticket_policy_flags(ipactx, NULL,
&entry->attributes);
if (kerr)
goto done;
}
/* Virtual static ticket flags are set regardless of database content */
kerr = add_virtual_static_tktflags(ipactx, entry, &entry->attributes);
if (kerr)
goto done;
}
done:
ldap_msgfree(res);
free(policy_dn);
@@ -1598,6 +1736,7 @@ static krb5_error_code dbget_alias(krb5_context kcontext,
-1,
};
size_t i = 0;
const char *stmsg = NULL;
/* For TGS-REQ server principal lookup, KDC asks with KRB5_KDB_FLAG_REFERRAL_OK
* and client usually asks for an KRB5_NT_PRINCIPAL type principal. */
@@ -1685,8 +1824,11 @@ static krb5_error_code dbget_alias(krb5_context kcontext,
if (kerr == KRB5_KDB_NOENTRY) {
/* If no trusted realm found, refresh trusted domain data and try again
* because it might be a freshly added trust to AD */
kerr = ipadb_reinit_mspac(ipactx, false);
kerr = ipadb_reinit_mspac(ipactx, false, &stmsg);
if (kerr != 0) {
if (stmsg)
krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s",
stmsg);
kerr = KRB5_KDB_NOENTRY;
goto done;
}
@@ -1825,7 +1967,7 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
return kerr;
/* If TGS principal, some virtual attributes may be added */
if (is_tgs_princ(kcontext, (*entry)->princ)) {
if (ipadb_is_tgs_princ(kcontext, (*entry)->princ)) {
kerr = cmp_local_tgs_princ(kcontext, ipactx->realm, (*entry)->princ,
&is_local_tgs_princ);
if (kerr)
@@ -1839,6 +1981,9 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
kerr = krb5_dbe_set_string(kcontext, *entry,
KRB5_KDB_SK_PAC_PRIVSVR_ENCTYPE,
"aes256-sha1");
if (kerr)
return kerr;
}
/* We should have been initialized at this point already */
@@ -1902,6 +2047,7 @@ void ipadb_free_principal(krb5_context kcontext, krb5_db_entry *entry)
for (i = 0; (acl_list != NULL) && (acl_list[i] != NULL); i++) {
free(acl_list[i]);
}
free(acl_list);
}
free(prev->tl_data_contents);
free(prev);
@@ -2041,6 +2187,36 @@ static void ipadb_mods_free_tip(struct ipadb_mods *imods)
imods->tip--;
}
/* Use LDAP REPLACE operation to remove an attribute.
* Contrary to the DELETE operation, it will not fail if the attribute does not
* exist. */
static krb5_error_code
ipadb_ldap_replace_remove(struct ipadb_mods *imods, char *attribute)
{
krb5_error_code kerr;
LDAPMod *m = NULL;
kerr = ipadb_mods_new(imods, &m);
if (kerr)
return kerr;
m->mod_op = LDAP_MOD_REPLACE;
m->mod_type = strdup(attribute);
if (!m->mod_type) {
kerr = ENOMEM;
goto end;
}
m->mod_values = NULL;
kerr = 0;
end:
if (kerr)
ipadb_mods_free_tip(imods);
return kerr;
}
static krb5_error_code ipadb_get_ldap_mod_str(struct ipadb_mods *imods,
char *attribute, char *value,
int mod_op)
@@ -2457,6 +2633,93 @@ static krb5_error_code ipadb_get_ldap_mod_auth_ind(krb5_context kcontext,
return ret;
}
static krb5_error_code
update_tktflags(krb5_context kcontext, struct ipadb_mods *imods,
krb5_db_entry *entry, int mod_op)
{
krb5_error_code kerr;
struct ipadb_context *ipactx;
struct ipadb_e_data *ied;
bool final_tktflags;
krb5_flags tktflags_mask;
int tktflags;
ipactx = ipadb_get_context(kcontext);
if (!ipactx) {
kerr = KRB5_KDB_DBNOTINITED;
goto end;
}
if (ipactx->override_restrictions) {
/* In IPA setup mode, IPA edata might not be available. In this mode,
* ticket flags are written as they are provided. */
tktflags = (int)entry->attributes;
} else {
kerr = ipadb_get_edata(entry, &ied);
if (kerr)
goto end;
kerr = get_virtual_static_tktflags_mask(ipactx, entry, &tktflags_mask);
if (kerr)
goto end;
kerr = are_final_tktflags(ipactx, entry, &final_tktflags);
if (kerr)
goto end;
/* Flags from the global ticket policy are filtered out only if the user
* principal flags are not final. */
if (!final_tktflags) {
krb5_flags gbl_tktflags = 0;
kerr = add_global_ticket_policy_flags(ipactx, NULL, &gbl_tktflags);
if (kerr)
goto end;
tktflags_mask &= ~gbl_tktflags;
}
tktflags = (int)(entry->attributes & tktflags_mask);
if (LDAP_MOD_REPLACE == mod_op && ied && !ied->has_tktpolaux) {
if (0 == tktflags) {
/* No point initializing principal ticket policy if there are no
* flags left after filtering out virtual and global ticket
* policy ones. */
kerr = 0;
goto end;
}
/* if the object does not have the krbTicketPolicyAux class
* we need to add it or this will fail, only for modifications.
* We always add this objectclass by default when doing an add
* from scratch. */
kerr = ipadb_get_ldap_mod_str(imods, "objectclass",
"krbTicketPolicyAux", LDAP_MOD_ADD);
if (kerr)
goto end;
}
}
if (tktflags != 0) {
kerr = ipadb_get_ldap_mod_int(imods, "krbTicketFlags", tktflags,
mod_op);
if (kerr)
goto end;
} else if (LDAP_MOD_REPLACE == mod_op) {
/* If the principal is not being created, and there are no custom ticket
* flags to be set, remove the "krbTicketFlags" attribute. */
kerr = ipadb_ldap_replace_remove(imods, "krbTicketFlags");
if (kerr)
goto end;
}
kerr = 0;
end:
return kerr;
}
static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext,
struct ipadb_mods *imods,
krb5_db_entry *entry,
@@ -2532,36 +2795,9 @@ static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext,
/* KADM5_ATTRIBUTES */
if (entry->mask & KMASK_ATTRIBUTES) {
/* if the object does not have the krbTicketPolicyAux class
* we need to add it or this will fail, only for modifications.
* We always add this objectclass by default when doing an add
* from scratch. */
if ((mod_op == LDAP_MOD_REPLACE) && entry->e_data) {
struct ipadb_e_data *ied;
ied = (struct ipadb_e_data *)entry->e_data;
if (ied->magic != IPA_E_DATA_MAGIC) {
kerr = EINVAL;
goto done;
}
if (!ied->has_tktpolaux) {
kerr = ipadb_get_ldap_mod_str(imods, "objectclass",
"krbTicketPolicyAux",
LDAP_MOD_ADD);
if (kerr) {
goto done;
}
}
}
kerr = ipadb_get_ldap_mod_int(imods,
"krbTicketFlags",
(int)entry->attributes,
mod_op);
if (kerr) {
kerr = update_tktflags(kcontext, imods, entry, mod_op);
if (kerr)
goto done;
}
}
/* KADM5_MAX_LIFE */
+6
View File
@@ -79,6 +79,7 @@ static void on_bind_readable(verto_ctx *vctx, verto_ev *ev)
struct otpd_queue_item *item = NULL;
int i, rslt;
(void)vctx;
int kerr = 0;
rslt = ldap_result(verto_get_private(ev), LDAP_RES_ANY, 0, NULL, &results);
if (rslt != LDAP_RES_BIND) {
@@ -118,6 +119,7 @@ static void on_bind_readable(verto_ctx *vctx, verto_ev *ev)
krad_code_name2num("Access-Accept"),
NULL, item->req, &item->rsp);
if (i != 0) {
kerr = 1;
errstr = krb5_get_error_message(ctx.kctx, i);
goto error;
}
@@ -127,6 +129,10 @@ error:
otpd_log_req(item->req, "bind end: %s",
item->rsp != NULL ? "success" : errstr);
if (kerr) {
krb5_free_error_message(ctx.kctx, errstr);
}
ldap_msgfree(results);
otpd_queue_push(&ctx.stdio.responses, item);
verto_set_flags(ctx.stdio.writer, VERTO_EV_FLAG_PERSIST |
+13 -7
View File
@@ -43,10 +43,14 @@ static void forward_cb(krb5_error_code retval, const krad_packet *request,
NULL, item->req, &item->rsp);
}
otpd_log_req(item->req, "forward end: %s",
retval == 0
? krad_code_num2name(code)
: krb5_get_error_message(ctx.kctx, retval));
if (retval == 0) {
otpd_log_req(item->req, "forward end: %s", krad_code_num2name(code));
} else {
const char *err_msg = krb5_get_error_message(ctx.kctx, retval);
otpd_log_req(item->req, "forward end: %s",
krb5_get_error_message(ctx.kctx, retval));
krb5_free_error_message(ctx.kctx, err_msg);
}
otpd_queue_push(&ctx.stdio.responses, item);
verto_set_flags(ctx.stdio.writer, VERTO_EV_FLAG_PERSIST |
@@ -117,8 +121,10 @@ krb5_error_code otpd_forward(struct otpd_queue_item **item)
*item = NULL;
error:
if (retval != 0)
otpd_log_req((*item)->req, "forward end: %s",
krb5_get_error_message(ctx.kctx, retval));
if (retval != 0) {
const char *err_msg = krb5_get_error_message(ctx.kctx, retval);
otpd_log_req((*item)->req, "forward end: %s", err_msg);
krb5_free_error_message(ctx.kctx, err_msg);
}
return retval;
}
+14 -10
View File
@@ -31,6 +31,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/random.h>
#include <sys/uio.h>
#include "internal.h"
@@ -93,6 +94,7 @@ static void oauth2_on_child_writable(verto_ctx *vctx, verto_ev *ev)
(void)vctx; /* Unused */
ssize_t io;
struct child_ctx *child_ctx;
struct iovec iov[3];
child_ctx = verto_get_private(ev);
if (child_ctx == NULL) {
@@ -102,15 +104,18 @@ static void oauth2_on_child_writable(verto_ctx *vctx, verto_ev *ev)
}
if (child_ctx->oauth2_state == OAUTH2_GET_DEVICE_CODE) {
/* no input needed */
verto_del(ev);
return;
io = write(verto_get_fd(ev), child_ctx->item->idp.ipaidpClientSecret,
strlen(child_ctx->item->idp.ipaidpClientSecret));
} else {
iov[0].iov_base = child_ctx->item->idp.ipaidpClientSecret;
iov[0].iov_len = strlen(child_ctx->item->idp.ipaidpClientSecret);
iov[1].iov_base = "\n";
iov[1].iov_len = 1;
iov[2].iov_base = child_ctx->saved_item->oauth2.device_code_reply;
iov[2].iov_len = strlen(child_ctx->saved_item->oauth2.device_code_reply);
io = writev(verto_get_fd(ev), iov, 3);
}
io = write(verto_get_fd(ev),
child_ctx->saved_item->oauth2.device_code_reply,
strlen(child_ctx->saved_item->oauth2.device_code_reply));
otpd_queue_item_free(child_ctx->saved_item);
if (io < 0) {
@@ -429,8 +434,7 @@ int oauth2(struct otpd_queue_item **item, enum oauth2_state oauth2_state)
args[args_idx++] = (*item)->idp.ipaidpClientID;
if ((*item)->idp.ipaidpClientSecret) {
args[args_idx++] = "--client-secret";
args[args_idx++] = (*item)->idp.ipaidpClientSecret;
args[args_idx++] = "--client-secret-stdin";
}
if ((*item)->idp.ipaidpScope) {
+7 -6
View File
@@ -2165,17 +2165,17 @@ static bool handle_cross_realm_princs(struct ipasam_private *ipasam_state,
princ_l = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
remote_realm, ipasam_state->realm);
princ_l_tdo = talloc_asprintf(tmp_ctx, "%s$@%s",
l_tdo_alias = talloc_asprintf(tmp_ctx, "%s$@%s",
flat_name, ipasam_state->realm);
l_tdo_alias = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
princ_l_tdo = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
flat_name, ipasam_state->realm);
princ_r = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
ipasam_state->realm, remote_realm);
princ_r_tdo = talloc_asprintf(tmp_ctx, "%s$@%s",
r_tdo_alias = talloc_asprintf(tmp_ctx, "%s$@%s",
ipasam_state->flat_name, remote_realm);
r_tdo_alias = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
princ_r_tdo = talloc_asprintf(tmp_ctx, "krbtgt/%s@%s",
ipasam_state->flat_name, remote_realm);
if (trusted_dn == NULL || princ_l == NULL || princ_l_tdo == NULL ||
@@ -2212,7 +2212,7 @@ static bool handle_cross_realm_princs(struct ipasam_private *ipasam_state,
* only used to retrieve trusted domain credentials by
* AD Trust Agents across the IPA topology */
failed += !set_krb_princ(ipasam_state, tmp_ctx,
r_tdo_alias, princ_r_tdo,
princ_r_tdo, r_tdo_alias,
pwd_incoming, trusted_dn,
(KRB_PRINC_CREATE_DISABLED |
KRB_PRINC_CREATE_AGENT_PERMISSION));
@@ -2232,8 +2232,9 @@ static bool handle_cross_realm_princs(struct ipasam_private *ipasam_state,
pwd_outgoing, trusted_dn,
KRB_PRINC_CREATE_DEFAULT);
/* Second: <REMOTE FLAT NAME>$@<OUR REALM>, enabled by default
/* Second: <krbtgt/REMOTE FLAT NAME>@<OUR REALM>, enabled by default
* as it is used for a remote DC to authenticate against IPA Samba
* Uses <REMOTE FLAT NAME$>@<OUR REALM> as an alias.
*
* A local account for the outbound trust must have
* POSIX and SMB identities associated with our domain but we associate
+5 -1
View File
@@ -30,7 +30,7 @@
* Program may make changes or additions to the list of Approved
* Interfaces.
*
* Copyright (C) 2010 Red Hat, Inc.
* Copyright (C) 2010-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -67,6 +67,10 @@
"[file %s, line %d]: " fmt, \
__FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_PWDPOLICY(fmt, ...) \
slapi_log_error(SLAPI_LOG_PWDPOLICY, log_func, fmt, ##__VA_ARGS__)
/* "Trace" logging is very expensive and should be avoided/replaced. TBD */
#define LOG_TRACE(fmt, ...) \
slapi_log_error(SLAPI_LOG_TRACE, log_func, fmt, ##__VA_ARGS__)
@@ -30,7 +30,7 @@
* Program may make changes or additions to the list of Approved
* Interfaces.
*
* Copyright (C) 2005 Red Hat, Inc.
* Copyright (C) 2005-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -132,7 +132,8 @@ ipa_join(Slapi_PBlock *pb)
Slapi_DN *sdn;
Slapi_Backend *be;
Slapi_Entry **es = NULL;
int rc=0, ret=0, res, i;
int rc=0, ret=0, res;
size_t i;
int is_root=0;
char *krbLastPwdChange = NULL;
char *fqdn = NULL;
@@ -204,7 +205,7 @@ ipa_join(Slapi_PBlock *pb)
/* if there is none or more than one, freak out */
if (i != 1) {
LOG_TRACE("Too many entries, or entry no found (%d)", i);
LOG_TRACE("Too many entries, or entry no found (%lu)\n", i);
if (i == 0)
errMesg = "Host not found.\n";
else
@@ -217,7 +218,7 @@ ipa_join(Slapi_PBlock *pb)
/* Is this host already enrolled? */
krbLastPwdChange = slapi_entry_attr_get_charptr(targetEntry, "krbLastPwdChange");
if (NULL != krbLastPwdChange) {
LOG_TRACE("Host already enrolled");
LOG_TRACE("Host already enrolled\n");
errMesg = "Host already enrolled.\n";
rc = LDAP_OPERATIONS_ERROR;
goto free_and_return;
@@ -313,8 +314,8 @@ done:
ret = slapi_pblock_set(pb, SLAPI_EXT_OP_RET_OID, JOIN_OID);
if (!ret) ret = slapi_pblock_set(pb, SLAPI_EXT_OP_RET_VALUE, &retbval);
if (ret) {
errMesg = "Could not set return values";
LOG("%s\n", errMesg);
errMesg = "Could not set return values\n";
LOG("%s", errMesg);
rc = SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
}
@@ -30,7 +30,7 @@
* Program may make changes or additions to the list of Approved
* Interfaces.
*
* Copyright (C) 2022 Red Hat, Inc.
* Copyright (C) 2022-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -447,7 +447,7 @@ static int ipagraceperiod_preop(Slapi_PBlock *pb)
LOG_TRACE("grace limit disabled, skipping\n");
goto done;
} else if (grace_limit < -1) {
LOG_FATAL("Invalid passwordGraceLimit value %d\n", grace_limit);
LOG_FATAL("Invalid passwordGraceLimit value %ld\n", grace_limit);
return LDAP_OPERATIONS_ERROR;
}
@@ -480,7 +480,7 @@ static int ipagraceperiod_preop(Slapi_PBlock *pb)
slapi_pwpolicy_make_response_control(pb, -1, grace_limit - grace_user_time , -1);
}
} else if (grace_user_time >= grace_limit) {
LOG_TRACE("%s password is expired and out of grace limit\n", dn);
LOG_PWDPOLICY("%s password is expired and out of grace limit\n", dn);
errstr = "Password is expired.\n";
ret = LDAP_INVALID_CREDENTIALS;
@@ -30,7 +30,7 @@
* Program may make changes or additions to the list of Approved
* Interfaces.
*
* Copyright (C) 2010 Red Hat, Inc.
* Copyright (C) 2010-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -823,13 +823,15 @@ static int ipalockout_preop(Slapi_PBlock *pb)
if (failedcount >= max_fail) {
if (lockout_duration == 0) {
errstr = "Entry permanently locked.\n";
LOG_PWDPOLICY("Entry '%s' is permanently locked.\n", dn);
ret = LDAP_UNWILLING_TO_PERFORM;
goto done;
}
if (time_now < last_failed + lockout_duration) {
/* Too many failures */
LOG_TRACE("Too many failed logins. %lu out of %d\n", failedcount, max_fail);
LOG_PWDPOLICY("Too many failed logins for '%s'. %lu out of %d\n",
dn, failedcount, max_fail);
errstr = "Too many failed logins.\n";
ret = LDAP_UNWILLING_TO_PERFORM;
}
@@ -30,7 +30,7 @@
* Program may make changes or additions to the list of Approved
* Interfaces.
*
* Copyright (C) 2010 Red Hat, Inc.
* Copyright (C) 2010-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -350,7 +350,6 @@ ipamodrdn_load_plugin_config(void)
{
int status = EOK;
int result;
int i;
Slapi_PBlock *search_pb;
Slapi_Entry **entries = NULL;
@@ -379,7 +378,7 @@ ipamodrdn_load_plugin_config(void)
goto cleanup;
}
for (i = 0; (entries[i] != NULL); i++) {
for (size_t i = 0; (entries[i] != NULL); i++) {
/* We don't care about the status here because we may have
* some invalid config entries, but we just want to continue
* looking for valid ones. */
@@ -680,7 +679,8 @@ ipamodrdn_change_attr(struct configEntry *cfgentry,
slapi_modify_internal_pb(mod_pb);
slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &ret);
if (ret != LDAP_SUCCESS) {
LOG_FATAL("Failed to change attribute with error %d\n", ret);
LOG_FATAL("Failed to change attribute '%s' in '%s' with error %d\n",
cfgentry->tattr, targetdn, ret);
ret = EFAIL;
}
ret = EOK;
@@ -33,7 +33,7 @@
* Authors:
* Nathaniel McCallum <npmccallum@redhat.com>
*
* Copyright (C) 2014 Red Hat, Inc.
* Copyright (C) 2014-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -295,14 +295,16 @@ preop_mod(Slapi_PBlock *pb)
}
if (!simulate(mods, attr, cpre, &cpost) && repl == 0) {
msg = slapi_ch_smprintf("Invalid operation sequence on %s", attr);
msg = slapi_ch_smprintf("Invalid operation sequence on %s (%s)",
attr, slapi_entry_get_dn_const(epre));
goto error;
}
if (cpost < cpre) {
if (repl == 0) {
msg = slapi_ch_smprintf("Will not %s %s",
cpost == COUNTER_UNSET ? "delete" : "decrement", attr);
msg = slapi_ch_smprintf("Will not %s %s (%s)",
cpost == COUNTER_UNSET ? "delete" : "decrement",
attr, slapi_entry_get_dn_const(epre));
goto error;
}
@@ -321,6 +323,9 @@ preop_mod(Slapi_PBlock *pb)
error:
rc = LDAP_UNWILLING_TO_PERFORM;
if (msg) {
LOG("%s - error %d\n", msg, rc);
}
slapi_send_ldap_result(pb, rc, NULL, msg, 0, NULL);
if (slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc)) {
LOG_FATAL("slapi_pblock_set failed!\n");
@@ -33,7 +33,7 @@
* Authors:
* Nathaniel McCallum <npmccallum@redhat.com>
*
* Copyright (C) 2014 Red Hat, Inc.
* Copyright (C) 2014-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -41,6 +41,8 @@
#include <slapi-plugin.h>
#define IPA_PLUGIN_NAME "ipa-otp-counter"
long long
ldapmod_get_value(const LDAPMod *mod, long long def);
@@ -33,7 +33,7 @@
* Authors:
* Nathaniel McCallum <npmccallum@redhat.com>
*
* Copyright (C) 2013 Red Hat, Inc.
* Copyright (C) 2013-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -46,7 +46,7 @@
#include "util.h"
#define PLUGIN_NAME "ipa-otp-lasttoken"
#define IPA_PLUGIN_NAME "ipa-otp-lasttoken"
#define OTP_CONTAINER "cn=otp,%s"
static struct otp_config *otp_config;
@@ -191,9 +191,14 @@ static inline int send_error(Slapi_PBlock *pb, int rc, const char *errstr)
static int preop_del(Slapi_PBlock *pb)
{
char *dn = NULL;
if (is_allowed(pb, NULL))
return 0;
slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn);
LOG("Can't delete last active token (%s)", dn);
return send_error(pb, LDAP_UNWILLING_TO_PERFORM,
"Can't delete last active token");
}
@@ -221,10 +226,12 @@ static int preop_mod(Slapi_PBlock *pb)
return 0;
/* If a protected attribute is modified, deny. */
for (int i = 0; mods != NULL && mods[i] != NULL; i++) {
for (int j = 0; errors[j].attr != NULL; j++) {
if (strcasecmp(mods[i]->mod_type, errors[j].attr) == 0)
for (size_t i = 0; mods != NULL && mods[i] != NULL; i++) {
for (size_t j = 0; errors[j].attr != NULL; j++) {
if (strcasecmp(mods[i]->mod_type, errors[j].attr) == 0) {
LOG("%s (%s)", errors[j].msg, slapi_entry_get_dn_const(entry));
return send_error(pb, LDAP_UNWILLING_TO_PERFORM, errors[j].msg);
}
}
}
@@ -284,7 +291,7 @@ static int ipa_otp_lasttoken_start(Slapi_PBlock *pb)
int ipa_otp_lasttoken_init(Slapi_PBlock *pb)
{
static const Slapi_PluginDesc preop_desc = {
PLUGIN_NAME,
IPA_PLUGIN_NAME,
"FreeIPA",
"FreeIPA/1.0",
"Protect the user's last active token"
@@ -297,14 +304,14 @@ int ipa_otp_lasttoken_init(Slapi_PBlock *pb)
ret |= slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01);
ret |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *) &preop_desc);
ret |= slapi_register_plugin("betxnpreoperation", 1, __func__, preop_init,
PLUGIN_NAME " betxnpreoperation", NULL,
IPA_PLUGIN_NAME " betxnpreoperation", NULL,
ipa_otp_lasttoken_plugin_id);
ret |= slapi_register_plugin("postoperation", 1, __func__, postop_init,
PLUGIN_NAME " postoperation", NULL,
IPA_PLUGIN_NAME " postoperation", NULL,
ipa_otp_lasttoken_plugin_id);
ret |= slapi_register_plugin("internalpostoperation", 1, __func__,
intpostop_init,
PLUGIN_NAME " internalpostoperation", NULL,
IPA_PLUGIN_NAME " internalpostoperation", NULL,
ipa_otp_lasttoken_plugin_id);
ret |= slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
(void *)ipa_otp_lasttoken_start);
@@ -33,7 +33,7 @@
* Authors:
* Simo Sorce <ssorce@redhat.com>
*
* Copyright (C) 2007-2010 Red Hat, Inc.
* Copyright (C) 2007-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -81,7 +81,9 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
char **encsalts;
char **tmparray;
char *tmpstr;
int i, ret;
int ret;
size_t i;
bool fips_enabled = false;
config = calloc(1, sizeof(struct ipapwd_krbcfg));
if (!config) {
@@ -240,28 +242,35 @@ static struct ipapwd_krbcfg *ipapwd_getConfig(void)
config->allow_nt_hash = false;
if (ipapwd_fips_enabled()) {
LOG("FIPS mode is enabled, NT hashes are not allowed.\n");
fips_enabled = true;
}
sdn = slapi_sdn_new_dn_byval(ipa_etc_config_dn);
ret = ipapwd_getEntry(sdn, &config_entry, NULL);
slapi_sdn_free(&sdn);
if (ret != LDAP_SUCCESS) {
LOG_FATAL("No config Entry?\n");
goto free_and_error;
} else {
sdn = slapi_sdn_new_dn_byval(ipa_etc_config_dn);
ret = ipapwd_getEntry(sdn, &config_entry, NULL);
slapi_sdn_free(&sdn);
if (ret != LDAP_SUCCESS) {
LOG_FATAL("No config Entry?\n");
goto free_and_error;
} else {
tmparray = slapi_entry_attr_get_charray(config_entry,
"ipaConfigString");
for (i = 0; tmparray && tmparray[i]; i++) {
tmparray = slapi_entry_attr_get_charray(config_entry,
"ipaConfigString");
for (i = 0; tmparray && tmparray[i]; i++) {
if (strcasecmp(tmparray[i], "EnforceLDAPOTP") == 0) {
config->enforce_ldap_otp = true;
continue;
}
if (!fips_enabled) {
if (strcasecmp(tmparray[i], "AllowNThash") == 0) {
config->allow_nt_hash = true;
continue;
}
}
if (tmparray) slapi_ch_array_free(tmparray);
}
slapi_entry_free(config_entry);
if (tmparray) slapi_ch_array_free(tmparray);
}
slapi_entry_free(config_entry);
return config;
free_and_error:
@@ -327,7 +336,8 @@ int ipapwd_getPolicy(const char *dn,
"ipaPwdUserCheck", NULL};
Slapi_Entry **es = NULL;
Slapi_Entry *pe = NULL;
int ret, res, scope, i;
int ret, res, scope;
size_t i;
int buffer_flags=0;
Slapi_ValueSet* results = NULL;
char *actual_type_name = NULL;
@@ -545,7 +555,7 @@ int ipapwd_gen_checks(Slapi_PBlock *pb, char **errMesg,
}
sdn = slapi_sdn_new_dn_byref(dn);
if (!sdn) {
LOG_FATAL("Unable to convert dn to sdn %s", dn ? dn : "<NULL>");
LOG_FATAL("Unable to convert dn to sdn %s\n", dn ? dn : "<NULL>");
*errMesg = "Internal Error";
rc = LDAP_OPERATIONS_ERROR;
goto done;
@@ -564,11 +574,18 @@ int ipapwd_gen_checks(Slapi_PBlock *pb, char **errMesg,
/* get the kerberos context and master key */
*config = ipapwd_getConfig();
if (NULL == *config) {
LOG_FATAL("Error Retrieving Master Key");
LOG_FATAL("Error Retrieving Master Key\n");
*errMesg = "Fatal Internal Error";
rc = LDAP_OPERATIONS_ERROR;
}
/* do not return the master key if asked */
if (check_flags & IPAPWD_CHECK_ONLY_CONFIG) {
free((*config)->kmkey->contents);
free((*config)->kmkey);
(*config)->kmkey = NULL;
}
done:
return rc;
}
@@ -594,7 +611,7 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
/* Find the entry with the password policy */
ret = ipapwd_getPolicy(data->dn, data->target, &pol);
if (ret) {
LOG_TRACE("No password policy, use defaults");
LOG_TRACE("No password policy, use defaults\n");
}
break;
case IPA_CHANGETYPE_ADMIN:
@@ -620,14 +637,14 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
*/
ret = ipapwd_getPolicy(data->dn, data->target, &tmppol);
if (ret) {
LOG_TRACE("No password policy, use defaults");
LOG_TRACE("No password policy, use defaults\n");
} else {
pol.max_pwd_life = tmppol.max_pwd_life;
pol.history_length = tmppol.history_length;
}
break;
default:
LOG_TRACE("Unknown password change type, use defaults");
LOG_TRACE("Unknown password change type, use defaults\n");
break;
}
@@ -860,7 +877,7 @@ int ipapwd_SetPassword(struct ipapwd_krbcfg *krbcfg,
case IPA_CHANGETYPE_DSMGR:
case IPA_CHANGETYPE_ADMIN:
/* Mark as administratively reset which will unlock acct */
ret = ipapwd_setdate(data->target, smods,
ret = ipapwd_setdate(data->target, smods,
"krbLastAdminUnlock",
data->timeNow, false);
if (ret != LDAP_SUCCESS)
@@ -951,7 +968,7 @@ Slapi_Value **ipapwd_setPasswordHistory(Slapi_Mods *smods,
char **new_pwd_history = NULL;
int n = 0;
int ret;
int i;
size_t i;
pwd_history = slapi_entry_attr_get_charray(data->target,
"passwordHistory");
@@ -1083,10 +1100,9 @@ int ipapwd_set_extradata(const char *dn,
void ipapwd_free_slapi_value_array(Slapi_Value ***svals)
{
Slapi_Value **sv = *svals;
int i;
if (sv) {
for (i = 0; sv[i]; i++) {
for (size_t i = 0; sv[i]; i++) {
slapi_value_free(&sv[i]);
}
}
@@ -1102,8 +1118,10 @@ void free_ipapwd_krbcfg(struct ipapwd_krbcfg **cfg)
krb5_free_default_realm(c->krbctx, c->realm);
krb5_free_context(c->krbctx);
free(c->kmkey->contents);
free(c->kmkey);
if (c->kmkey) {
free(c->kmkey->contents);
free(c->kmkey);
}
free(c->supp_encsalts);
free(c->pref_encsalts);
slapi_ch_array_free(c->passsync_mgrs);
@@ -33,7 +33,7 @@
* Authors:
* Simo Sorce <ssorce@redhat.com>
*
* Copyright (C) 2007-2010 Red Hat, Inc.
* Copyright (C) 2007-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -231,7 +231,7 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
if (!*svals) {
/* errMesg should have been set in encrypt_encode_key() */
LOG_FATAL("key encryption/encoding failed\n");
LOG_FATAL("key encryption/encoding failed (%s)\n", *errMesg);
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
@@ -267,6 +267,7 @@ int ipapwd_gen_hashes(struct ipapwd_krbcfg *krbcfg,
}
(*ntvals)[0] = slapi_value_new();
if (slapi_value_set((*ntvals)[0], nt_key, 16) == NULL) {
LOG("Failed to set value for nt_key");
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
@@ -33,7 +33,7 @@
* Authors:
* Simo Sorce <ssorce@redhat.com>
*
* Copyright (C) 2007-2010 Red Hat, Inc.
* Copyright (C) 2007-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -108,7 +108,7 @@ static void filter_keys(struct ipapwd_krbcfg *krbcfg,
struct ipapwd_keyset *kset,
bool allow_nthash)
{
int i, j;
size_t i, j;
for (i = 0; i < kset->num_keys; i++) {
for (j = 0; j < krbcfg->num_supp_encsalts; j++) {
@@ -151,11 +151,11 @@ static void filter_enctypes(struct ipapwd_krbcfg *krbcfg,
bool allow_nthash)
{
/* first filter for duplicates */
for (int i = 0; i + 1 < *num_kenctypes; i++) {
for (int j = i + 1; j < *num_kenctypes; j++) {
for (size_t i = 0; i + 1 < *num_kenctypes; i++) {
for (size_t j = i + 1; j < *num_kenctypes; j++) {
if (kenctypes[i].ks_enctype == kenctypes[j].ks_enctype) {
/* duplicate, filter out */
for (int k = j; k + 1 < *num_kenctypes; k++) {
for (size_t k = j; k + 1 < *num_kenctypes; k++) {
kenctypes[k].ks_enctype = kenctypes[k + 1].ks_enctype;
kenctypes[k].ks_salttype = kenctypes[k + 1].ks_salttype;
}
@@ -166,8 +166,8 @@ static void filter_enctypes(struct ipapwd_krbcfg *krbcfg,
}
/* then filter for supported */
for (int i = 0; i < *num_kenctypes; i++) {
int j;
for (size_t i = 0; i < *num_kenctypes; i++) {
size_t j;
/* Check if supported */
for (j = 0; j < krbcfg->num_supp_encsalts; j++) {
@@ -184,7 +184,7 @@ static void filter_enctypes(struct ipapwd_krbcfg *krbcfg,
}
if (j == krbcfg->num_supp_encsalts) {
/* Unsupported, filter out */
for (int k = i; k + 1 < *num_kenctypes; k++) {
for (size_t k = i; k + 1 < *num_kenctypes; k++) {
kenctypes[k].ks_enctype = kenctypes[k + 1].ks_enctype;
kenctypes[k].ks_salttype = kenctypes[k + 1].ks_salttype;
}
@@ -344,6 +344,8 @@ parse_req_done:
rc = ipapwd_check_max_pwd_len(strlen(newPasswd), &errMesg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
bindDN, errMesg);
goto free_and_return;
}
@@ -456,7 +458,7 @@ parse_req_done:
char *cur_pw;
if (oldPasswd == NULL || *oldPasswd == '\0') {
LOG_FATAL("Old password was not provided!\n");
LOG_FATAL("Old password was not provided for '%s'!\n", dn);
rc = LDAP_INVALID_CREDENTIALS;
goto free_and_return;
}
@@ -466,7 +468,7 @@ parse_req_done:
cur_pw = slapi_entry_attr_get_charptr(targetEntry,
"userPassword");
if (!cur_pw) {
LOG_FATAL("User has no current password?\n");
LOG_FATAL("User '%s' does not have a current password?\n", dn);
rc = LDAP_UNWILLING_TO_PERFORM;
goto free_and_return;
}
@@ -485,7 +487,7 @@ parse_req_done:
slapi_value_free(&pw);
if (ret != 0) {
LOG_TRACE("Invalid password!\n");
LOG_TRACE("Invalid password for '%s'!\n", dn);
rc = LDAP_INVALID_CREDENTIALS;
goto free_and_return;
}
@@ -579,11 +581,9 @@ parse_req_done:
/* special cases */
if ((strcasecmp(dn, bindDN) != 0) &&
(strcasecmp(ipa_changepw_principal_dn, bindDN) != 0)) {
int i;
pwdata.changetype = IPA_CHANGETYPE_ADMIN;
for (i = 0; i < krbcfg->num_passsync_mgrs; i++) {
for (size_t i = 0; i < krbcfg->num_passsync_mgrs; i++) {
if (strcasecmp(krbcfg->passsync_mgrs[i], bindDN) == 0) {
pwdata.changetype = IPA_CHANGETYPE_DSMGR;
break;
@@ -606,6 +606,8 @@ parse_req_done:
errMesg = ipapwd_error2string(ret);
ret = ipapwd_to_ldap_pwpolicy_error(ret);
slapi_pwpolicy_make_response_control(pb, -1, -1, ret);
LOG_PWDPOLICY("Failed to set password credentials for"
" '%s': %s\n", dn, errMesg);
rc = LDAP_CONSTRAINT_VIOLATION;
goto free_and_return;
}
@@ -666,7 +668,7 @@ free_and_return:
if (targetEntry) slapi_entry_free(targetEntry);
if (ber) ber_free(ber, 1);
LOG("%s", errMesg ? errMesg : "success");
LOG("%s\n", errMesg ? errMesg : "success");
slapi_send_ldap_result(pb, rc, NULL, errMesg, 0, NULL);
return SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
@@ -732,7 +734,8 @@ static Slapi_Entry *get_entry_by_principal(const char *principal)
"krbCanonicalName",
"enrolledBy", NULL };
Slapi_Entry **es = NULL;
int res, ret, i;
int res, ret;
size_t i;
Slapi_Entry *entry = NULL;
/* Find ancestor base DN */
@@ -774,7 +777,7 @@ static Slapi_Entry *get_entry_by_principal(const char *principal)
/* if there is none or more than one, freak out */
if (i != 1) {
LOG_TRACE("Too many entries, or entry no found (%d)", i);
LOG_TRACE("Too many entries, or entry no found (%ld)\n", i);
goto free_and_return;
}
entry = slapi_entry_dup(es[0]);
@@ -809,7 +812,7 @@ static bool is_allowed_to_access_attr(Slapi_PBlock *pb, char *bindDN,
*/
be = get_realm_backend();
if (!be) {
LOG_FATAL("Could not fetch REALM backend!");
LOG_FATAL("Could not fetch REALM backend!\n");
return false;
}
if (slapi_pblock_set(pb, SLAPI_BACKEND, be)) {
@@ -868,7 +871,8 @@ static void remove_user_password(Slapi_Mods *smods,
if ((NULL != pw) && (NULL == krbLastPwdChange)) {
slapi_mods_add_mod_values(smods, LDAP_MOD_DELETE,
"userPassword", NULL);
LOG_TRACE("Removing userPassword from host entry\n");
LOG_TRACE("Removing userPassword from host entry '%s'\n",
slapi_entry_get_dn_const(targetEntry));
}
}
if (krbLastPwdChange) slapi_ch_free_string(&krbLastPwdChange);
@@ -891,8 +895,9 @@ static int store_new_keys(Slapi_Entry *target, char *svcname, char *bind_dn,
rc = set_krbLastPwdChange(smods, time_now);
if (rc) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to set krbLastPwdChange");
err_msg = "Internal error while storing keytab data\n";
LOG_FATAL("Failed to set krbLastPwdChange for target '%s'\n",
slapi_entry_get_dn_const(target));
err_msg = "Internal error while storing keytab data";
goto done;
}
@@ -905,8 +910,9 @@ static int store_new_keys(Slapi_Entry *target, char *svcname, char *bind_dn,
rc = ipapwd_apply_mods(slapi_entry_get_dn_const(target), smods);
if (rc != LDAP_SUCCESS) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to apply mods");
err_msg = "Internal error while saving keys\n";
LOG_FATAL("Failed to apply mods to target '%s'\n",
slapi_entry_get_dn_const(target));
err_msg = "Internal error while saving keys";
goto done;
}
@@ -914,8 +920,9 @@ static int store_new_keys(Slapi_Entry *target, char *svcname, char *bind_dn,
svcname, time_now);
if (rc != LDAP_SUCCESS) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to set extradata");
err_msg = "Internal error while saving keytab extradata\n";
LOG_FATAL("Failed to set extradata for target '%s'\n",
slapi_entry_get_dn_const(target));
err_msg = "Internal error while saving keytab extradata";
goto done;
}
@@ -1003,7 +1010,7 @@ static int decode_setkeytab_request(krb5_context krbctx,
kset->mkvno = mkvno;
rtag = ber_peek_tag(ber, &tlen);
for (int i = 0; rtag == LBER_SEQUENCE; i++) {
for (size_t i = 0; rtag == LBER_SEQUENCE; i++) {
krb5_key_data *newset;
ber_tag_t ctag;
ber_int_t type;
@@ -1181,29 +1188,29 @@ static int encode_setkeytab_reply(struct ipapwd_keyset *kset,
rc = ber_printf(ber, "{i{", (ber_int_t)kset->keys[0].key_data_kvno);
if (rc == -1) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to ber_printf the kvno");
LOG_FATAL("Failed to ber_printf the kvno\n");
goto done;
}
for (int i = 0; i < kset->num_keys; i++) {
for (size_t i = 0; i < kset->num_keys; i++) {
rc = ber_printf(ber, "{i}", (ber_int_t)kset->keys[i].key_data_type[0]);
if (rc == -1) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to ber_printf the enctype");
LOG_FATAL("Failed to ber_printf the enctype\n");
goto done;
}
}
rc = ber_printf(ber, "}}");
if (rc == -1) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to ber_printf the termination");
LOG_FATAL("Failed to ber_printf the termination\n");
goto done;
}
rc = ber_flatten(ber, &bvp);
if (rc == -1) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("Failed to ber_flatten the buffer");
LOG_FATAL("Failed to ber_flatten the buffer\n");
goto done;
}
@@ -1306,7 +1313,7 @@ static int ipapwd_setkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
/* get next kvno for entry (will be 1 if this is new) and fix keyset */
kvno = ipapwd_get_cur_kvno(targetEntry) + 1;
for (int i = 0; i < kset->num_keys; i++) {
for (size_t i = 0; i < kset->num_keys; i++) {
kset->keys[i].key_data_kvno = kvno;
}
@@ -1352,7 +1359,7 @@ static int ipapwd_setkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
rc = encode_setkeytab_reply(kset, &bvp);
if (rc) {
errMesg = "Internal Error.\n";
errMesg = "Internal Error.";
goto free_and_return;
}
@@ -1372,7 +1379,7 @@ free_and_return:
if (targetEntry) slapi_entry_free(targetEntry);
if (svals) {
for (int i = 0; svals[i]; i++) {
for (size_t i = 0; svals[i]; i++) {
slapi_value_free(&svals[i]);
}
free(svals);
@@ -1382,7 +1389,7 @@ free_and_return:
if (rc == LDAP_SUCCESS)
errMesg = NULL;
LOG("%s", errMesg ? errMesg : "success");
LOG("%s\n", errMesg ? errMesg : "success");
slapi_send_ldap_result(pb, rc, NULL, errMesg, 0, NULL);
return SLAPI_PLUGIN_EXTENDED_SENT_RESULT;
@@ -1403,7 +1410,6 @@ static int decode_getkeytab_request(struct berval *extop, bool *wantold,
krb5_key_salt_tuple *enctypes = NULL;
bool newkt;
bool ret;
int i;
ret = ipaasn1_dec_getkt(extop->bv_val, extop->bv_len, &newkt,
&svcname, &password, &etypes, &numtypes);
@@ -1423,7 +1429,7 @@ static int decode_getkeytab_request(struct berval *extop, bool *wantold,
goto done;
}
for (i = 0; i < numtypes; i++) {
for (size_t i = 0; i < numtypes; i++) {
enctypes[i].ks_enctype = etypes[i];
enctypes[i].ks_salttype = KRB5_KDB_SALTTYPE_NORMAL;
}
@@ -1466,7 +1472,7 @@ static int encode_getkeytab_reply(krb5_context krbctx,
/* uses last key kvno */
kvno = keys[num_keys-1].key_data_kvno;
for (int i = 0; i < num_keys; i++) {
for (size_t i = 0; i < num_keys; i++) {
krb5_enc_data cipher = { 0 };
krb5_data plain = { 0 };
krb5_int16 plen;
@@ -1516,7 +1522,7 @@ static int encode_getkeytab_reply(krb5_context krbctx,
rc = LDAP_SUCCESS;
done:
for (int i = 0; i < ksc.nkeys; i ++) {
for (size_t i = 0; i < ksc.nkeys; i++) {
free(ksc.ksdata[i].key.contents);
}
if (rc != LDAP_SUCCESS) {
@@ -1632,7 +1638,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
* this operation. */
if (bind_dn == NULL || *bind_dn == '\0') {
/* Refuse the operation because they're bound anonymously */
err_msg = "Anonymous Binds are not allowed.\n";
err_msg = "Anonymous Binds are not allowed.";
rc = LDAP_INSUFFICIENT_ACCESS;
goto free_and_return;
}
@@ -1648,7 +1654,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
slapi_pblock_get(pb, SLAPI_EXT_OP_REQ_VALUE, &extop_value);
if (!extop_value) {
LOG_FATAL("Failed to retrieve extended op value from pblock\n");
err_msg = "Failed to retrieve extended operation value\n";
err_msg = "Failed to retrieve extended operation value";
rc = LDAP_OPERATIONS_ERROR;
goto free_and_return;
}
@@ -1674,7 +1680,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
/* get Entry by krbPrincipalName */
target_entry = get_entry_by_principal(service_name);
if (!target_entry) {
err_msg = "PrincipalName not found.\n";
err_msg = "PrincipalName not found.";
rc = LDAP_NO_SUCH_OBJECT;
goto free_and_return;
}
@@ -1690,7 +1696,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
if (!acl_ok) {
LOG_FATAL("Not allowed to retrieve keytab on [%s] as user [%s]!\n",
service_name, bind_dn);
err_msg = "Insufficient access rights\n";
err_msg = "Insufficient access rights";
rc = LDAP_INSUFFICIENT_ACCESS;
goto free_and_return;
}
@@ -1701,6 +1707,8 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
/* if password was passed-in, check its length */
rc = ipapwd_check_max_pwd_len(strlen(password), &err_msg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
bind_dn, err_msg);
goto free_and_return;
}
}
@@ -1712,7 +1720,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
if (!acl_ok) {
LOG_FATAL("Not allowed to set keytab on [%s]!\n",
service_name);
err_msg = "Insufficient access rights\n";
err_msg = "Insufficient access rights";
rc = LDAP_INSUFFICIENT_ACCESS;
goto free_and_return;
}
@@ -1745,7 +1753,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
if (!svals) {
rc = LDAP_OPERATIONS_ERROR;
LOG_FATAL("encrypt_encode_keys failed!\n");
err_msg = "Internal error while encrypting keys\n";
err_msg = "Internal error while encrypting keys";
goto free_and_return;
}
@@ -1765,7 +1773,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
rc = encode_getkeytab_reply(krbctx, krbcfg->kmkey, mkvno,
keys, num_keys, &bvp);
if (rc != LDAP_SUCCESS) {
err_msg = "Internal Error.\n";
err_msg = "Internal Error.";
goto free_and_return;
}
@@ -1776,7 +1784,7 @@ static int ipapwd_getkeytab(Slapi_PBlock *pb, struct ipapwd_krbcfg *krbcfg)
free_and_return:
if (rc == LDAP_SUCCESS) err_msg = NULL;
LOG("%s", err_msg ? err_msg : "success");
LOG("%s\n", err_msg ? err_msg : "success");
slapi_send_ldap_result(pb, rc, NULL, err_msg, 0, NULL);
/* Free anything that we allocated above */
@@ -1787,7 +1795,7 @@ free_and_return:
if (target_entry) slapi_entry_free(target_entry);
if (keys) ipa_krb5_free_key_data(keys, num_keys);
if (svals) {
for (int i = 0; svals[i]; i++) {
for (size_t i = 0; svals[i]; i++) {
slapi_value_free(&svals[i]);
}
free(svals);
@@ -2031,7 +2039,7 @@ int ipapwd_init( Slapi_PBlock *pb )
"ipapwd_post_init_betxn", ipapwd_post_init_betxn,
"IPA pwd post ops betxn", NULL,
ipapwd_plugin_id);
}
}
slapi_register_plugin("preoperation", 1,
"ipapwd_pre_init", ipapwd_pre_init,
@@ -70,6 +70,7 @@
#define IPAPWD_CHECK_CONN_SECURE 0x00000001
#define IPAPWD_CHECK_DN 0x00000002
#define IPAPWD_CHECK_ONLY_CONFIG 0x00000004
#define IPA_CHANGETYPE_NORMAL 0
#define IPA_CHANGETYPE_ADMIN 1
@@ -109,6 +110,7 @@ struct ipapwd_krbcfg {
char **passsync_mgrs;
int num_passsync_mgrs;
bool allow_nt_hash;
bool enforce_ldap_otp;
};
int ipapwd_entry_checks(Slapi_PBlock *pb, struct slapi_entry *e,
@@ -33,7 +33,7 @@
* Authors:
* Simo Sorce <ssorce@redhat.com>
*
* Copyright (C) 2007-2010 Red Hat, Inc.
* Copyright (C) 2007-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -248,6 +248,13 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
return 0;
}
/* Get target DN */
ret = slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
if (ret) {
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
/* Ok this is interesting,
* Check this is a clear text password, or refuse operation */
if ('{' == userpw[0]) {
@@ -280,6 +287,8 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
} else {
rc = ipapwd_check_max_pwd_len(strlen(userpw_clear), &errMesg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
slapi_sdn_get_dn(sdn), errMesg);
goto done;
}
userpw = slapi_ch_strdup(userpw_clear);
@@ -329,13 +338,6 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
goto done;
}
/* Get target DN */
ret = slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
if (ret) {
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
/* time to get the operation handler */
ret = slapi_pblock_get(pb, SLAPI_OPERATION, &op);
if (ret != 0) {
@@ -359,7 +361,6 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR;
} else {
char *binddn;
int i;
pwdop->pwdata.changetype = IPA_CHANGETYPE_ADMIN;
@@ -367,7 +368,7 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
slapi_pblock_get(pb, SLAPI_CONN_DN, &binddn);
/* if it is a passsync manager we also need to skip resets */
for (i = 0; i < krbcfg->num_passsync_mgrs; i++) {
for (size_t i = 0; i < krbcfg->num_passsync_mgrs; i++) {
if (strcasecmp(krbcfg->passsync_mgrs[i], binddn) == 0) {
pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR;
break;
@@ -385,6 +386,8 @@ static int ipapwd_pre_add(Slapi_PBlock *pb)
if ((pwdop->pwdata.changetype != IPA_CHANGETYPE_DSMGR) &&
(ret != 0) ) {
errMesg = ipapwd_error2string(ret);
LOG_PWDPOLICY("Failed to add password credentials for '%s': %s\n",
slapi_sdn_get_dn(sdn), errMesg);
rc = LDAP_CONSTRAINT_VIOLATION;
goto done;
}
@@ -507,6 +510,13 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
goto done;
}
/* Get target DN */
ret = slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
if (ret) {
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
/* grab the mods - we'll put them back later with
* our modifications appended
*/
@@ -568,6 +578,8 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
rc = ipapwd_check_max_pwd_len(bv->bv_len, &errMesg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
slapi_sdn_get_dn(sdn), errMesg);
goto done;
}
slapi_ch_free_string(&unhashedpw);
@@ -591,14 +603,6 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
/* OK we have something interesting here, start checking for
* pre-requisites */
/* Get target DN */
ret = slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
if (ret) {
rc = LDAP_OPERATIONS_ERROR;
goto done;
}
tmp_sdn = slapi_sdn_dup(sdn);
if (tmp_sdn) {
/* xxxPAR: Ideally SLAPI_MODIFY_EXISTING_ENTRY should be
@@ -795,6 +799,8 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
const char *userpw_clear = &userpw[strlen("{CLEAR}")];
rc = ipapwd_check_max_pwd_len(strlen(userpw_clear), &errMesg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
slapi_sdn_get_dn(sdn), errMesg);
goto done;
}
unhashedpw = slapi_ch_strdup(userpw_clear);
@@ -806,9 +812,8 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
slapi_ch_free_string(&userpw);
} else if (slapi_is_encoded(userpw)) {
LOG("Pre-Encoded passwords are not valid\n");
errMesg = "Pre-Encoded passwords are not valid\n";
errMesg = "Pre-Encoded passwords are not valid";
LOG("%s (%s)\n", errMesg, slapi_sdn_get_dn(sdn));
rc = LDAP_CONSTRAINT_VIOLATION;
goto done;
}
@@ -843,7 +848,6 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
} else {
char *binddn;
Slapi_DN *bdn, *tdn;
int i;
/* Check Bind DN */
slapi_pblock_get(pb, SLAPI_CONN_DN, &binddn);
@@ -857,18 +861,16 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
pwdop->pwdata.changetype = IPA_CHANGETYPE_ADMIN;
/* if it is a passsync manager we also need to skip resets */
for (i = 0; i < krbcfg->num_passsync_mgrs; i++) {
for (size_t i = 0; i < krbcfg->num_passsync_mgrs; i++) {
if (strcasecmp(krbcfg->passsync_mgrs[i], binddn) == 0) {
pwdop->pwdata.changetype = IPA_CHANGETYPE_DSMGR;
break;
}
}
}
slapi_sdn_free(&bdn);
slapi_sdn_free(&tdn);
}
pwdop->pwdata.dn = slapi_ch_strdup(slapi_sdn_get_dn(sdn));
@@ -884,6 +886,8 @@ static int ipapwd_pre_mod(Slapi_PBlock *pb)
if ((pwdop->pwdata.changetype != IPA_CHANGETYPE_DSMGR) &&
(ret != 0)) {
errMesg = ipapwd_error2string(ret);
LOG_PWDPOLICY("Check Password Policy failed for (%s) - %s/n",
pwdop->pwdata.dn, errMesg);
rc = LDAP_CONSTRAINT_VIOLATION;
goto done;
}
@@ -976,7 +980,6 @@ static int ipapwd_regen_nthash(Slapi_PBlock *pb, Slapi_Mods *smods,
int num_keys;
int mkvno;
int ret;
int i;
ret = slapi_entry_attr_find(entry, "ipaNTHash", &attr);
if (ret == 0) {
@@ -1008,7 +1011,7 @@ static int ipapwd_regen_nthash(Slapi_PBlock *pb, Slapi_Mods *smods,
ret = LDAP_UNWILLING_TO_PERFORM;
for (i = 0; i < num_keys; i++) {
for (size_t i = 0; i < num_keys; i++) {
char nthash[16];
krb5_enc_data cipher;
krb5_data plain;
@@ -1209,13 +1212,20 @@ done:
* value at the end. This leaves only the password in creds for later
* validation.
*/
typedef enum {
OTP_IS_NOT_REQUIRED = 0,
OTP_IS_REQUIRED_EXPLICITLY,
OTP_IS_REQUIRED_IMPLICITLY
} otp_req_enum;
static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
struct berval *creds, bool otpreq)
struct berval *creds, otp_req_enum otpreq,
bool *notokens)
{
uint32_t auth_types;
/* Get the configured authentication types. */
auth_types = otp_config_auth_types(otp_config, entry);
*notokens = false;
/*
* IMPORTANT SECTION!
@@ -1245,7 +1255,11 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
/* With no tokens, succeed if tokens aren't required. */
if (tokens[0] == NULL) {
otp_token_free_array(tokens);
return !otpreq;
*notokens = true;
if (otpreq != OTP_IS_NOT_REQUIRED)
/* DENY: OTP is required, either explicitly or implicitly */
return false;
return true;
}
if (otp_token_validate_berval(tokens, creds, NULL)) {
@@ -1256,7 +1270,8 @@ static bool ipapwd_pre_bind_otp(const char *bind_dn, Slapi_Entry *entry,
otp_token_free_array(tokens);
}
return (auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD) && !otpreq;
return (auth_types & OTP_CONFIG_AUTH_TYPE_PASSWORD) &&
(otpreq == OTP_IS_NOT_REQUIRED);
}
static int ipapwd_authenticate(const char *dn, Slapi_Entry *entry,
@@ -1411,6 +1426,11 @@ done:
}
#ifdef USE_OP_NOTE_MFA_AUTH
/* defined in ldap/servers/slapd/pblock.c in 389-ds but not exposed via slapi-plugin.h */
extern void slapi_pblock_set_flag_operation_notes(Slapi_PBlock *pb, uint32_t opflag);
#endif
/* PRE BIND Operation
*
* Used for:
@@ -1428,6 +1448,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
"krbPasswordExpiration", "krblastpwchange",
NULL
};
struct ipapwd_krbcfg *krbcfg = NULL;
struct berval *credentials = NULL;
Slapi_Entry *entry = NULL;
Slapi_DN *target_sdn = NULL;
@@ -1443,6 +1464,7 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
struct tm expire_tm;
int rc = LDAP_INVALID_CREDENTIALS;
char *errMesg = NULL;
bool notokens = false;
/* get BIND parameters */
ret |= slapi_pblock_get(pb, SLAPI_BIND_TARGET_SDN, &target_sdn);
@@ -1501,9 +1523,28 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
/* Try to do OTP first. */
syncreq = otpctrl_present(pb, OTP_SYNC_REQUEST_OID);
otpreq = otpctrl_present(pb, OTP_REQUIRED_OID);
if (!syncreq && !ipapwd_pre_bind_otp(dn, entry, credentials, otpreq))
goto invalid_creds;
otpreq = otpctrl_present(pb, OTP_REQUIRED_OID) ?
OTP_IS_REQUIRED_EXPLICITLY : OTP_IS_NOT_REQUIRED;
if (!syncreq && (otpreq == OTP_IS_NOT_REQUIRED)) {
ret = ipapwd_gen_checks(pb, &errMesg, &krbcfg, IPAPWD_CHECK_ONLY_CONFIG);
if (ret != 0) {
LOG_FATAL("ipapwd_gen_checks failed!?\n");
slapi_entry_free(entry);
slapi_sdn_free(&sdn);
return 0;
}
if (krbcfg->enforce_ldap_otp) {
otpreq = OTP_IS_REQUIRED_IMPLICITLY;
}
}
if (!syncreq && !ipapwd_pre_bind_otp(dn, entry,
credentials, otpreq, &notokens)) {
/* We got here because ipapwd_pre_bind_otp() returned false,
* it means that either token verification failed or
* a rule for empty tokens failed current policy. */
if (!(notokens || (otpreq == OTP_IS_NOT_REQUIRED)))
goto invalid_creds;
}
/* Ensure that there is a password. */
if (credentials->bv_len == 0) {
@@ -1511,6 +1552,8 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
} else {
rc = ipapwd_check_max_pwd_len(credentials->bv_len, &errMesg);
if (rc) {
LOG_PWDPOLICY("Failed to set password credentials for '%s': %s\n",
slapi_sdn_get_dn(sdn), errMesg);
goto invalid_creds;
}
}
@@ -1533,11 +1576,23 @@ static int ipapwd_pre_bind(Slapi_PBlock *pb)
/* Attempt to write out kerberos keys for the user. */
ipapwd_write_krb_keys(pb, discard_const(dn), entry, credentials);
#ifdef USE_OP_NOTE_MFA_AUTH
/* If it was a successful authentication with OTP required, mark it
* for access log to notice multi-factor authentication has happened
* https://www.port389.org/docs/389ds/design/mfa-operation-note-design.html
*/
if (!syncreq &&
((otpreq != OTP_IS_NOT_REQUIRED) && !notokens)) {
slapi_pblock_set_flag_operation_notes(pb, SLAPI_OP_NOTE_MFA_AUTH);
}
#endif
slapi_entry_free(entry);
slapi_sdn_free(&sdn);
return 0;
invalid_creds:
free_ipapwd_krbcfg(&krbcfg);
slapi_entry_free(entry);
slapi_sdn_free(&sdn);
slapi_send_ldap_result(pb, rc, NULL, errMesg, 0, NULL);
@@ -45,6 +45,8 @@
#define UID_NUMBER "uidnumber"
#define GID_NUMBER "gidnumber"
#define IPA_SID "ipantsecurityidentifier"
#define IPA_UNIQUEID "ipauniqueid"
#define IPA_UNIQUEID_AUTOGENERATE "autogenerate"
#define DOM_ATTRS_FILTER OBJECTCLASS"=ipantdomainattrs"
#define DOMAIN_ID_RANGE_FILTER OBJECTCLASS"=ipadomainidrange"
#define POSIX_ACCOUNT "posixaccount"
@@ -104,3 +106,6 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
const char *base_dn,
const char *dom_sid,
struct range_info **ranges);
int sidgen_task_init(Slapi_PBlock *pb);
int ipa_sidgen_init(Slapi_PBlock *pb);
@@ -454,6 +454,7 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
uint32_t id;
char *sid = NULL;
char **objectclasses = NULL;
char *uniqueid = NULL;
Slapi_PBlock *mod_pb = NULL;
Slapi_Mods *smods = NULL;
int result;
@@ -479,8 +480,18 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
goto done;
}
uniqueid = slapi_entry_attr_get_charptr(entry, IPA_UNIQUEID);
if (uniqueid != NULL &&
strncmp(IPA_UNIQUEID_AUTOGENERATE, uniqueid,
sizeof(IPA_UNIQUEID_AUTOGENERATE)) == 0) {
LOG("Staged entry [%s] does not have Posix IDs, nothing to do.\n",
dn_str);
ret = 0;
goto done;
}
if (uid_number >= UINT32_MAX || gid_number >= UINT32_MAX) {
LOG_FATAL("ID value too large.\n");
LOG_FATAL("ID value too large on entry [%s].\n", dn_str);
ret = LDAP_CONSTRAINT_VIOLATION;
goto done;
}
@@ -497,7 +508,7 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
&has_posix_group,
&has_ipa_id_object);
if (ret != 0) {
LOG_FATAL("Cannot determine objectclasses.\n");
LOG_FATAL("Cannot determine objectclasses on entry [%s].\n", dn_str);
goto done;
}
@@ -511,15 +522,16 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
id = (uid_number != 0) ? uid_number : gid_number;
objectclass_to_add = NULL;
} else {
LOG_FATAL("Inconsistent objectclasses and attributes, nothing to do.\n");
LOG_FATAL("Inconsistent objectclasses and attributes on entry "
"[%s], nothing to do.\n", dn_str);
ret = 0;
goto done;
}
ret = find_sid_for_id(id, plugin_id, base_dn, dom_sid, ranges, &sid);
if (ret != 0) {
LOG_FATAL("Cannot convert Posix ID [%lu] into an unused SID.\n",
(unsigned long) id);
LOG_FATAL("Cannot convert Posix ID [%lu] into an unused SID on "
"entry [%s].\n", (unsigned long) id, dn_str);
goto done;
}
@@ -554,6 +566,7 @@ int find_sid_for_ldap_entry(struct slapi_entry *entry,
}
done:
slapi_ch_free_string(&uniqueid);
slapi_ch_free_string(&sid);
slapi_pblock_destroy(mod_pb);
slapi_mods_free(&smods);
@@ -89,7 +89,7 @@ static void free_pblock(void *arg)
static int do_work(struct worker_ctx *worker_ctx)
{
Slapi_PBlock *pb;
int ret;
int ret, failures = 0;
size_t c;
char *filter = NULL;
char *attrs[] = { OBJECTCLASS, UID_NUMBER, GID_NUMBER, NULL };
@@ -151,8 +151,7 @@ static int do_work(struct worker_ctx *worker_ctx)
worker_ctx->base_dn, worker_ctx->dom_sid,
worker_ctx->ranges);
if (ret != 0) {
LOG_FATAL("Cannot add SID to existing entry.\n");
goto done;
failures++;
}
if (worker_ctx->delay != 0) {
@@ -162,6 +161,12 @@ static int do_work(struct worker_ctx *worker_ctx)
}
};
ret = failures;
if (ret > 0) {
LOG_FATAL("Finished with %d failures, please check the log.\n",
failures);
}
done:
slapi_ch_free_string(&filter);
pthread_cleanup_pop(1);
@@ -30,7 +30,7 @@
* Program may make changes or additions to the list of Approved
* Interfaces.
*
* Copyright (C) 2010 Red Hat, Inc.
* Copyright (C) 2010-2023 Red Hat, Inc.
* All rights reserved.
* END COPYRIGHT BLOCK **/
@@ -1185,7 +1185,7 @@ static int ipauuid_pre_op(Slapi_PBlock *pb, int modtype)
* enforce is enabled. */
errstr = slapi_ch_smprintf("Only the Directory Manager "
"can set arbitrary values "
"for %s\n", cfgentry->attr);
"for %s", cfgentry->attr);
ret = LDAP_INSUFFICIENT_ACCESS;
goto done;
}
@@ -1221,7 +1221,7 @@ done:
}
if (ret) {
LOG("operation failure [%d]\n", ret);
LOG("operation failure [%d] - %s\n", ret, errstr);
slapi_send_ldap_result(pb, ret, NULL, errstr, 0, NULL);
slapi_ch_free((void **)&errstr);
ret = EFAIL;
+1 -1
View File
@@ -5,7 +5,7 @@
# from the environment for the first two.
PYTHON ?= python3
VENVDIR = ./.venv
SPHINXOPTS ?= -W --keep-going -j auto
SPHINXOPTS ?= -W --keep-going -j 1
SPHINXBUILD ?= PATH=$(VENVDIR)/bin:$$PATH sphinx-build
SOURCEDIR = .
BUILDDIR = _build
+2 -2
View File
@@ -63,7 +63,7 @@ else:
This will connect to LDAP directly if we are running our script in server, or
use a RPC client if we are running it from a FreeIPA client.
After we have initialized the API and stablished a connection, we are ready to
After we have initialized the API and established a connection, we are ready to
issue commands.
## Running commands
@@ -278,4 +278,4 @@ for i in range(100):
'params' : [args, kw]
})
ret = api.Command.batch(*batch_args)
```
```
+1
View File
@@ -8,6 +8,7 @@ Make multiple ipa calls via one remote procedure call
|methods|:ref:`Dict<Dict>`|False
### Options
* keeponly : :ref:`Str<Str>`
* version : :ref:`Str<Str>`
### Output
+1 -1
View File
@@ -27,7 +27,7 @@ No arguments.
* ipauserobjectclasses : :ref:`Str<Str>`
* ipapwdexpadvnotify : :ref:`Int<Int>`
* ipaconfigstring : :ref:`StrEnum<StrEnum>`
* Values: ('AllowNThash', 'KDC:Disable Last Success', 'KDC:Disable Lockout', 'KDC:Disable Default Preauth for SPNs')
* Values: ('AllowNThash', 'KDC:Disable Last Success', 'KDC:Disable Lockout', 'KDC:Disable Default Preauth for SPNs', 'EnforceLDAPOTP')
* ipaselinuxusermaporder : :ref:`Str<Str>`
* ipaselinuxusermapdefault : :ref:`Str<Str>`
* ipakrbauthzdata : :ref:`StrEnum<StrEnum>`
+262
View File
@@ -0,0 +1,262 @@
# Audit IPA API operations
## Overview
IPA servers present an API to perform various actions that change the state of
the deployment. These actions include, among others, modifications of user and
group databases, add or remove information about hosts and Kerberos services,
HBAC and SUDO rules, and many other action types.
It is possible to observe IPA API actions through the web server logs. Each IPA
server logs their API calls in `/var/log/httpd/error_log` log file, as part of
standard Apache webserver logs. However, IPA command line utilities, when run
as `root` on IPA server, operate directly against LDAP database and results of
these operations only present in LDAP logs.
Thus, current IPA API implementation does not provide a unified method to
collect logs to audit API operations. The goal of this change is to make sure
IPA API backend logs externally-initiated operations, regardless how these
operations were invoked.
## Use Cases
- As an administrator, I'd like to collect details on who and when has called
a particular IPA API on a particular IPA server. This information needs to be
easily queried and it should be possible to correlate it across all servers
in the IPA deployment.
- As an administrator, I'd like to make sure operations performed as part of
IPA administrative utilities are audited as well.
## How to Use
`journalctl` tool can be used to query and filter through the IPA
API audit details. Each logged entry will be tagged with an 'IPA.API' label and
thus can easily be queried:
```
# journalctl -g IPA.API
...
```
`journalctl -g` allows to search through the content of the log entries'
messages. Each found entry has associated metadata which can be retrieved in a
different format, depending on other options to `journalctl` invocation.
## Design
Audit of IPA API operations should happen independently. Operations should be
logged whenever they happen.
IPA deployment heavily relies on a working systemd setup. systemd provides
logging facilities in the form of a system journal. systemd journal allows
centralized collection of the journals from individual systems, forward secure
sealing of the forwarded data, and rich metadata associated with the log
entries. Thus, it already provides an infrastructure to allow secure
centralized collection of actions performed through IPA API on IPA servers.
From administrator's point of view, when IPA API operations logged through the
systemd journal, standard journal commands can be used to retrieve and
manipulate logged entries.
## Implementation
All IPA API calls end up in `Command.__do_call()` internal method. This method
prepares execution of the command and runs it. After the command was performed,
the output is formatted. If operations require forwarding the request to a
remote IPA server, this will be performed automatically. As a result,
`Command.__do_call()` is executed by both IPA client and IPA server components.
It is possible to derive a context of operations through IPA API environment,
using `api.env.in_server` boolean.
systemd journal provides a simple Python binding, `systemd.journal`, that
allows structured logging of the messages against a `journald` daemon running
on the system. If such operation is performed in the server context, system
journal will be updated.
To aid with identification of these messages, an application name is replaced
with IPA.API and the actual name from api.env.script is made a part of the
logged message. The actual application script name is available as part of the
journal metadata anyway. Additionally, a `MESSAGE_ID` property is set to IPA
API-specific application UID, generated with Python's
`uuid.uuid3(uuid.NAMESPACE_DNS, 'IPA.API')` function call. This value is
available in IPA constants (`ipalib/constants.py`) as `SD_IPA_API_MESSAGE_ID`.
The value of the constant is `6d70f1b493df36478bc3499257cd3b17`.
If no Kerberos authentication was used but rather LDAPI autobind was in use,
the name of the authenticated principal will be replaced with `[autobind]`
text.
Messages sent with syslog `NOTICE` priority.
An example session looks like the following output:
```
# ipa -e in_server=True console
(Custom IPA interactive Python console)
api: IPA API object
pp: pretty printer
>>> api.Command.user_del('foobar')
{'result': {'failed': []}, 'value': ['foobar'], 'messages': [{'type':
'warning', 'name': 'VersionMissing', 'message': "API Version number was not
sent, forward compatibility not guaranteed. Assuming server's API version,
2.253", 'code': 13001, 'data': {'server_version': '2.253'}}], 'summary':
'Deleted user "foobar"'}
>>> ^D
now exiting InteractiveConsole...
# journalctl -g IPA.API
May 21 11:31:33 master1.ipa1.test /usr/bin/ipa[247422]: [IPA.API] [autobind]: user_del: SUCCESS [ldap2_140328582446688] {"uid": ["foobar"], "continue": false, "version": "2.253"}
```
All operations triggered through IPA API logged, including locally initiated,
as can be seen in the output above. For httpd end-point operations will be
logged as requested by the `/mod_wsgi` binary:
```
May 21 11:35:19 master1.ipa1.test /mod_wsgi[247035]: [IPA.API] admin@IPA1.TEST: ping: SUCCESS [ldap2_139910420944784] {"version": "2.253"}
```
The message includes following fields:
- executable name and PID (`/mod_wsgi` for HTTP end-point)
- `[IPA.API]` marker to allow searches with `journalctl -g IPA.API`
- authenticated Kerberos principal or `[autobind]` marker for LDAPI-based access as root
- name of the command executed
- result of execution: `SUCCESS` or an exception name
- LDAP backend instance identifier. The identifier will be the same for all operations performed under the same request. This allows to identify operations which were executed as a part of the same API request instance. For API operations that didn't result in LDAP access, there will be `[no_connection_id]` marker.
- finally, a list of arguments and options passed to the command is provided in JSON format
If an API call results in multiple operations triggered by the internal
implementation of the API command, only the external operation is recorded.
This means, for example, that a `user_del` API call will only be recorded as a
`user_del` command and not a sequence of a `user_find`, `otptoken_find`,
`subid_find`, and corresponding deletion commands which `user_del`
implementation is using.
IPA supplies a message catalog to systemd journal which allows to explain
content of the audited message and provide references to corresponding IPA API
documentation. This feature is triggered by `journalctl -x` systemd journal
command.
Full journal entry looks like the one below and can be obtained with `journalctl -o json-pretty` command:
```
{
"PRIORITY" : "5",
"_HOSTNAME" : "master1.ipa1.test",
"__SEQNUM" : "608971",
"_COMM" : "ipa",
"_AUDIT_LOGINUID" : "0",
"CODE_FUNC" : "__audit_to_journal",
"_TRANSPORT" : "journal",
"__SEQNUM_ID" : "aa96317d3ab84c16b5f131922414af11",
"_CAP_EFFECTIVE" : "1ffffffffff",
"_MACHINE_ID" : "5582ad1e90354a2e82710afb4cd4477f",
"_RUNTIME_SCOPE" : "system",
"MESSAGE" : "[IPA.API] [autobind]: user_del: SUCCESS [ldap2_140155643874720] {\"uid\": [\"zuser3\"], \"continue\": false, \"version\": \"2.253\"}",
"CODE_LINE" : "495",
"__REALTIME_TIMESTAMP" : "1716360895014405",
"__MONOTONIC_TIMESTAMP" : "5952405665424",
"_SYSTEMD_OWNER_UID" : "0",
"_SYSTEMD_UNIT" : "session-30.scope",
"_SYSTEMD_CGROUP" : "/user.slice/user-0.slice/session-30.scope",
"CODE_FILE" : "/usr/lib/python3.12/site-packages/ipalib/frontend.py",
"_SYSTEMD_SESSION" : "30",
"_SYSTEMD_INVOCATION_ID" : "d166c864dba04b478d01658aa180d50d",
"_PID" : "255232",
"IPA_API_PARAMS" : "{\"uid\": [\"zuser3\"], \"continue\": false, \"version\": \"2.253\"}",
"MESSAGE_ID" : "6d70f1b493df36478bc3499257cd3b17",
"IPA_API_ACTOR" : "[autobind]",
"_SYSTEMD_SLICE" : "user-0.slice",
"IPA_API_COMMAND" : "user_del",
"_BOOT_ID" : "cce41ab07f404ced8676400eb01bf220",
"__CURSOR" : "s=aa96317d3ab84c16b5f131922414af11;i=94acb;b=cce41ab07f404ced8676400eb01bf220;m=569e7067690;t=6190569742605;x=265dd38af30f934c",
"_AUDIT_SESSION" : "30",
"SYSLOG_IDENTIFIER" : "/usr/bin/ipa",
"_UID" : "0",
"_SYSTEMD_USER_SLICE" : "-.slice",
"_SOURCE_REALTIME_TIMESTAMP" : "1716360895014364",
"_SELINUX_CONTEXT" : "unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023",
"_CMDLINE" : "/usr/bin/python3 -I /usr/bin/ipa -e in_server=True console",
"_EXE" : "/usr/bin/python3.12",
"_GID" : "0",
"IPA_API_RESULT" : "SUCCESS"
}
```
An explanation for this audit message can be generated with `journalctl -x` command:
```
# journalctl -x -g ldap2_140155643874720
May 22 06:54:55 master1.ipa1.test /usr/bin/ipa[255232]: [🡕] [IPA.API] [autobind]: user_del: SUCCESS [ldap2_140155643874720] {"uid": ["zuser3"], "continue": false, "version": "2.253"}
░░ Subject: IPA API command was executed and result of its execution was audited
░░ Defined-by: FreeIPA
░░ Support: https://lists.fedorahosted.org/archives/list/freeipa-users@lists.fedorahosted.org/
░░ Documentation: man:ipa(1)
░░ Documentation: https://freeipa.readthedocs.io/en/latest/api/index.html
░░ Documentation: https://freeipa.readthedocs.io/en/latest/api/user_del.html
░░ FreeIPA provides an extensive API that allows to manage all aspects of IPA deployments.
░░ The following information about the API command executed is available:
░░ [IPA.API] [autobind]: user_del: SUCCESS [ldap2_140155643874720] {"uid": ["zuser3"], "continue": false, "version": "2.253"}
░░ The command was executed by '/usr/bin/ipa' utility. If the utility name
░░ is '/mod_wsgi`, then this API command came from a remote source through the IPA
░░ API end-point.
░░ The message includes following fields:
░░ - executable name and PID ('/mod_wsgi' for HTTP end-point; in this case it
░░ was '/usr/bin/ipa' command)
░░ - '[IPA.API]' marker to allow searches with 'journalctl -g IPA.API'
░░ - authenticated Kerberos principal or '[autobind]' marker for LDAPI-based
░░ access as root. In this case it was '[autobind]'
░░ - name of the command executed, in this case 'user_del'
░░ - result of execution: `SUCCESS` or an exception name. In this case it was
░░ 'SUCCESS'
░░ - LDAP backend instance identifier. The identifier will be the same for all
░░ operations performed under the same request. This allows to identify operations
░░ which were executed as a part of the same API request instance. For API
░░ operations that didn't result in LDAP access, there will be
░░ '[no_connection_id]' marker.
░░ - finally, a list of arguments and options passed to the command is provided
░░ in JSON format.
░░ ---------
░░ The following list of arguments and options were passed to the command
░░ 'user_del' by the '[autobind]' actor:
░░
░░ {"uid": ["zuser3"], "continue": false, "version": "2.253"}
░░ ---------
░░ A detailed information about FreeIPA API can be found at upstream documentation API reference:
░░ https://freeipa.readthedocs.io/en/latest/api/index.html
░░ For details on the IPA API command 'user_del' see
░░ https://freeipa.readthedocs.io/en/latest/api/user_del.html
```
## Feature Management
There is no separate management of the IPA API audit logging. Logging is always
active on IPA server.
systemd journal has own mechanisms to control rates of messages coming from the
services. The details can be found in the man page `journald.conf(5)`.
## Upgrade
There is no impact on upgrade. Once new IPA API code installed, any new
application using it will start issuing log entries to the journald.
## Test plan
Test of IPA API audit logging can be done by observing systemd journal.
+21 -3
View File
@@ -43,6 +43,20 @@ There are a few basic rules:
### Installation
#### SELinux
The two supported hardware HSMs require additional SELinux permissions
so that IPA and certmonger have access to the tokens. There is a
separate module for each one: {free}ipa-selinux-nfast and
{free}ipa-selinux-luna. These are NOT installed by default and
the user must install the appropriate one manually.
During HSM validation early in the installation a check is made to
ensure that the correct module is installed but this is a best
effort and will not cause the installation to fail if the module
is not available.
#### CA
The token name, module name and shared library must be provided to the
@@ -57,6 +71,10 @@ are generated and stored in the HSM.
| --token-name | NSS name for the token |
| --library-path | Path to PKCS#11 shared library |
| --token-password | Password for the token |
| --token-password-file | File containing the token password |
If neither --token-password nor --token-password-file are provided
then the password will be obtained interactively.
This information will be stored in new schema so that replicas can auto-detect when an HSM is configured.
@@ -64,7 +82,7 @@ ipa-ca-install will accept the same options.
```
attributeTypes: (
2.16.840.1.113730.3.8.21.1.TBD
2.16.840.1.113730.3.8.21.1.10
NAME 'ipaCaHSMConfiguration'
DESC 'HSM Configuration'
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
@@ -78,11 +96,11 @@ This attribute will be semi-colon delimited and contain the HSM information need
token-name;library-path
The token password will be prompted by ipa-replica-install or passed on the cli.
On a replica installation the token password will be prompted by ipa-replica-install or passed using the cli options.
The presence of this attribute is enough to indicate that an HSM is present in the installation and the options will automatically be used for additional servers and/or services. The password will not be stored and the user must provide them on the cli. Whenever a replica, replica CA, KRA or replica KRA is added this attribute will be examined to determine whether an HSM is available or not, and what the options are.
A user can override library-path on the command-line in case it is in a different location or architecture. A different token name would mean a different token and they cannot be mixed.
A user can override library-path on the command-line in case it is in a different location or architecture. A different token name would mean a different token and they cannot be mixed. If not provided on the command-line then the stored value will be used.
The NSS module name will be the basepath of the library minus .so*.
+411
View File
@@ -0,0 +1,411 @@
# Identity Mapping
In FreeIPA deployments user and group objects get their POSIX identities (IDs)
assigned and managed in an automated way. This document describes how
identity mapping is performed and enforced in FreeIPA deployments.
## Overview
FreeIPA deployment has three major identity mapping elements:
- automated identifier assignment through LDAP
- automated identifier assignment through SSSD
- identity information consistency enforcement in LDAP and Kerberos KDC
POSIX identities are allocated to objects that need to be visible at run-time
in POSIX environment. These are typically POSIX users and groups but there are
some exceptions to these objects, to accomodate specialized use cases.
In POSIX environment user and group identities are properties of several
different objects. When login session is initiated, the login process is
started as root (ID 0) and during login flow at some point a switch to a
certain user ID is performed. User's primary group is associated with a process
and information about other groups a user is a member of is populated as
'secondary groups' of the process. During lifetime of the process these lists
are typically left intact and cannot be modified unless a process possesses
certain administrative capabilities.
Both user and group IDs in POSIX environment are represented by unsigned
integers. In Linux environment user and group ID spaces are separate and fit
into 32-bit unsigned integer since 2001. Due to historical reasons, some of
file formats might not support more than 16- or 15-bit unsigned integer spaces
for UID and GID values. FreeIPA environment assumes operations in a
contemporary environment, with 32-bit user and group IDs.
[Linux Standard Base](https://en.wikipedia.org/wiki/Linux_Standard_Base) Core
Specification defines certain reserved ID ranges. Some Linux distributions or
projects go beyond that and define own ID ranges. To avoid conflicts with these
ranges, FreeIPA defines its own default ID ranges above 16-bit space.
For interoperability purposes a mapping between POSIX and non-POSIX identities
has to be established. The only supported non-POSIX identities for which there
exists a well defined mapping mechanism are identities represented with the
help of Security IDentifiers (SIDs) from Active Directory.
## Identity ranges
Each POSIX identity issued by the FreeIPA server is generated within a certain
identity range. ID ranges serve several purposes: they help multiple
FreeIPA components to coordinate identity allocation and convey details of the
purpose of the allocated identity ranges.
ID ranges are stored in LDAP, under `cn=ranges,cn=etc,$BASEDN` subtree. LDAP
objects for ID ranges are based on the `ipaidrange` objectclass. Depending on
the type of the range, other objectclasses might be added to express additional
attributes.
As of FreeIPA 4.11, there are following ID range categories in FreeIPA:
- local FreeIPA POSIX ID range (`ipa-local` ID range type)
- POSIX ID range for local subordinate identities (`ipa-ad-trust`)
- trusted domain ID range using automated allocation based on SID of an object (`ipa-ad-trust`)
- trusted domain ID range using explicit allocation for POSIX identities (`ipa-ad-trust-posix`)
These four categories expressed using three ID range types for technical reasons.
More ID ranges can be added through the lifetime of the deployment to
accomodate administrative needs. The main requirement for these additional
ranges is to not overlap with existing ranges. Range consistency is controlled
with the help of a specialized plugin to 389-ds LDAP server, `ipa-range-check`.
When a new range conflicts with existing configuration, its acceptance will be
refused and an LDAP error `LDAP_CONSTRAINT_VIOLATION` will be returned. This
ensures all ranges are in consistent state.
Trusted domain ID ranges have information about the domain SID of the
associated domain stored directly in the range LDAP object. For the local
domain ID ranges this information is stored elsewhere because only a single
organizational domain (as opposed to DNS domains) can be present in IPA
deployment.
Information about SID and other parameters of the local domain is stored in the
LDAP object `cn=<domain>,cn=ad,cn=etc,$SUFFIX`. This information is used for ID
mapping enforcement purposes by SID generation plugin and Kerberos KDC driver.
Information about SID and other parameters of a trusted domain is stored in the
LDAP object `cn=<domain>,cn=ad,cn=trusts,$SUFFIX`. It is used by the Kerberos
KDC driver when processing Kerberos requests.
### Local FreeIPA POSIX ID range
Each FreeIPA deployment has its own primary (or local) POSIX ID range. The
range is chosen during an initial server deployment and cannot be changed.
Initial `admin` user and associated groups (e.g. `admins`) are all allocated
from this range. The range size defaults to 200000 identities but both starting
point and the size of the range can be modified with `ipa-server-install`
options.
The primary ID range corresponds to the DNA range also created during the
initial IPA server deployment. When replica is deployed, this ID range already
exists in the topology and is visible to the replica. However, a corresponding
slice of the DNA range will not be created on the replica until the DNA plugin
on the replica is not asked to allocate an ID. See `Automated Identifier Assignment Through LDAP`_
section for details how DNA ranges are used.
### POSIX ID range for local subordinate identities
Subordinate identities are a Linux Kernel feature to grant a user additional
user and group ID ranges. Amongst others, the feature can be used by container
runtime engines to implement rootless containers. Traditionally subordinate ID
ranges are configured in `/etc/subuid` and `/etc/subgid`. More details about
subordinate ranges can be found in ["Subordinate IDs"](subordinate-ids.html)
design page.
Due to a technical use of a trusted domain type to represent ID range of the
local subordinate identities, the ID range has a domain SID associated with it.
The SID has a special structure: `S-1-5-21-738065-838566-$DOMAIN_HASH`.
`S-1-5-21` is the well-known SID prefix for domain SIDs. `738065-838566`
is the representation of the string `IPA-SUB`. `DOMAIN_HASH` is the
[MURMUR-3](https://en.wikipedia.org/wiki/MurmurHash) hash of the domain name
for key `0xdeadbeef`. SSSD rejects SIDs unless they are prefixed with
`S-1-5-21`. This SID is never used for any SID generation.
### Trusted domain ID range using automated allocation based on SID of an object
Active Directory environment does not use itself any POSIX identities because
they have no meaning within the context of Windows operating system. Each
object in Active Directory has associated security identifier (SID). SIDs stay
the same for the lifetime of the object and never re-used by other objects. SID
can be used to map an object in Active Directory to POSIX environment.
There are several methods to map SIDs to POSIX IDs. FreeIPA relies on an
algorithmic method provided by SSSD. The algorithm is described in
[sssd-ad(5) manual page](https://manpages.org/sssd-ad/5) in the section
"Mapping algorithm".
On start-up, SSSD looks up all ID ranges from the active IPA server and uses
information about trusted domains to map between SIDs and POSIX IDs. This
avoids static allocation of identities in LDAP. Instead, ID ranges in
FreeIPA serve as fences, to prevent other allocators from using these ranges
for static allocation.
For each trusted domain, a separate ID range is created since every trusted
domain has unique domain SID. Each ID range will have own POSIX ID range
allocation. These allocations can be created automatically during `ipa
trust-add` operation or ID ranges can be pre-created in advance with `ipa
idrange-add` operation. The latter is useful when there is a need to explicitly
define specific POSIX ID range boundaries as `ipa trust-add` command only
allows to define a new range's size.
### Trusted domain ID range using explicit allocation for POSIX identities
In case there is already existing static mapping of POSIX identities in Active
Directory, one can explicitly define ID range assocated with the trust to
Active Directory to handle explicit allocation. In this case SSSD will not use
algorithmic method but instead will look up identities from LDAP entry (e.g.
`uidNumber` and `gidNumber` attributes).
In case of explicit allocation, ID range associated with the trusted forest
Active Directory root domain must have ID range type of `ipa-ad-trust-posix`,
as well as all other domains visible through the trust link.
## ID range allocation
During deployment FreeIPA takes a random ID range slice from `(1,10000)` and
multiplies the base offset by 200000. This base becomes a starting point for
the deployment's ID range.
Both starting point and size of the range can be overridden by an administrator
who deploys the initial server. The minimal value for the initial ID range
start cannot be less than `UID_MAX` or `GID_MAX` from `/etc/login.defs`. This
range is then used by all systems enrolled into the domain managed by this
initial server.
Thus, a default range that FreeIPA chooses the deployment ID range from is
200000...2000000000. If this is a single domain and amount of users in it is
not going to be above 200K, then FreeIPA administrators may never need to
allocate another ID range within 200000...2000000000 and that original ID range
stays fixed forever.
There are two other use cases:
- trusting another IPA or AD deployment, and
- migrating pre-existing deployment not based on IPA.
When there are multiple organizational domains around and they need to
interoperate (establish trust between them), additional ID ranges get added on
the consuming side to represent trusted domain(s). For a trusted domain that is
an Active Directory, there would be two possibilities, managed within SSSD and
IPA:
- an ID range is implicit, defined through a murmurhash3 hash of the domain
SID,
- an ID range is explicit, defined by the admin as UID/GID values stored in AD
LDAP user entries for each user. The explicitly defined ID ranges most
likely are part of a legacy setup and most likely are within `UID_MAX` and
`GID_MAX` values from `/etc/login.defs`. There are exceptions, of course.
An implicit ID range derivation by SSSD is described in `sssd-ad(5)`, section 'ID
Mapping'. Samba has own way to derive similar ID ranges based on different
properties of the domain SID, handled by individual `idmap` modules but
conceptually it is similar: a rule is chosen to map those properties to POSIX
IDs and a map is maintained, algorithmically or based on a stored mapping in
Samba's own ID database.
With Active Directory environments all domain objects have their own unique
identifier, in the form of a SID. RID value of the SID is never reused when
objects get deleted and added. This means that for a company with an Active
Directory domain of ~20-25 years and large churn of employees over that time it
is not uncommon to see RIDs above 200K. For such deployments an ID range
SSSD and IPA would need to synthesize on Linux side would have size larger than
200K.
Thus ID range landscape is 'dynamic'. At a given time SSSD on the client will
be able to see all the ID ranges defined within the domain they enrolled into.
When a new trust is established and a new ID range for that trusted domain is
added, SSSD on the client will see this new ID range and will be able to derive
user/group IDs automatically for them. Most likely there are no existing files
on the client with ownership for these IDs yet -- except networking file
systems but for those to be usable at least one system should be able to create
those files with those POSIX IDs on a compatible client.
Existing ranges never change, LDAP plugins provided by FreeIPA prevent
modifying existing ranges in IPA or delete them if there are users/groups
with IDs assigned from those ID ranges.
## Automated identifier assignment through LDAP
When algorithmic ID range is used, SSSD only maps existing users and groups
coming from trusted Active Directory domains and those so based on their SID
values. For all other range types allocation of POSIX IDs is done in advance,
typically when user or group is created or moved from staged/preserved state.
This automated allocation is done with the help of [Distributed Numeric
Assignment (DNA) plugin](https://access.redhat.com/documentation/en-us/red_hat_directory_server/11/html/administration_guide/dna)
in 389-ds LDAP server. DNA plugin has its own identity ranges and provides a
generic mechanism to assign identities to various objects across the whole LDAP
topology. During installation of the original IPA server a DNA range is created
to match the primary IPA ID range. When new replicas added to IPA topology,
their DNA plugins become aware of the overal DNA range and may ask for a
sub-set of it for own needs. This sub-allocation only happens when DNA plugin
needs a range to allocate an ID. For example, when a user or a group is created
on that replica.
Since DNA ranges only get splitted and not extended automatically, IPA ID
ranges aren't tracking changes in DNA ranges. However, if somebody adds new DNA
ranges outside of the original primary IPA ID range, then a corresponding IPA
ID range needs to be created manually. This affects a lot of legacy deployments
where no real control over use of POSIX IDs through static allocation was done.
Another automatic ID assignment happens for SIDs. For each object in LDAP that
has POSIX attributes and `ipaNTUserAttrs` or `ipaNTGroupAttrs` object classes
upon creation a SID is generated by the `ipa-sidgen` 389-ds plugin. The SID is
stored in `ipaNTSecurityIdentifier` attribute. There is also another plugin,
`ipa-sidgen-task`, which handles a task of generating of SIDs for existing
objects. Both plugins issue error messages in the 389-ds error log in case they
were unable to map POSIX ID to a SID.
## ID mapping adjustments using ID overrides
On top of automatically or algorithmically allocated POSIX IDs, administrators
have possiblity to adjust POSIX IDs locally for users and groups coming from
trusted Active Directory domains. The same mechanism can also be used for
adjustments of POSIX IDs on individual IPA clients (or groups of IPA clients)
for legacy compatibility. These mechanisms should not be used for IPA users and
groups in general case because they might break certain assumptions in SSSD and
Kerberos KDC driver.
For users and groups from trusted Active Directory domains, ID overrides in
"Default Trust View" are used by SSSD on IPA server to override any ID
retrieved from the trusted domain controler side or generated algorithmically.
This mechanism allows to migrate pre-defined POSIX IDs from Active Directory by
creating ID overrides for individual users and groups.
From SSSD point of view, these ID overrides represent `uidNumber` and
`gidNumber` attributes as if they were specified in the original LDAP object
entry.
IPA users and groups cannot have ID overrides in the "Default Trust View".
Their POSIX IDs have to be present in their own LDAP object entries.
## Security IDentifiers
While primary goal of FreeIPA is to serve identities for POSIX environment, a
large effort is put into making interoperability with other identity management
systems, out of which Active Directory is the most important one. Active
Directory is using a different method to control access to their resources than
POSIX environment and this method extends from identity management to
authorization mechanisms. It is also has visible effects on various protocols
through which FreeIPA interoperability with Active Directory is achieved.
One of the corner stones of Active Directory security model is the [security
identifier (SID)](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/78eb9013-1c3a-4970-ad1f-2b1dad588a25)
assignment to each object in Active Directory that can be used for security
evaluation. Objects grouped by Active Directory domains, each domain having a
domain SID and all objects within the same domain have their SIDs starting with
the SID of the domain. The relative identifier (RID) is the unique identity of
an object within the domain scope. A full object SID, thus, is a combination of
the `<domain-SID>-<object RID>`.
Since objects are unique within the domain, RIDs can be reused in different
domains. There are common, so-called ['well-known'
identifiers](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/81d92bba-d22b-4a8c-908a-554ab29148ab),
which express the same functional objects in different domains. These
well-known objects have the same RID values but still be distinct: Objects from
`domain1.test` and `domain2.test` with the same RID values will be different.
For example, domain administrator user `Administrator` has RID value 500.
`Administrator` user from `domain1.test` would be different from
`Administrator` user from `domain2.test`, even though their individual RIDs
(500) would be the same. If `domain1.test` has SID `S-1-5-21-123-45-6789` and
`domain2.test` has SID `S-1-5-21-54-321-6789` then `Administrator` user from
`domain1.test` would have SID `S-1-5-21-123-45-6789-500` and `Administrator`
user from `domain2.test` would have SID `S-1-5-21-54-321-6789-500`.
Internally Active Directory does only use user and group names to perform
translation to a SID. Once SID of the object who authenticated the connection
is established, names don't matter anymore. For each authenticated object
within a specific connection a special security token is built which contains
this object's membership information in form of SIDs of groups it belongs to.
Access control lists attached to Active Directory objects contain SIDs as well,
making access control evaluation straightforward: security token SID details
evaluated against access control lists to grant or deny access.
This model is loosely similar to how processes in POSIX environment get
evaluated when accessing resources. Each POSIX process has user identity it is
running under, with a set of primary and secondary groups associated with the
identity as part of the process description. The difference is that POSIX UID
and GID values exist only on a single machine and a care to avoid conflicts
between multiple systems should be taken. In Active Directory model the SIDs
are already bearing domain-specific information, hence allowing to distinguish
objects belonging to different systems. The latter means for both networking
and local resources such as file systems a single access control list mechanism
can be used to address both remote and local identities.
Since SIDs do not exist in POSIX environment, mapping of objects from trusted
Active Directory domains to POSIX environment within IPA deployment is based on
other properties. In particular, a fully-qualified user or group name is used
to represent the user (or group): a user Administrator from `domain1.test`
would have a fully-qualified name `Administrator@domain1.test`, different from
the user Administrator of the domain `domain2.test` which would have a
fully-qualified name of `Administrator@domain2.test`.
Above description uses so-called user principal name (UPN) notation to describe
user names. In this notation a user name corresponds to a (case-insensitive)
Kerberos principal name. Since each Active Directory domain is a Kerberos
realm, this allows to establish mapping between identities on POSIX and Active
Directory levels through Kerberos authorization mechanism.
Active Directory has extended Kerberos protocol by adding a privilege
attributes certificate (PAC) information to the Kerberos ticket issued by
Active Directory domain controllers. The PAC part contains the security token
details of the authenticated object represented by the Kerberos principal.
These details are protected by a set of security checksums that prevent
external modifications to the PAC content. This information is detailed in the
[MS-PAC] and [MS-KILE] specifications Microsoft has published and Open Source
projects such as MIT Kerberos, Heimdal Kerberos, Samba, and FreeIPA have since
implemented.
## Enforcement of ID mapping
For trusted domains using Kerberos protocol to establish trust, a duty to
validate information falls onto Kerberos KDCs of each realm. FreeIPA KDCs
re-assess content of the presented Kerberos tickets and validate PAC issued by
a trusted domain's domain controller. This validation includes checks to make
sure only SIDs from trusted domains can be present there and a trusted domain's
KDC cannot inject SIDs that belong to IPA domain.
The latter is needed because both sides of the trust possess a key that
represents a cross-realm service principal, `krbtgt/DOMAIN1.TEST@DOMAIN2.TEST`.
This key allows KDC from `DOMAIN1.TEST` realm to issue a service ticket that a
client from `DOMAIN1.TEST` can present to a KDC from `DOMAIN2.TEST` to request
a service ticket for a service from `DOMAIN2.TEST`. If a KDC from
`DOMAIN1.TEST` goes rogue and decides to inject SIDs of groups from
`DOMAIN2.TEST` into a security token of the user from `DOMAIN1.TEST`, nothing
can stop it. Thus, a KDC from `DOMAIN2.TEST` must validate that a token encoded
in the PAC buffer of the Kerberos ticket coming from the `DOMAIN1.TEST` is
'sane'.
Sanity checks performed by the KDC in FreeIPA include multiple steps. For each
trusted domain FreeIPA records a list of SIDs that must be filtered out
unconditionally. This list is based on the section ['4.1.2.2 SID Filtering and
Claims Transformation'](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/55fc19f2-55ba-4251-8a6a-103dd7c66280)
of the [MS-PAC] specification. The list can be extended for each specific
domain using `ipa trust-mod` command for both incoming
(`--sid-blacklist-incoming`) and outgoing (`--sid-blacklist-outgoing`)
directions.
Additionally, KDC verifies that a PAC issued by a trusted domain's KDC does not
contain SIDs from IPA domain. In such case the ticket issuance will be rejected.
For each ticket issued, KDC adds information about the requestor's SID
in a separate PAC buffer. During processing of the consequent requests KDC does
validate that a requestor SID is the same as the SID of the identity of the
security token in PAC buffer. This information is then cross-verified against
the list of known trusted domains to avoid cases of impersonation exploited
through [CVE-2020-25721].
As a consequence of these checks, FreeIPA Kerberos KDC only issues initial
Kerberos tickets for principals which have SID assigned. The SID assignment in
FreeIPA is tied to presence of an ID range that covers both `uidNumber` and
`gidNumber` of the LDAP object representing the principal. If there is no such
range can be found, SID will not be issued and a Kerberos principal associated
with this LDAP object will be used for authentication. Thus, SID and POSIX
attributes are tied together.
[MS-KILE]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-kile/2a32282e-dd48-4ad9-a542-609804b02cc9
[MS-PAC]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-pac/166d8064-c863-41e1-9c23-edaaa5f36962
[CVE-2020-25721]: https://www.samba.org/samba/security/CVE-2020-25721.html
+2
View File
@@ -32,3 +32,5 @@ FreeIPA design documentation
passkeys.md
prci_checker.md
rbcd.md
id-mapping.md
audit-ipa-api.md
+396 -313
View File
@@ -1,12 +1,10 @@
# IPA Migration
## Overview
## Overview of the old plugin-based migration
IPA has had a plugin-based migration for remote LDAP servers since
version 2.0.0. It will only migrate users and groups.
IPA has had a plugin-based migration for remote LDAP servers since version 2.0.0. It will only migrate users and groups.
It has some powerful capabilities for working around eccentricities in
the remote server including:
It has some powerful capabilities for working around eccentricities in the remote server including:
* it is idempotent
* support for both RFC2307 and 2307bis
@@ -18,198 +16,272 @@ This is insufficient for the following reasons:
* It severely limits IPA-to-IPA migration as all other entry types are lost
* User-private groups are not maintained
* Syntax errors can cause migration to fail with the only resolution
being to skip broken entries or fix the remote LDAP server
* It is executed as a server-side plugin and if it runs long enough the
client may disconnect
* Syntax errors can cause migration to fail with the only resolution being to skip broken entries or fix the remote LDAP server
* It is executed as a server-side plugin and if it runs long enough the client may disconnect
* There is no feedback during the migration beyond watching the logs
* There is no migration-specific log
The basic operation includes:
* loop through the remote user and group containers examining each entry
* if it looks like a user or group (based on objectclass) try to
migrate it
* if it looks like a user or group (based on objectclass) try to migrate it
* convert group membership from the detected or provided RFC
* retain passwords if the provider LDAP bind user can read them
* drop conflicting attributes (like kerberos)
* skip duplicates so it can be rerun multiple times
* convert groups to IPA POSIX groups
## Use Cases
### Use cases for a new IPA to IPA migration tool
There are two use-cases driving a re-implementation (or extension) of
migration:
There are two use-cases driving a re-implementation (or extension) of migration:
1. Addressing bugs in current LDAP-only migration code
2. Adding IPA-to-IPA migration including all entry types.
## Migration basics
## IPA to IPA migration
### General considerations
### Terminology
LDAP stores information in a tree structure known as the Directory
Information Tree (DIT). Each node in the tree is an entry and each
entry contains information in an attribute=value form. It is a very
different storage model than a relational database as there is no
"join" capability between entries (among other things).
In the following sections we will describe the IPA server that has the data we are pulling the migration data from as the **remote server**, and the **local server** is the new IPA server that will receive this data. So the **local server** is the new server and also the server where the migration tool will be run from. In other words the migration tool pulls from the remote server and applies it to the local server.
The organization of the entries depends on schema which defines which
object types (objectclasses) and attributes (attributetypes) are
allowed. https://ldap.com/ has a pretty decent introduction to LDAP,
schemas, etc. The important thing to understand is that in order for
an attribute to be in an entry, there must be a corresponding
objectclass which allows it, either as a MUST or MAY. The schema defines
a syntax for that attribute which defines what type of data may be
stored in it. Some LDAP servers do a better job than others at enforcing
this syntax.
### Prerequisites
### pure LDAP migration
You must install IPA on the new system (local server), and the domain/suffix must be the final expected values. The remote data will be converted to match the new local server. Typically it is expected that this installation be bare. The tool was not designed to merge two different installations (although it might work).
While it is easy to see a remote LDAP migration as a subset of IPA to
IPA it is better to keep them as separate for the following reasons:
### IPA to IPA migration design
1. It represents a small subset of a typical IPA installation: only
users and groups.
2. The remote schema and DIT are unknown and different for each migration so it will require more care.
3. The quality of the data is unknown. 389-ds, used by IPA, enforces proper syntax where other servers may not.
- IPA-to-IPA migration will be implemented as an *AdminTool* standalone client tool: **/usr/sbin/ipa-migrate**
- Migration will consist of three areas:
- Schema - the LDAP schema (objectclasses and attributes)
- Config - the LDAP configuration under **cn=config** (dse.ldif)
- Database - the main LDAP database
- Allow online (LDAP over the network) or offline (LDIF file) migration. You can mix and match
LDIF (offline) with LDAP (online)
### IPA to IPA migration
### Online migration
For an IPA to IPA migration it is possible to make certain assumptions
that aren't possible in a pure LDAP migration including:
Online migration consists of contacting the remote server over the network and pulling in all the required information. With very large databases this could impact the tool's performance
1. The DIT is understood and consistent
2. Unique UID/GID/login/group name(s) so additional checking is not necessary
3. A consistent schema (perhaps variability for users and groups)
### Offline migration
## Design
Offline migration consists of using LDIF files from the remote server
- Config - the DS config file: **/etc/dirsrv/slapd-YOUR_LDAP_INSTANCE/dse.ldif**
- Schema - all the schema files found under **/etc/dirsrv/schema/** and **/etc/dirsrv/slapd-YOUR_LDAP_INSTANCE/schema/**
- Database - You need to export the **userroot** database to an ldif file
### IPA to IPA migration
Then copy these LDIF files to the new **local server**
It would be risky to hardcode the data to pull in. It is far simpler to
iterate the things you *don't* want to migrate. This should also improve
the chances for future-proofing and preventing bugs like not migrating
some new feature area. It will require that versions only migrate up or
sideways and not backwards.
### Mixing online and offline methods
IPA-to-IPA migration will be implemented as an AdminTool standalone
client.
You are allowed to mix and match both approaches. The most advantageous reason to mix and match these approaches would be if you have a very large database. You can do the config and schema migration online and then use a database LDIF from the remote server for the database migration. This will perform faster than reading and comparing thousands of entries over the network. It will also be more stable. You won't have to worry about network issues breaking the process mid-migration.
#### Prerequisites
### Dry-run migrations
A migration should only be done to a single IPA server. This will greatly
simplify certain things, particularly performance. We may want an option
to allow this and deny it by default.
You can also do a dry-run of the migration to see what would be migrated to the new local server. In addition to a dry-run you can also record to an LDIF file what LDAP operation would be performed during the migration. This LDIF file can be inspected to see fine grained details about what the migration would do, "replayed" to perform the migration at later date, or to reuse a common deployment on multiple IPA servers.
If DNS is enabled on the remote server it will need to be enabled in
the local one in order to migrate DNS data. It would need to be determined
if the DNS DIT exists in a migrated server would allow bind to be
configured (I suspect it will) but we don't want to get into a situation
where the migrated DNS data is unusable.
### Migration modes
#### Retain REALM/domain
As of right now there are two migration modes, but in the future there could be more. Migration modes allow for easier use of the tool. the mode will define what is migrated and what is not.
It will be optional to retain the same REALM and domain. This will make the
use-cases of staging and development server migration possible.
#### Production mode
#### Retain ranges
In production mode basically everything is brought over. It is assumed that the *remote server* is/was fully functional and the database and entry states are valid. This means things like DNA ranges, IDs, and SIDs (ipantsecurityidentifier) will be migrated as is.
This is TBD. I don't know of a reason why a user wouldn't want to retain the
ranges as it would affect owned files, etc, but *someone* may want to make a
clean break. I don't believe it would be difficult to deal with as we would
just set the magic values for DNA generation.
#### Staging mode
In order to retain the range then the remote and local ranges would need to
be compared and the migration rejected if they do not overlap (perhaps allowed
with --force).
In this mode it is assumed that the remote server was in a staging environment and that things like the DNA ranges and ID attributes (uidNumber, gidNumber, etc) should **not** be migrated as is. The DNA entry attributes will be reset to the *magic regen* value.
As for DNA, if the range remains some effort will need to be made to set the
local DNS configuration to match what is available remotely.
### Migration content
This may not be ideal. The basic process would be:
This section will describe how various entries & attributes will be migrated to the local server.
* connect to all servers in the remote IPA installation
* collect the DNA and on-deck ranges
* determine the starting point
* set the local DNA range to this starting point + the range end - 1
#### REALM/Domain
This could well leave huge holes of allocated values within the range but the
DNA plugin should be able to handle that.
For realm/domain/suffixes all the remote data will be converted to match the the new local server. This will apply to all the entries and subtrees. This is an automatic process and can not be adjusted or disabled. This is why it's important when you install the new local server that you set the realm/domain/database suffix to the expected production values.
subids TBD. It may be fine to just straight migrate the range and records.
#### ID ranges
#### Discovery of IPA objects
The migration mode (production or staging) will determine if the ID ranges are migrated or not. You can still skip the ID range migration in production mode using a CLI option and the tool will reset the DNA attributes (uidNumber, gidNumber, etc) to the magic regeneration value.
The objects to migrate can be determined by examining the local API.
It can be iterated to discover the available class objects which contain
the container_dn and other useful information. Not all objects need
to be migrated either because they are internal objects, represent
schema or represent commands that have no underlying storage.
Initialize the API and iterate over Object:
#### Skipped attributes
api.bootstrap(in_server=True, context='migrate')
api.finalize()
When adding new entries to the local server the following attributes are skipped ...
for obj in api.Object:
work()
Operational attributes
- modifiersname
- modifytimestamp
- creatorsname
- createtimestamp
- nsuniqueid
- dsentrydn
- entryuuid
This gives us an alphabetized list of objects. An implicit relationship
can be determined by examining the member* values in `obj.attribute_members`
if it is present.
Standard attributes
- krbextradata
- krblastfailedauth
- krblastpwdchange
- krbloginfailedcount
- krbticketflags
- krbmkey
- ipasshpubkey --> We do keep the public key for users
- mepmanagedentry
- memberof
- krbprincipalkey
- memberofindirect
- memberindirect
- memberofindirect
- memberindirect
- userCertificate --> if issued by the remote IPA server
Using this list we know which are "leaf" entries which have no dependencies.
These are migrated first. Then the list is iterated again looking for
those with dependencies that are already satisfied and those are migrated.
And so on.
#### Ignored attributes
So for example users and hosts are migrated. Then groups, which has a dependency on
users. Then hostgroups can then be migrated.
When comparing entries (not when adding entries) the following attributes are ignored and the value that exists on the local server will remain intact
Some objects, like hostgroups, can be nested. These will need to be deferred until
all of their members are added. If a running list of objects that have been migrated
is maintained then it can be easily calculated which are ready for migration and
which are not without having to refer to LDAP.
- description
- ipasshpubkey
- ipantsecurityidentifier --> except in production mode
- ipantflatname
- ipamigrationenabled
- ipauniqueid
- serverhostname
- krbpasswordexpiration
- krblastadminunlock
#### Objects to ignore
#### DNS records
The IPA API object list includes an number of internal-only objects and
some classes that represent informational commands so they can be skipped
for migration.
By default all DNS entries are migrated, but you can skip the DNS records via a CLI option.
| Object | Reason |
| --- | ----- |
| certreq | no storage |
| class | schema |
| command | internal |
| cosentry | migration not needed |
| dns_system_records | no storage |
| metaobject | schema |
| param | internal |
| pkinit | no storage |
| topic | internal |
| userstatus | no storage |
#### Limited migration
#### Objects TBD
If there are cases where you don't want to migrate the configuration or schema there are CLI options to skip each of these areas.
Each DNS record type is represented as a separate class. It is probably safe
to just bulk import all dns records as there isn't any IPA-specific information in them.
#### Non-IPA content
So basically add them to the ignore list.
Some Administrators store non-IPA content in the database tree. In order for this content to be migrated it must be specified via a CLI option.
#### Other Containers
### Configuration migration design
Not all data in IPA can be manipulated with the API.
The following sections of the Directory Server configuration will be migrated
cn=certificates,cn=ipa,cn=etc,$SUFFIX contains any user-provided certificates.
I think we can skip this and require that any necessary certificates be
re-added. Otherwise, to be safe, we should validatate the trust and expiration
dates on all of them.
#### Core configuration (cn=config)
DNA ranges. Depending on the local ranges we could try to recover them.
The core configuration attributes will be migrated to the core server. Things like performance tuning, security settings, and log rotation settings.
#### Items to NOT be migrated
#### Database settings
The various look through limits, ID scan limits, import cache size, backend indexes, and encrypted attributes are migrated.
#### Plugins
The following plugins are migrated
- Attribute Uniqueness plugins
- DNA Plugins
- MemberOf plugin
- Referential integrity plugin
- Retro Changelog plugin
- SASL Mapping plugins
- IPA DNS plugin
- IPA Enrollment plugin
- IPA Extdom plugin
- IPA Graceperiod plugin
- IPA Lockout plugin
- IPA Password Policy plugin
- IPA Topology plugin
- IPA Unique ID plugins
- IPA Winsync plugin
- Schema Compatibility plugin
- Slapi NIS plugin
### Schema migration design
By default any *missing* objectclasses and attributes are migrated. There is also a CLI option to completely overwrite the existing schema on the local server with the remote server's schema.
### Database migration design
The following subtrees and entries are migrated. Any missing entries will be added, and any existing entries will be compared and any differences will be merged into the new local server
#### Plugin entries
- Automember Definitions (subtree of ```cn=automember,cn=etc,$SUFFIX```)
- DNA Ranges (subtree of ```cn=ranges,cn=etc,$SUFFIX```)
- DNA Posix IDs (```cn=automember,cn=etc,$SUFFIX```)
- DNA SubIDs (```cn=subordinate-ids,cn=dna,cn=ipa,cn=etc,$SUFFIX```)
- MEP Templates (subtree of ```cn=templates,cn=managed entries,cn=etc,$SUFFIX```)
- MEP Definitions (subtree of ```cn=definitions,cn=managed entries,cn=etc,$SUFFIX```)
#### Etc entries
- Anonymous Limits (```cn=anonymous-limits,cn=etc,$SUFFIX```)
- CA (```cn=ca,$SUFFIX```)
- IPA Config (```cn=ipaconfig,cn=etc,$SUFFIX```)
- Sys Accounts (subtree of ```cn=sysaccounts,cn=etc,$SUFFIX```)
- Topology (subtree of ```cn=topology,cn=ipa,cn=etc,$SUFFIX```)
- Certmap (```cn=certmap,$SUFFIX```)
- Certmap Rules (subtree of ```cn=certmaprules,cn=certmap,$SUFFIX```)
- s4u2proxy (subtree of ```cn=s4u2proxy,cn=etc,$SUFFIX```)
- Passkey Config (```cn=passkeyconfig,cn=etc,$SUFFIX```)
- Desktop Profile (```cn=desktop-profile,$SUFFIX```)
- OTP (```cn=otp,cn=etc,$SUFFIX``)
- Realm (subtree of ```cn=realm domains,cn=ipa,cn=etc,$SUFFIX```)
- AD (subtree of ```cn=ad,cn=etc,$SUFFIX```)
- Master Configurations (subtree of ```cn=masters,cn=ipa,cn=etc,$SUFFIX```)
- Domain Configuration (```cn=domain level,cn=ipa,cn=etc,$SUFFIX```)
#### Accounts
- Computers (subtree of ```cn=computers,cn=accounts,$SUFFIX```)
- Administrator (uid=admin,cn=users,cn=accounts,$SUFFIX)
- Users (subtree of ```cn=users,cn=accounts,$SUFFIX```)
- Groups (subtree of ```cn=groups,cn=accounts,$SUFFIX```)
- Roles (subtree of ```cn=roles,cn=accounts,$SUFFIX```)
- Host Groups (subtree of ```cn=hostgroups,cn=accounts,$SUFFIX```)
- Services (subtree of ```cn=services,cn=accounts,$SUFFIX```)
- Views (subtree of ```cn=views,cn=accounts,$SUFFIX```)
- IP Services (subtree of ```cn=ipservices,cn=accounts,$SUFFIX```)
- Sub IDs (subtree of ```cn=subids,cn=accounts,$SUFFIX```)
#### HBAC & PBAC
- HBAC Services (subtree of ```cn=hbacservices,cn=hbac,$SUFFIX```)
- HBAC Service Groups (subtree of ```cn=hbacservicegroups,cn=hbac,$SUFFIX```)
- PBAC Privileges (subtree of ```cn=privileges,cn=pbac,$SUFFIX```)
- PBAC Permissions (subtree of ```cn=permissions,cn=pbac,$SUFFIX```)
#### Sudo
- Sudo Rules (subtree of ```cn=sudorules,cn=sudo,$SUFFIX```)
- Sudo Commands (subtree of ```cn=sudocmds,cn=sudo,$SUFFIX```)
- Sudo Command Groups (subtree of ```cn=sudocmdgroups,cn=sudo,$SUFFIX```)
#### DNS
- DNS Records (subtree of ```cn=dns,$SUFFIX```)
- DNS Servers (subtree of ```cn=servers,cn=dns,$SUFFIX```)
#### Kerberos
- Kerberos Realm & Policy (subtree of ```cn=kerberos,$SUFFIX```)
- Kerberos Password Policy (```cn=global_policy,cn=$REALM,cn=kerberos,$SUFFIX```)
- Kerberos Default Password Policy (```cn=default kerberos service password policy,cn=$REALM,cn=kerberos,$SUFFIX```)
#### Misc
- Automounts & Automount Maps (subtree of ```cn=automount,$SUFFIX```)
- Trusts (subtree of ```cn=trusts,$SUFFIX```)
- Provisioning (subtree of ```cn=accounts,cn=provisioning,$SUFFIX```)
- SELinux Usermaps (subtree of ```cn=usermap,cn=selinux,$SUFFIX```)
- DUA Config Profiles (subtree of ```ou=profile,$SUFFIX```)
- CA Certificates (subtree of ```cn=certificates,cn=ipa,cn=etc,$SUFFIX```)
#### Excluded Subtrees
- All Class Of Service (COS) entries
- ```cn=sec,cn=dns,$SUFFIX```
- ```cn=custodia,cn=ipa,cn=etc,$SUFFIX```
#### Entries NOT be to migrated
We will not have migrate existing keys from the remote IPA server so the
following will not be migrated:
@@ -221,127 +293,11 @@ following will not be migrated:
* DNSSEC keys
* admin password
* DM password
* Basically anything in Custodia
* Anything in Custodia
#### Migrating conflicting data
### Migration steps
For new entries (users, groups, hosts, etc) we can do a straight LDAP
ADD after massaging necessary attributes (see Attributes to not migrate).
That is the easy part.
There are some parts of IPA that are default and will exist in both servers
such as the configuration (config commands), allow_all HBAC rule,
permissions, privileges, roles, selinux mappings, ipaservers hostgroup and more.
The strategy for this will be use the existing entry comparison in ldap2 and
modify the new IPA instation to match the original minus some specific things like
the CA subject base in the config. So in most cases we favor the remote IPA
installation except for things which are installation-dependent.
The downside of this is that it could interpret "fresher" defaults in the
new IPA server with stale ones from the old. We will need good logging around
these types of entries.
Standard boilerplate will not be evaluated, things like cosTemplates. These are not
user-modifiable and if a user decides to mess with them, they can correct it
after migration.
#### Migrating cn=config
A number of plugins are optional in IPA: nis, compat, ACME.
These will be enabled in the new IPA server if enabled in the remote at
the end of migration:
* cn=Schema Compatibility, cn=plugins, cn=config
* cn=NIS Server, cn=plugins, cn=config
Schema compatibility will be disabled during migration as it can cause
performance issues and we don't want to try to migrate anything in
cn=compat since it is generated data.
ACME is a feature of the CA. We should be able to import ipa_acme_manage
and call enable/disable within the migration if it is remotely enabled.
#### Configuration to not migrate
These will not be migrated:
* AD Trusts
* Winsync configuration (though the entries will)
* CA, KRA
* DNSSEC
#### Special migration
cn=kerberos contains the Kerberos master key as well as the default
ticket policy. Only the policy can be migrated.
#### Attributes to not migrate
Some attributes we will need to completely drop because they contain key or
server-specific information for the remote IPA server. This may also
include objectClasses that may need to be dropped if the last attribute
is removed.
* krbPrincipalKey (will require dropping objectclasses)
* krbExtraData
* ipaNTSecurityIdentifier
* memberOf (will be reconstructed after the migration)
* userCertificate if issued by the remote IPA server
#### Attributes to update to new REALM
If a REALM change is part of migration then these will need to be updated
to reflect the new installation.
* krbPrincipalKey
* krbCanonicalName
#### Attributes to change basedn
Prior to writing a new value any DN syntax attributes will need to be
examined to see if they contain the remote baseDN if it is different. If
so then the following need to be updated:
* mepManagedEntry
* mepManagedBy
#### Migrating custom schema
Schema is stored in LDAP so we *should* be able to use our ldap library
to discover differences. We probably want to do only ADD and bail if we
determine something will be a MOD or DEL.
#### Excluding specific entries
The ignore user/group options of migrate-ds were introduced so that non-compliant
entries could be skipped to not block the migration. We can ignore these for now.
#### Performance considerations
Some benefits would be likely if common entry types were added in
batches rather than individually. This would not easily allow for a
"stop on failure" approach but could be considerably faster.
The basic idea is that added entries of the same type (user, group, etc)
would be accumulated and added together. The result would be iterated
through and logged.
The memberOf plugin should be disabled. A fixup task can be run post-migration
to calculate the memberships.
#### Idempotency
The migrate-ds plugin manages idempotency because it skips over entries
that already have been migrated (or exist). This new migration will handle
it by merging the remote and local entries. This may not be desirable in
all cases.
#### Migration steps
A simplistic view of the steps
A simplistic view of the steps (the following might be outdated/unnecessary - TODO)
Set migration mode=True
Disable compat
@@ -358,44 +314,167 @@ Enable compat
Restart world
Run ipa-server-upgrade
### pure LDAP migration
#### Supported Migration Scenarios
The current code generally works minus a few bugs and RFEs, some of which are resolved
by doing an IPA-to-IPA migration instead. It should be maintained for now and migrated
to the standalone client in the future.
There are quite a few ways that migration can be done, both for testing and production uses. Any scenario not specifically mentioned here should be considered unsupported.
These bugs should be considered for the existing plugin.
These scenarios are not enforced by code. At best we can prompt the user
for confirmation if we believe that they are non-conformant but I choose
the trade-off of allowing for unsupported migrations to the flexibility
of not trying to force square pegs into round holes.
* https://pagure.io/freeipa/issue/3096 - error when migrating unknown schema
* https://pagure.io/freeipa/issue/3100 - Check for userPassword in migration
* https://pagure.io/freeipa/issue/4738 - [RFE] ipa migrate-ds should provide option for creating UPG from posixGroup objectClass
* https://pagure.io/freeipa/issue/5020 - migrate-ds: does not show migrated users if an error happened during group migration
* https://pagure.io/freeipa/issue/5693 - Passwords become "expired" when migrating from directory server to IPA
* https://pagure.io/freeipa/issue/6105 - migrate-ds is not completely ignoring attributes.
* https://pagure.io/freeipa/issue/6360 - ipa migrate-ds does not rename uniquemember/member attributes properly
* https://pagure.io/freeipa/issue/6380 - ipa migrate-ds should print warning for referrals
* https://pagure.io/freeipa/issue/7368 - ipa migrate-ds converts groupofuniquenames objects to groupofnames, but leaves groupofuniquenames objectclass present
* https://pagure.io/freeipa/issue/7749 - `ipa migrate-ds` fails to migrate user and group data from directory server to IDM.
There are a few points to consider.
**Replicas**
All references to replicas in the existing deployment will not be migrated. There is no mechanism to one-by-one replace each server with a new one using migration. One will be migrated and new replicas will need to be manually added directly to that using ipa-replica-install.
**Kerberos**
The Kerberos master key will not be migrated. Kerberos principals are retained but the keys are not.
**Certificates**
The existing CA will be abandoned in favor of a CA on the new installation.
If the realm, domain and CA subject base (default is O=REALM) are identical between the two installations then there is no way, other than the CA private key, to distinguish between the original CA and the new CA. Therefore no certificates will be maintained in the migration. All certificates other than those already present in the new IPA server as part of installation will need to be re-issued.
If one of these doesn't match then the certificates will be retained but the backing PKI will be lost so there will be no possibility of renewals or revocation (no OCSP or CRL).
##### Scenario 1 - Production to new production
Preconditions:
* There is a existing production IPA server (or servers)
* There is a new IPA server installation with the same realm and domain
Optional:
* If desired the realm and domain may be changed. The migrated data will accommodate these changes but this will require reconfiguration of all clients, etc. beyond just re-enrollment.
Result:
* All valid IPA entries will be migrated
* All ids (uid, gid, SID, etc) will be maintained
* All certificates issued from the previous CA will be dropped unless the CA subject base DN, or the realm, is changed in the new deployment.
* All clients must re-enroll to the new deployment
* Users will have to migrate their passwords to generate Kerberos and other keys
##### Scenario 2 - Production to new staging
Preconditions:
* There is an existing production IPA server (or servers)
* There is a new IPA server installation with a different realm and domain (e.g. staging.example.test)
Result:
* All valid IPA entries will be migrated
* All ids (uid, gid, SID, etc) will be re-generated
* All certificates from the previous CA will be preserved
* Given this is a new staging deployment there will be no enrolled clients. The host entries from the production deployment will exist but all keys are dropped.
* Users will have to migrate their passwords to generate Kerberos and other keys
##### Scenario 3 - Staging to new production
Preconditions:
* There is an existing production IPA server (or servers)
* There is a new IPA server installation with a different realm and domain (e.g. staging.example.test)
Result:
* All valid IPA entries will be migrated
* All ids (uid, gid, SID, etc) will be re-generated
* All certificates from the previous CA will be removed
* Users will have to migrate their passwords to generate Kerberos and other keys
##### Scenario 4 - From IPA backup
The migration tool will have the capability to do offline migration using an LDIF file. An IPA backup is a tar ball that contains the IPA data in EXAMPLE-TEST-userRoot.ldif
Preconditions:
* A backup from an existing IPA installation exists
* There is a new IPA server installation with the same realm and domain
Result:
* All valid IPA entries will be migrated
* All ids (uid, gid, SID, etc) will be maintained
* All certificates issued from the previous CA will be dropped unless the CA subject base DN, or the realm, is changed in the new deployment.
* All clients must re-enroll to the new deployment
* Users will have to migrate their passwords to generate Kerberos and other keys
## Logging
By default the log file will be /var/log/ipa-migrate.log and will be appended to
and not overwritten. This is so it can reflect multiple runs if they are required.
At least the DN of all entries written should be logged (pkey may be sufficient).
### Standard logging
Logging by object type could be handy and should natural since this is how the
objects will be sorted.
Here is an example of the standard logging
DEBUG logging may want to show gory details, particularly when merging entries.
```
024-02-27T17:10:03Z DEBUG ================================================================================
2024-02-27T17:10:03Z INFO IPA to IPA migration starting ...
2024-02-27T17:10:03Z DEBUG Migration options:
2024-02-27T17:10:03Z DEBUG --mode=prod-mode
2024-02-27T17:10:03Z DEBUG --hostname=hpe-dl385gen8-01.hpe2.lab.eng.bos.redhat.com
2024-02-27T17:10:03Z DEBUG --verbose=False
2024-02-27T17:10:03Z DEBUG --bind-dn=cn=directory manager
2024-02-27T17:10:03Z DEBUG --bind-pw-file=None
2024-02-27T17:10:03Z DEBUG --cacertfile=None
2024-02-27T17:10:03Z DEBUG --subtree=[]
2024-02-27T17:10:03Z DEBUG --log-file=/var/log/ipa-migrate.log
2024-02-27T17:10:03Z DEBUG --skip-schema=False
2024-02-27T17:10:03Z DEBUG --skip-config=False
2024-02-27T17:10:03Z DEBUG --migrate-dns=False
2024-02-27T17:10:03Z DEBUG --dryrun=True
2024-02-27T17:10:03Z DEBUG --dryrun-record=None
2024-02-27T17:10:03Z DEBUG --force=False
2024-02-27T17:10:03Z DEBUG --version=False
2024-02-27T17:10:03Z DEBUG --quiet=False
2024-02-27T17:10:03Z DEBUG --schema-overwrite=False
2024-02-27T17:10:03Z DEBUG --reset-range=False
2024-02-27T17:10:03Z DEBUG --db-ldif=None
2024-02-27T17:10:03Z DEBUG --schema-ldif=None
2024-02-27T17:10:03Z DEBUG --config-ldif=None
2024-02-27T17:10:03Z DEBUG --no-prompt=False
2024-02-27T17:10:03Z DEBUG flushing ldapi://%2Frun%2Fslapd-HPE2-LAB-ENG-BOS-REDHAT-COM.socket from SchemaCache
2024-02-27T17:10:03Z DEBUG retrieving schema for SchemaCache url=ldapi://%2Frun%2Fslapd-HPE2-LAB-ENG-BOS-REDHAT-COM.socket conn=<ldap.ldapobject.SimpleLDAPObject object at 0x7f5a1eb68210>
2024-02-27T17:10:03Z DEBUG retrieving schema for SchemaCache url=ldap://hpe-dl385gen8-01.hpe2.lab.eng.bos.redhat.com conn=<ldap.ldapobject.SimpleLDAPObject object at 0x7f5a1e7eba10>
2024-02-27T17:10:04Z DEBUG Found realm from remote server: HPE2.LAB.ENG.BOS.REDHAT.COM
2024-02-27T17:10:04Z INFO Migrating schema ...
2024-02-27T17:10:04Z DEBUG Getting schema from the remote server ...
2024-02-27T17:10:04Z DEBUG Retrieved 1556 attributes and 349 objectClasses
2024-02-27T17:10:07Z DEBUG Migrated 0 attributes and 0 objectClasses
2024-02-27T17:10:07Z DEBUG Skipped 1556 attributes and 349 objectClasses
2024-02-27T17:10:07Z INFO Migrating configuration ...
2024-02-27T17:10:07Z DEBUG Getting config from the remote server ...
2024-02-27T17:10:08Z DEBUG flushing ldapi://%2Frun%2Fslapd-HPE2-LAB-ENG-BOS-REDHAT-COM.socket from SchemaCache
2024-02-27T17:10:08Z DEBUG retrieving schema for SchemaCache url=ldapi://%2Frun%2Fslapd-HPE2-LAB-ENG-BOS-REDHAT-COM.socket conn=<ldap.ldapobject.SimpleLDAPObject object at 0x7f5a1eb68210>
2024-02-27T17:10:09Z INFO Migrating database ... (this make take a while)
2024-02-27T17:10:11Z DEBUG Removed IPA issued userCertificate from: krbprincipalname=ldap/hpe-dl385gen8-01.hpe2.lab.eng.bos.redhat.com@HPE2.LAB.ENG.BOS.REDHAT.COM,cn=services,cn=accounts,dc=hpe2,dc=lab,dc=eng,dc=bos,dc=redhat,dc=com
2024-02-27T17:10:11Z DEBUG Skipping remote certificate entry: 'cn=HPE2.LAB.ENG.BOS.REDHAT.COM IPA CA,cn=certificates,cn=ipa,cn=etc,dc=hpe2,dc=lab,dc=eng,dc=bos,dc=redhat,dc=com' Issuer: CN=Certificate Authority,O=HPE2.LAB.ENG.BOS.REDHAT.COM
2024-02-27T17:10:11Z DEBUG Removed IPA issued userCertificate from: krbprincipalname=HTTP/hpe-dl385gen8-01.hpe2.lab.eng.bos.redhat.com@HPE2.LAB.ENG.BOS.REDHAT.COM,cn=services,cn=accounts,dc=hpe2,dc=lab,dc=eng,dc=bos,dc=redhat,dc=com
2024-02-27T17:10:16Z INFO Running ipa-server-upgrade ... (this make take a while)
2024-02-27T17:10:16Z INFO Skipping ipa-server-upgrade in dryrun mode.
2024-02-27T17:10:16Z INFO Running SIDGEN task ...
2024-02-27T17:10:16Z INFO Skipping SIDGEN task in dryrun mode.
2024-02-27T17:10:16Z INFO Migration complete!
```
## Implementation
### Verbose logging
The command will be named ipa-migrate. It must determine whether the remote server is
actually an IPA server or not. ipaclient/discovery.py::ipacheckldap may be re-usable.
If get the verbose logging you simply just use the **--verbose, -v** CLI option. Here you will see the exact operations there were performed. Here is an example showing the additional information that is logged.
```
...
...
2024-02-28T15:30:53Z INFO Migrating database ... (this make take a while)
2024-02-28T15:30:53Z INFO Entry is different and will be updated: 'uid=admin,cn=users,cn=accounts,dc=hpe2,dc=lab,dc=eng,dc=bos,dc=redhat,dc=com' attribute 'ipaNTSecurityIdentifier' replaced with val 'S-1-5-21-404865364-1326736403-3398440945-501' old value: ['S-1-5-21-404865364-1326736403-3398440945-500']
2024-02-28T15:30:53Z INFO Add db entry 'uid=mark,cn=users,cn=accounts,dc=hpe2,dc=lab,dc=eng,dc=bos,dc=redhat,dc=com - users'
2024-02-28T15:30:53Z INFO Entry is different and will be updated: 'cn=HPE2.LAB.ENG.BOS.REDHAT.COM_id_range,cn=ranges,cn=etc,dc=hpe2,dc=lab,dc=eng,dc=bos,dc=redhat,dc=com' attribute 'ipaBaseID' replaced with val '9000999' old value: ['90000000']
2024-02-28T15:30:53Z INFO Entry is different and will be updated: 'cn=HPE2.LAB.ENG.BOS.REDHAT.COM_subid_range,cn=ranges,cn=etc,dc=hpe2,dc=lab,dc=eng,dc=bos,dc=redhat,dc=com' attribute 'ipaIDRangeSize' replaced with val '2147352575' old value: ['2147352576']
...
...
```
The standalone client should use a unique context, migration. This will
allow for a separate configuration file.
## Feature Management
@@ -405,51 +484,55 @@ No UI option will be provided. This is command-line client only.
### CLI
Overview of the CLI commands.
Overview of the CLI usage
#### IPA to IPA
Advance knowledge of the DIT substantially reduces the number of options
necessary for migration.
ipa-migrate <prod-mode|stage-mode> <HOSTNAME> [options]
| Option | Description |
| --- | --- |
| --dry-run | try the migration without writing data |
| --force | ignore errors and keep going |
| --version | version of the tool |
| --quiet | output only errors |
| --log-file | log to the given file |
| --help | this message |
| --bind-dn, -D | The bind DN to use for authentication to the remote IPA server (default is "cn=directory manager") |
| --bind-pw, -w | The password for the bind DN |
| --bind-pw-file, -j | A file that contains the password |
| --cacertfile, -Z | The CA cert file |
| --skip-schema, -S | Do not migrate the schema |
| --skip-config, -C | Do not migrate the DS configuration |
| --schema-overwrite, -O | Completely overwrite schema |
| --reset-range, -r | Reset all the DNA attributes (uidNumber, etc) to the magic regen value (-1) |
| --db-ldif, -f | An LDIF file containing the export of the userRoot database |
| --schema-ldif, -m | An LDIF file containing the schema from the remote server |
| --config-ldif, -g | The DS config file dse.ldif |
| --migrate-dns, -B | Migrate the DNS records in the database |
| --subtree, -s | Non standard IPA subtree to include in the migration |
| --dryrun, -x | try the migration without writing data |
| --dryrun-record, -o | Perform dryrun but record all the LDAP changes to a LDIF file |
| --force. -F | ignore errors and keep going |
| --version, -V | version of the tool |
| --quiet, -q | output only errors |
| --no-prompt, -n | Do not do a confirmation prompt about starting the migration |
| --log-file, -l | log to the given file |
| --verbose, -v | Display verbose output |
| --help, -h | this message |
The DM password will be prompted for interactively.
If the DM password is not provided then you will be prompted for it.
| Argument | Description |
| url | ldap url for remote IPA server |
#### Examples
#### pure LDAP
# ipa-migrate prod-mode remote.server.com
# ipa-migrate prod-mode remote.server.com --dryrun
# ipa-migrate prod-mode remote.server.com -D "cn=directory manager" -j ./passwd.txt
# ipa-migrate prod-mode remote.server.com --db-ldif=/tmp/remote-userroot.ldif
# ipa-migrate prod-mode remote.server.com --skip-config --skip-schema
# ipa-migrate stage-mode remote.server.com --dryrun-record=/tmp/dryrun-ops.ldif
# ipa-migrate stage-mode remote.server.com --config-ldif=/tmp/dse.ldif --schema-ldif=/tmp/schema.ldif --db-ldif=/tmp/remote-userroot.ldif
Will remain unchanged unless one of the bug fixes requires it (perhaps for the UPG
ticket).
# ipa-migrate stage-mode remote.server.com --subtree="ou=my own data,dc=ipa,dc=com"
### Configuration
N/A
## Upgrade
N/A
## Test plan
There are currently no tests for migration.
Some simplisitic approaches for starting testing might include:
* Count the number of entries that will be migrated and ensure they were migrated, by type (hosts, groups, etc).
* Verify that the services enabled on the remote side are enabled after migration (NIS, ACME, etc).
* Double-check, perhaps spot-checking, memberOf
* Migrate a password to ensure it was imported properly
We have a data generation script in freeipa-tools that may be leveraged to generate the data but it currently generates a LOT of entries which is likely too much for automation.
## Troubleshooting and debugging
+18
View File
@@ -173,6 +173,7 @@ any user. However, to make it usable for S4U2Proxy (constrained delegation),
the service ticket must be forwardable. In such case the Kerberos service would
be able to impersonate user and requires an explicit administrative permission.
IPA API provides a way to record this permission in both host and service
command families. The following commands have option
`--ok-to-auth-as-delegate=BOOL`:
@@ -183,6 +184,23 @@ command families. The following commands have option
This flag is equivalent to MS-SFU's `TrustedToAuthenticationForDelegation`
boolean setting.
The behavior of FreeIPA regarding S4U2Self-granted tickets differs depending of
the krb5 version that was used to compile:
* **krb5 1.20+**: KDC will always respond to S4U2Self TGS-REQ with forwardable
tickets, except if the requester principal is set as impersonator service in
at least one general constrained delegation rule (even if the rule has no
target set)
* **krb5 1.19-**: KDC will respond to all S4U2Self TGS-REQs with non-forwardable
tickets
In both cases, granting the `ok-to-auth-as-delegate` permission to a principal
will override this default behavior and allow it to obtain forwardable tickets
to itself. In practice, it means the `ok-to-auth-as-delegate` permission is
required if you want to grant a service the special privilege to impersonate
any user against services configured as targets in a general constrained
delegation rule.
### General constrained delegation design
General constrained delegation uses two objects: a rule and a target.
+1
View File
@@ -11,6 +11,7 @@ m2r2
## ipa dependencies
dnspython
jwcrypto
ifaddr
netaddr
qrcode
six
+4 -3
View File
@@ -1,4 +1,5 @@
..
.. _1-server-install:
Copyright 2015-2018 Red Hat, Inc.
This work is licensed under the Creative Commons Attribution 4.0
@@ -157,8 +158,8 @@ more!
To prepare for the next unit, exit the ``server`` SSH session (but
do not shut the VM down). The next essential unit is
`Unit 2: Enrolling client machines <2-client-install.rst>`_.
:ref:`Unit 2: Enrolling client machines <2-client-install>`.
Alternatively, if you would like to immediately install a replica
server (essential for production deployments), you can take a detour
to `Unit 7: Replica installation <7-replica-install.rst>`_.
to :ref:`Unit 7: Replica installation <7-replica-install>`.
+3 -1
View File
@@ -1,9 +1,11 @@
.. _10-ssh-key-management:
Unit 10: SSH user and host key management
=========================================
**Prerequisites:**
- `Unit 3: User management and Kerberos authentication <3-user-management.rst>`_
- :ref:`Unit 3: User management and Kerberos authentication <3-user-management>`
In this module you will explore how to use FreeIPA as a backend
provider for SSH keys. Instead of distributing ``authorized_keys``
+3 -1
View File
@@ -1,9 +1,11 @@
.. _11-kerberos-ticket-policy:
Unit 11: Kerberos ticket policy
=========================================
**Prerequisites:**
- `Unit 3: User management and Kerberos authentication <3-user-management.rst>`_
- :ref:`Unit 3: User management and Kerberos authentication <3-user-management>`
In this module you will explore how to manage properties of Kerberos
authentication and authorization in FreeIPA.
+8 -1
View File
@@ -1,9 +1,11 @@
.. _12-external-idp-support:
Unit 12: Authentication against external Identity Providers
===========================================================
**Prerequisites:**
- `Unit 11: Kerberos ticket policy <11-kerberos-ticket-policy.rst>`_
- :ref:`Unit 11: Kerberos ticket policy <11-kerberos-ticket-policy>`
In this module you will explore how to manage use external OAuth 2.0 servers to
authorize issuance of Kerberos tickets in FreeIPA.
@@ -389,6 +391,11 @@ for Keycloak or Red Hat SSO IdPs. The template expects both Keycloak's realm
typically deployed as a part of a larger solution. These options may not be
needed for other pre-defined templates like Google or Github.
The `openid` scope is mandatory since
[Keycloak 19.0.2](https://www.keycloak.org/docs/latest/upgrading/index.html#userinfo-endpoint-changes).
Without the `openid` scope, Keycloak refuses userinfo requests with HTTP
response 403: `invalid_scope` `Missing openid scope`.
Associate IdP reference with IPA user
-------------------------------------
+4 -2
View File
@@ -1,9 +1,11 @@
.. _2-client-install:
Unit 2: Enrolling client machines
===================================
**Prerequisites**:
- `Unit 1: Installing the FreeIPA server <1-server-install.rst>`_
- :ref:`Unit 1: Installing the FreeIPA server <1-server-install>`
In this unit, you will enrol a *host* as a client of your FreeIPA
domain. This means that *users* in your FreeIPA realm (or Active
@@ -57,4 +59,4 @@ logged onto the host can also acquire Kerberos tickets for accessing
*services* in your domain.
You can now move on to
`Unit 3: User management and Kerberos authentication <3-user-management.rst>`_.
:ref:`Unit 3: User management and Kerberos authentication <3-user-management>`.
+4 -2
View File
@@ -1,3 +1,5 @@
.. _3-user-management:
Unit 3: User management and Kerberos authentication
=====================================================
@@ -124,8 +126,8 @@ is a true *single sign-on* protocol!
Now that you have created some users, it's time to define some
access policies. Proceed to
`Unit 4: Host-based access control (HBAC) <4-hbac.rst>`_.
:ref:`Unit 4: Host-based access control (HBAC) <4-hbac>`.
Alternatively, if you are interested in SSH public key management
for users and hosts, jump ahead to
`Unit 10: SSH user and host key management <10-ssh-key-management.rst>`_.
:ref:`Unit 10: SSH user and host key management <10-ssh-key-management>`.
+5 -3
View File
@@ -1,9 +1,11 @@
.. _4-hbac:
Unit 4: Host-based access control (HBAC)
==========================================
**Prerequisites:**
- `Unit 3: User management and Kerberos authentication <3-user-management.rst>`_
- :ref:`Unit 3: User management and Kerberos authentication <3-user-management>`
FreeIPA's *host-based access control* (HBAC) feature allows you to
define policies that restrict access to hosts or services based on
@@ -142,7 +144,7 @@ Now try ``alice``::
This was the final mandatory unit in the workshop. From here, there
are several optional units you can choose from. You can proceed
directly to
`Unit 5: Web application authentication and authorisation <5-web-app-authnz.rst>`_.
:ref:`Unit 5: Web application authentication and authorisation <5-web-app-authnz>`.
Otherwise,
`return to the curriculum overview <workshop.rst#curriculum-overview>`_
:ref:`return to the curriculum overview <curriculum-overview>`
to see all the options.
+5 -3
View File
@@ -1,10 +1,12 @@
.. _5-web-app-authnz:
Unit 5: Web application authentication and authorisation
==========================================================
**Prerequisites**:
- `Unit 3: User management and Kerberos authentication <3-user-management.rst>`_
- `Unit 4: Host-based access control (HBAC) <4-hbac.rst>`_
- :ref:`Unit 3: User management and Kerberos authentication <3-user-management>`
- :ref:`Unit 4: Host-based access control (HBAC) <4-hbac>`
You can configure many kinds of applications to rely on FreeIPA's
centralised authentication, including web applications. In this
@@ -309,4 +311,4 @@ authenticated as ``bob`` instead?
This unit is now concluded. Now that you have mastered web app
authentication, you'll want to configure TLS for your site. Proceed
to
`Unit 6: Service certificates <6-cert-management.rst>`_.
:ref:`Unit 6: Service certificates <6-cert-management>`.
+5 -3
View File
@@ -1,3 +1,5 @@
.. _6-cert-management:
Unit 6: Service certificates
================================
@@ -126,9 +128,9 @@ Restart Apache and make a request to the app over HTTPS::
You can now proceed to
`Unit 7: Replica installation <7-replica-install.rst>`_
:ref:`Unit 7: Replica installation <7-replica-install>`
or
`Unit 8: Sudo rule management <8-sudorule.rst>`_.
:ref:`Unit 8: Sudo rule management <8-sudorule>`.
Otherwise,
`return to the curriculum overview <workshop.rst#curriculum-overview>`_
:ref:`return to the curriculum overview <curriculum-overview>`
to see all the options.
+6 -4
View File
@@ -1,9 +1,11 @@
.. _7-replica-install:
Unit 7: Replica installation
==============================
**Prerequisites**:
- `Unit 1: Installing the FreeIPA server <1-server-install.rst>`_
- :ref:`Unit 1: Installing the FreeIPA server <1-server-install>`
FreeIPA is designed to be run in a replicated multi-master
environment. In this unit, we will install a replica of the
@@ -19,7 +21,7 @@ Client installation
The first step of replica creation is to enrol the machine that will
become the replica. SSH to the ``replica`` VM and enrol it per
`Unit 2: Enrolling client machines <2-client-install.rst>`_
:ref:`Unit 2: Enrolling client machines <2-client-install>`
Replica promotion
-----------------
@@ -56,7 +58,7 @@ After ``ipa-replica-install`` finishes, the replica is operational.
LDAP changes on any server will be replicated to all other servers.
You can proceed to
`Unit 8: Sudo rule management <8-sudorule.rst>`_
:ref:`Unit 8: Sudo rule management <8-sudorule>`
or
`return to the curriculum overview <workshop.rst#curriculum-overview>`_
:ref:`return to the curriculum overview <curriculum-overview>`
to see all the available topics.
+5 -3
View File
@@ -1,10 +1,12 @@
.. _8-sudorule:
Unit 8: Sudo rule management
============================
**Prerequisites**:
- `Unit 3: User management and Kerberos authentication <3-user-management.rst>`_
- `Unit 4: Host-based access control (HBAC) <4-hbac.rst>`_
- :ref:`Unit 3: User management and Kerberos authentication <3-user-management>`
- :ref:`Unit 4: Host-based access control (HBAC) <4-hbac>`
Sudo is a program that allows users to run programs as another user
with different privileges (possibly ``root``). Sudo rules provide
@@ -241,4 +243,4 @@ restart (or start) Apache, but not run other commands via ``sudo``::
This concludes the unit. Now that you have Sudo rules working,
proceed to `Unit 9: SELinux User Maps <9-selinux-user-map.rst>`_.
proceed to :ref:`Unit 9: SELinux User Maps <9-selinux-user-map>`.
+8 -6
View File
@@ -1,11 +1,13 @@
.. _9-selinux-user-map:
Unit 9: SELinux User Maps
=========================
**Prerequisites**:
- `Unit 3: User management and Kerberos authentication <3-user-management.rst>`_
- `Unit 4: Host-based access control (HBAC) <4-hbac.rst>`_
- `Unit 8: Sudo rule management <8-sudorule.rst>`_
- :ref:`Unit 3: User management and Kerberos authentication <3-user-management>`
- :ref:`Unit 4: Host-based access control (HBAC) <4-hbac>`
- :ref:`Unit 8: Sudo rule management <8-sudorule>`
SELinux is a *mandatory access controls* mechanism for Linux,
providing more powerful and flexible access control than traditional
@@ -43,7 +45,7 @@ will automatically be used.
Recall that members of the ``sysadmin`` User Group already have
access to ``webservers`` via the ``sysadmin_webservers`` rule that
was created in `Unit 4: Host-based access control (HBAC)`_. Create
was created in :ref:`Unit 4: Host-based access control (HBAC)<4-hbac>`. Create
the SELinux User Map::
[client]$ ipa selinuxusermap-add sysadmin_staff_t \
@@ -135,7 +137,7 @@ the program being run::
Hello, world!
This concludes the unit. You can now proceed to
`Unit 10: SSH user and host key management <10-ssh-key-management.rst>`_
:ref:`Unit 10: SSH user and host key management <10-ssh-key-management>`
or
`return to the curriculum overview <workshop.rst#curriculum-overview>`_
:ref:`return to the curriculum overview <curriculum-overview>`
to see all the available topics.
+2
View File
@@ -1,3 +1,5 @@
.. _building:
Building Vagrant box images
===========================
+1 -1
View File
@@ -30,6 +30,6 @@ Example: https://goo.gl/forms/UOkcsVROqV
Vagrant boxes
-------------
See ``building.rst`` for instructions on building Vagrant boxes.
See :ref:`building` for instructions on building Vagrant boxes.
At time of writing, the ``freeipa/freeipa-workshop`` box is
FreeIPA 4.9.3 / Fedora 34, for the VirtualBox and libvirt providers.
+16 -14
View File
@@ -1,4 +1,5 @@
..
.. _workshop:
Copyright 2015, 2016 Red Hat, Inc.
This work is licensed under the Creative Commons Attribution 4.0
@@ -18,27 +19,28 @@ X.509 certificates for services.
.. _FreeIPA: http://www.freeipa.org/page/Main_Page
.. _curriculum-overview:
Curriculum overview
-------------------
Mandatory:
- `Unit 1: Installing the FreeIPA server <1-server-install.rst>`_
- `Unit 2: Enrolling client machines <2-client-install.rst>`_
- `Unit 3: User management and Kerberos authentication <3-user-management.rst>`_
- `Unit 4: Host-based access control (HBAC) <4-hbac.rst>`_
- :ref:`Unit 1: Installing the FreeIPA server <1-server-install>`
- :ref:`Unit 2: Enrolling client machines <2-client-install>`
- :ref:`Unit 3: User management and Kerberos authentication <3-user-management>`
- :ref:`Unit 4: Host-based access control (HBAC) <4-hbac>`
Optional units—choose the topics that are relevant to you:
- `Unit 5: Web application authentication and authorisation <5-web-app-authnz.rst>`_
- `Unit 6: Service certificates <6-cert-management.rst>`_
- `Unit 7: Replica installation <7-replica-install.rst>`_
- `Unit 8: Sudo rule management <8-sudorule.rst>`_
- `Unit 9: SELinux User Maps <9-selinux-user-map.rst>`_
- `Unit 10: SSH user and host key management <10-ssh-key-management.rst>`_
- `Unit 11: Kerberos ticket policy <11-kerberos-ticket-policy.rst>`_
- `Unit 12: External IdP support <12-external-idp-support.rst>`_
- :ref:`Unit 5: Web application authentication and authorisation <5-web-app-authnz>`
- :ref:`Unit 6: Service certificates <6-cert-management>`
- :ref:`Unit 7: Replica installation <7-replica-install>`
- :ref:`Unit 8: Sudo rule management <8-sudorule>`
- :ref:`Unit 9: SELinux User Maps <9-selinux-user-map>`
- :ref:`Unit 10: SSH user and host key management <10-ssh-key-management>`
- :ref:`Unit 11: Kerberos ticket policy <11-kerberos-ticket-policy>`
- :ref:`Unit 12: External IdP support <12-external-idp-support>`
Editing files on VMs
--------------------
@@ -241,7 +243,7 @@ Next step
---------
You are ready to begin the workshop. Continue to
`Unit 1: Installing the FreeIPA server <1-server-install.rst>`_.
:ref:`Unit 1: Installing the FreeIPA server <1-server-install>`.
After the workshop
+139 -15
View File
@@ -78,8 +78,8 @@
%global ds_version 1.4.3.16-12
%global selinux_policy_version 3.14.3-107
%else
# DNA interval enabled
%global ds_version 2.0.5-1
# version supporting LMDB and lib389.cli_ctl.dblib.run_dbscan utility
%global ds_version 2.1.0
%global selinux_policy_version 38.1.1-1
%endif
@@ -124,10 +124,11 @@
# Make sure to use 389-ds-base versions that fix https://github.com/389ds/389-ds-base/issues/4700
# and has DNA interval enabled
# version supporting LMDB and lib389.cli_ctl.dblib.run_dbscan utility
%if 0%{?fedora} < 34
%global ds_version 1.4.4.16-1
%else
%global ds_version 2.0.7-1
%global ds_version 2.1.0
%endif
# Fix for TLS 1.3 PHA, RHBZ#1775146
@@ -173,7 +174,7 @@
%endif
# RHEL 8.3+, F32+ has 0.79.13
%global certmonger_version 0.79.7-3
%global certmonger_version 0.79.17-1
# RHEL 8.2+, F32+ has 3.58
%global nss_version 3.44.0-4
@@ -289,6 +290,7 @@ BuildRequires: gettext
BuildRequires: gettext-devel
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: python3-argcomplete
BuildRequires: systemd >= %{systemd_version}
# systemd-tmpfiles which is executed from make install requires apache user
BuildRequires: httpd
@@ -306,9 +308,12 @@ BuildRequires: libpwquality-devel
BuildRequires: libsss_idmap-devel
BuildRequires: libsss_certmap-devel
BuildRequires: libsss_nss_idmap-devel >= %{sssd_version}
%if 0%{?fedora} >= 39 || 0%{?rhel} >= 10
%if 0%{?fedora} >= 41
# Do not use nodejs22 on fedora < 41, https://pagure.io/freeipa/issue/9643
BuildRequires: nodejs(abi)
%elif 0%{?fedora} >= 39 || 0%{?rhel} >= 10
# Do not use nodejs20 on fedora < 39, https://pagure.io/freeipa/issue/9374
BuildRequires: nodejs(abi)
BuildRequires: nodejs(abi) < 127
%else
BuildRequires: nodejs(abi) < 111
%endif
@@ -401,7 +406,7 @@ BuildRequires: python3-libipa_hbac
BuildRequires: python3-libsss_nss_idmap
BuildRequires: python3-lxml
BuildRequires: python3-netaddr >= %{python_netaddr_version}
BuildRequires: python3-netifaces
BuildRequires: python3-ifaddr
BuildRequires: python3-pki >= %{pki_version}
BuildRequires: python3-polib
BuildRequires: python3-pyasn1
@@ -714,7 +719,7 @@ Requires: oddjob-mkhomedir
Requires: libsss_autofs
Requires: autofs
Requires: libnfsidmap
Requires: nfs-utils
Requires: (nfs-utils or nfsv4-client-utils)
Requires: sssd-tools >= %{sssd_version}
Requires(post): policycoreutils
@@ -873,6 +878,7 @@ Requires: %{name}-common = %{version}-%{release}
Requires(pre): python3-ldap >= %{python_ldap_version}
Requires: gnupg2
Requires: keyutils
Requires: python3-argcomplete
Requires: python3-cffi
Requires: python3-cryptography >= 1.6
Requires: python3-dateutil
@@ -882,7 +888,7 @@ Requires: python3-gssapi >= 1.2.0
Requires: python3-jwcrypto >= 0.4.2
Requires: python3-libipa_hbac
Requires: python3-netaddr >= %{python_netaddr_version}
Requires: python3-netifaces >= 0.10.4
Requires: python3-ifaddr
Requires: python3-pyasn1 >= 0.3.2-2
Requires: python3-pyasn1-modules >= 0.3.2-2
Requires: python3-pyusb
@@ -902,6 +908,7 @@ Requires: python3-urllib3 >= 1.24.2-3
# For urllib3.util.ssl_match_hostname
Requires: python3-urllib3 >= 1.25.8
%endif
Requires: python3-systemd
%description -n python3-ipalib
IPA is an integrated solution to provide centrally managed Identity (users,
@@ -993,6 +1000,26 @@ Requires(post): selinux-policy-%{selinuxtype}
%description selinux
Custom SELinux policy module for FreeIPA
%package selinux-nfast
Summary: FreeIPA SELinux policy for nCipher nfast HSMs
BuildArch: noarch
Requires: selinux-policy-%{selinuxtype}
Requires(post): selinux-policy-%{selinuxtype}
%{?selinux_requires}
%description selinux-nfast
Custom SELinux policy module for nCipher nfast HSMs
%package selinux-luna
Summary: FreeIPA SELinux policy for Thales Luna HSMs
BuildArch: noarch
Requires: selinux-policy-%{selinuxtype}
Requires(post): selinux-policy-%{selinuxtype}
%{?selinux_requires}
%description selinux-luna
Custom SELinux policy module for Thales Luna HSMs
# with selinux
%endif
@@ -1079,6 +1106,15 @@ rm -f %{buildroot}%{_usr}/share/ipa/ui/images/product-name.png
%endif
# RHEL spec file only: END
%if 0%{?fedora} >= 38
# Register CLI tools for bash completion (fedora only)
for clitool in ipa-migrate
do
register-python-argcomplete "${clitool}" > "${clitool}"
install -p -m 0644 -D -t '%{buildroot}%{bash_completions_dir}' "${clitool}"
done
%endif
%find_lang %{gettext_domain}
%if ! %{ONLY_CLIENT}
@@ -1142,6 +1178,10 @@ fi
/bin/systemctl reload-or-try-restart oddjobd
%tmpfiles_create ipa.conf
%journal_catalog_update
%postun server
%journal_catalog_update
%posttrans server
# don't execute upgrade and restart of IPA when server is not installed
@@ -1278,13 +1318,23 @@ if [ $1 -gt 1 ] ; then
cp /etc/ipa/ca.crt /var/lib/ipa-client/pki/kdc-ca-bundle.pem
cp /etc/ipa/ca.crt /var/lib/ipa-client/pki/ca-bundle.pem
fi
%{__python3} -c 'from ipaclient.install.client import configure_krb5_snippet; configure_krb5_snippet()' >>/var/log/ipaupgrade.log 2>&1
%{__python3} -c 'from ipaclient.install.client import update_ipa_nssdb; update_ipa_nssdb()' >>/var/log/ipaupgrade.log 2>&1
chmod 0600 /var/log/ipaupgrade.log
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config"
if [ -f "$SSH_CLIENT_SYSTEM_CONF" ]; then
sed -E --in-place=.orig 's/^(HostKeyAlgorithms ssh-rsa,ssh-dss)$/# disabled by ipa-client update\n# \1/' "$SSH_CLIENT_SYSTEM_CONF"
if grep -E -q '^HostKeyAlgorithms ssh-rsa,ssh-dss' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null; then
sed -E --in-place=.orig 's/^(HostKeyAlgorithms ssh-rsa,ssh-dss)$/# disabled by ipa-client update\n# \1/' "$SSH_CLIENT_SYSTEM_CONF"
fi
# https://pagure.io/freeipa/issue/9536
# replace sss_ssh_knownhostsproxy with sss_ssh_knownhosts
if [ -f '/usr/bin/sss_ssh_knownhosts' ]; then
if grep -E -q 'Include' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null ; then
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config.d/04-ipa.conf"
fi
sed -E --in-place=.orig 's/^(GlobalKnownHostsFile \/var\/lib\/sss\/pubconf\/known_hosts)$/# disabled by ipa-client update\n# \1/' $SSH_CLIENT_SYSTEM_CONF
sed -E --in-place=.orig 's/(ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h)/# replaced by ipa-client update\n KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H/' $SSH_CLIENT_SYSTEM_CONF
fi
fi
fi
fi
@@ -1300,17 +1350,76 @@ fi
semodule -d ipa_custodia &> /dev/null || true;
%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.bz2
%post selinux-nfast
%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-nfast.pp.bz2
%post selinux-luna
%selinux_modules_install -s %{selinuxtype} %{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-luna.pp.bz2
%postun selinux
if [ $1 -eq 0 ]; then
%selinux_modules_uninstall -s %{selinuxtype} %{modulename}
semodule -e ipa_custodia &> /dev/null || true;
fi
%postun selinux-nfast
if [ $1 -eq 0 ]; then
%selinux_modules_uninstall -s %{selinuxtype} %{modulename}-nfast
fi
%postun selinux-luna
if [ $1 -eq 0 ]; then
%selinux_modules_uninstall -s %{selinuxtype} %{modulename}-luna
fi
%posttrans selinux
%selinux_relabel_post -s %{selinuxtype}
# with_selinux
%endif
%triggerin client -- sssd-common < 2.10
# Has the client been configured?
restore=0
test -f '/var/lib/ipa-client/sysrestore/sysrestore.index' && restore=$(wc -l '/var/lib/ipa-client/sysrestore/sysrestore.index' | awk '{print $1}')
if [ -f '/etc/ssh/sshd_config' -a $restore -ge 2 ]; then
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config"
if [ -f "$SSH_CLIENT_SYSTEM_CONF" ]; then
# https://pagure.io/freeipa/issue/9536
# downgrade sss_ssh_knownhosts with sss_ssh_knownhostsproxy
if [ -f '/usr/bin/sss_ssh_knownhosts' ]; then
if grep -E -q 'Include' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null ; then
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config.d/04-ipa.conf"
fi
GLOBALKNOWNHOSTFILE="GlobalKnownHostsFile /var/lib/sss/pubconf/known_hosts/"
grep -qF '$GLOBALKNOWNHOSTFILE' $SSH_CLIENT_SYSTEM_CONF
if [ $? -ne 0 ]; then
sed -E --in-place=.orig '/(# IPA-related configuration changes to ssh_config)/a # added by ipa-client update\n'"$GLOBALKNOWNHOSTFILE"'' $SSH_CLIENT_SYSTEM_CONF
fi
sed -E --in-place=.orig 's/(KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H)/ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h/' $SSH_CLIENT_SYSTEM_CONF
fi
fi
fi
%triggerin client -- sssd-common >= 2.10
# Has the client been configured?
restore=0
test -f '/var/lib/ipa-client/sysrestore/sysrestore.index' && restore=$(wc -l '/var/lib/ipa-client/sysrestore/sysrestore.index' | awk '{print $1}')
if [ -f '/etc/ssh/sshd_config' -a $restore -ge 2 ]; then
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config"
if [ -f "$SSH_CLIENT_SYSTEM_CONF" ]; then
# https://pagure.io/freeipa/issue/9536
# upgrade sss_ssh_knownhostsproxy with sss_ssh_knownhosts
if [ -f '/usr/bin/sss_ssh_knownhosts' ]; then
if grep -E -q 'Include' $SSH_CLIENT_SYSTEM_CONF 2>/dev/null ; then
SSH_CLIENT_SYSTEM_CONF="/etc/ssh/ssh_config.d/04-ipa.conf"
fi
sed -E --in-place=.orig 's/^(GlobalKnownHostsFile \/var\/lib\/sss\/pubconf\/known_hosts)$/# disabled by ipa-client update\n# \1/' $SSH_CLIENT_SYSTEM_CONF
sed -E --in-place=.orig 's/(ProxyCommand \/usr\/bin\/sss_ssh_knownhostsproxy -p \%p \%h)/# replaced by ipa-client update\n KnownHostsCommand \/usr\/bin\/sss_ssh_knownhosts \%H/' $SSH_CLIENT_SYSTEM_CONF
fi
fi
fi
%triggerin client -- openssh-server < 8.2
# Has the client been configured?
@@ -1409,6 +1518,10 @@ fi
%{_sbindir}/ipa-crlgen-manage
%{_sbindir}/ipa-cert-fix
%{_sbindir}/ipa-acme-manage
%{_sbindir}/ipa-migrate
%if 0%{?fedora} >= 38
%{bash_completions_dir}/ipa-migrate
%endif
%{_libexecdir}/certmonger/dogtag-ipa-ca-renew-agent-submit
%{_libexecdir}/certmonger/ipa-server-guard
%dir %{_libexecdir}/ipa
@@ -1441,6 +1554,7 @@ fi
%attr(644,root,root) %{_unitdir}/ipa-otpd@.service
%attr(644,root,root) %{_unitdir}/ipa-ccache-sweep.service
%attr(644,root,root) %{_unitdir}/ipa-ccache-sweep.timer
%attr(644,root,root) %{_journalcatalogdir}/ipa.catalog
# END
%attr(755,root,root) %{plugin_dir}/libipa_pwd_extop.so
%attr(755,root,root) %{plugin_dir}/libipa_enrollment_extop.so
@@ -1483,6 +1597,7 @@ fi
%{_mandir}/man1/ipa-crlgen-manage.1*
%{_mandir}/man1/ipa-cert-fix.1*
%{_mandir}/man1/ipa-acme-manage.1*
%{_mandir}/man1/ipa-migrate.1*
%files -n python3-ipaserver
@@ -1555,10 +1670,11 @@ fi
%dir %{_sysconfdir}/ipa/html
%config(noreplace) %{_sysconfdir}/ipa/html/ssbrowser.html
%config(noreplace) %{_sysconfdir}/ipa/html/unauthorized.html
%ghost %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/httpd/conf.d/ipa-rewrite.conf
%ghost %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/httpd/conf.d/ipa.conf
%ghost %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/httpd/conf.d/ipa-kdc-proxy.conf
%ghost %attr(0640,root,root) %config(noreplace) %{_sysconfdir}/httpd/conf.d/ipa-pki-proxy.conf
%dir %{_sysconfdir}/ipa/http
%ghost %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ipa/httpd/ipa-rewrite.conf
%ghost %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ipa/httpd/ipa.conf
%ghost %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ipa/httpd/ipa-kdc-proxy.conf
%ghost %attr(0640,root,root) %config(noreplace) %{_sysconfdir}/ipa/httpd/ipa-pki-proxy.conf
%ghost %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ipa/kdcproxy/ipa-kdc-proxy.conf
%ghost %attr(0644,root,root) %config(noreplace) %{_usr}/share/ipa/html/ca.crt
%ghost %attr(0640,root,named) %config(noreplace) %{_sysconfdir}/named/ipa-ext.conf
@@ -1757,6 +1873,14 @@ fi
%files selinux
%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}.pp.*
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}
%files selinux-nfast
%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-nfast.pp.*
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}-nfast
%files selinux-luna
%{_datadir}/selinux/packages/%{selinuxtype}/%{modulename}-luna.pp.*
%ghost %verify(not md5 size mode mtime) %{_sharedstatedir}/selinux/%{selinuxtype}/active/modules/200/%{modulename}-luna
# with selinux
%endif
+4
View File
@@ -18,6 +18,10 @@ systemdsystemunit_DATA = \
ipa-ccache-sweep.timer \
$(NULL)
dist_systemdcatalog_DATA = \
ipa.catalog \
$(NULL)
CLEANFILES = $(systemdsystemunit_DATA)
%: %.in Makefile
+58
View File
@@ -0,0 +1,58 @@
#
#
#
-- 6d70f1b493df36478bc3499257cd3b17
Subject: IPA API command was executed and result of its execution was audited
Defined-by: FreeIPA
Support: https://lists.fedorahosted.org/archives/list/freeipa-users@lists.fedorahosted.org/
Documentation: man:ipa(1)
Documentation: https://freeipa.readthedocs.io/en/latest/api/index.html
Documentation: https://freeipa.readthedocs.io/en/latest/api/@IPA_API_COMMAND@.html
FreeIPA provides an extensive API that allows to manage all aspects of IPA deployments.
The following information about the API command executed is available:
@MESSAGE@
The command was executed by '@SYSLOG_IDENTIFIER@' utility. If the utility name
is '/mod_wsgi`, then this API command came from a remote source through the IPA
API end-point.
The message includes following fields:
- executable name and PID ('/mod_wsgi' for HTTP end-point; in this case it
was '@SYSLOG_IDENTIFIER@' command)
- '[IPA.API]' marker to allow searches with 'journalctl -g IPA.API'
- authenticated Kerberos principal or '[autobind]' marker for LDAPI-based
access as root. In this case it was '@IPA_API_ACTOR@'
- name of the command executed, in this case '@IPA_API_COMMAND@'
- result of execution: `SUCCESS` or an exception name. In this case it was
'@IPA_API_RESULT@'
- LDAP backend instance identifier. The identifier will be the same for all
operations performed under the same request. This allows to identify operations
which were executed as a part of the same API request instance. For API
operations that didn't result in LDAP access, there will be
'[no_connection_id]' marker.
- finally, a list of arguments and options passed to the command is provided
in JSON format.
---------
The following list of arguments and options were passed to the command
'@IPA_API_COMMAND@' by the '@IPA_API_ACTOR@' actor:
@IPA_API_PARAMS@
---------
A detailed information about FreeIPA API can be found at upstream documentation API reference:
https://freeipa.readthedocs.io/en/latest/api/index.html
For details on the IPA API command '@IPA_API_COMMAND@' see
https://freeipa.readthedocs.io/en/latest/api/@IPA_API_COMMAND@.html
@@ -42,7 +42,7 @@ import six
from ipalib.install.kinit import kinit_keytab
from ipapython import ipautil
from ipapython.dn import DN
from ipalib import api, errors, x509
from ipalib import api, errors, x509, sysrestore
from ipaplatform.paths import paths
from ipaserver.plugins.ldap2 import ldap2
from ipaserver.install import ca, cainstance, dsinstance, certs
@@ -383,7 +383,20 @@ def retrieve_cert_continuous(reuse_existing, **kwargs):
return result
new_cert = x509.load_pem_x509_certificate(result[1].encode('ascii'))
nickname = get_nickname()
if new_cert == old_cert:
sstore = sysrestore.StateFile(paths.SYSRESTORE)
if (
sstore.get_state('pki_hsm', 'enabled')
and sstore.get_state('pki_hsm', 'token_name')
and nickname != 'ipaCert'
):
# HSMs must be networked so the cert is already present
# exception of the RA Agent certificate.
return (
ISSUED,
new_cert.public_bytes(x509.Encoding.PEM).decode("ascii"),
)
syslog.syslog(syslog.LOG_INFO, "Updated certificate not available")
# No cert available yet, tell certmonger to wait another 8 hours
return (WAIT_WITH_DELAY, 8 * 60 * 60, '')
@@ -15,6 +15,7 @@ import six
import gssapi
from ipalib.install.kinit import kinit_keytab, kinit_password
from ipapython.admintool import admin_cleanup_global_argv
if six.PY3:
unicode = str
@@ -52,11 +53,13 @@ def parse_options():
"--password",
action="store",
dest="password",
help="Display debugging information",
help="Password for Active Directory administrator",
sensitive=True
)
options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
admin_cleanup_global_argv(parser, options, sys.argv)
# We only use first argument of the passed args but as D-BUS interface
# in oddjobd cannot expose optional, we fill in empty slots from IPA side
+11 -22
View File
@@ -28,7 +28,6 @@ import shutil
import traceback
from ipalib.install import certstore
from ipapython import directivesetter
from ipapython import ipautil
from ipalib import api, errors
from ipalib import x509
@@ -37,7 +36,7 @@ from ipaserver.install import certs, cainstance
from ipaserver.plugins.ldap2 import ldap2
from ipaplatform import services
from ipaplatform.paths import paths
from ipapython.certdb import TrustFlags
from ipapython.certdb import TrustFlags, get_ca_nickname
def _main():
@@ -50,6 +49,8 @@ def _main():
dogtag_service = services.knownservices['pki_tomcatd']
ca = cainstance.CAInstance(host_name=api.env.host)
# dogtag opens its NSS database in read/write mode so we need it
# shut down so certmonger can open it read/write mode. This avoids
# database corruption. It should already be stopped by the pre-command
@@ -83,13 +84,15 @@ def _main():
api.Backend.ldap2.connect()
ca = cainstance.CAInstance(host_name=api.env.host)
ca.update_cert_config(nickname, cert)
if ca.is_renewal_master():
cainstance.update_people_entry(cert)
cainstance.update_authority_entry(cert)
if nickname == 'auditSigningCert cert-pki-ca':
if nickname in (
'auditSigningCert cert-pki-ca',
'auditSigningCert cert-pki-kra',
):
# Fix trust on the audit cert
try:
db.run_certutil(['-M',
@@ -105,26 +108,9 @@ def _main():
"Updating trust on certificate %s failed in %s" %
(nickname, db.secdir))
elif nickname == 'caSigningCert cert-pki-ca':
# Update CS.cfg
cfg_path = paths.CA_CS_CFG_PATH
config = directivesetter.get_directive(
cfg_path, 'subsystem.select', '=')
if config == 'New':
syslog.syslog(syslog.LOG_NOTICE, "Updating CS.cfg")
if cert.is_self_signed():
directivesetter.set_directive(
cfg_path, 'hierarchy.select', 'Root',
quotes=False, separator='=')
else:
directivesetter.set_directive(
cfg_path, 'hierarchy.select', 'Subordinate',
quotes=False, separator='=')
else:
syslog.syslog(syslog.LOG_NOTICE, "Not updating CS.cfg")
# Remove old external CA certificates
for ca_nick, ca_flags in db.list_certs():
if ca_flags.has_key:
if ca_flags.has_key or not ca_flags.ca:
continue
# Delete *all* certificates that use the nickname
while True:
@@ -168,8 +154,11 @@ def _main():
"%s" % e)
ca_certs = []
realm_nickname = get_ca_nickname(api.env.realm)
for ca_cert, ca_nick, ca_flags in ca_certs:
try:
if ca_nick == realm_nickname:
ca_nick = 'caSigningCert cert-pki-ca'
db.add_cert(ca_cert, ca_nick, ca_flags)
except ipautil.CalledProcessError as e:
syslog.syslog(
+2 -1
View File
@@ -8,6 +8,7 @@ attributeTypes: (2.16.840.1.113730.3.8.21.1.6 NAME 'ipaCaId' DESC 'Dogtag Author
attributeTypes: (2.16.840.1.113730.3.8.21.1.7 NAME 'ipaCaIssuerDN' DESC 'Issuer DN' SUP distinguishedName X-ORIGIN 'IPA v4.4 Lightweight CAs' )
attributeTypes: (2.16.840.1.113730.3.8.21.1.8 NAME 'ipaCaSubjectDN' DESC 'Subject DN' SUP distinguishedName X-ORIGIN 'IPA v4.4 Lightweight CAs' )
attributeTypes: (2.16.840.1.113730.3.8.21.1.9 NAME 'ipaCaRandomSerialNumberVersion' DESC 'Random Serial Number Version' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'IPA v4.9 RSNv3' )
attributeTypes: (2.16.840.1.113730.3.8.21.1.10 NAME 'ipaCaHSMConfiguration' DESC 'HSM Configuration' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v4.10 HSM' )
objectClasses: (2.16.840.1.113730.3.8.21.2.1 NAME 'ipaCertProfile' SUP top STRUCTURAL MUST ( cn $ description $ ipaCertProfileStoreIssued ) X-ORIGIN 'IPA v4.2' )
objectClasses: (2.16.840.1.113730.3.8.21.2.2 NAME 'ipaCaAcl' SUP ipaAssociation STRUCTURAL MUST cn MAY ( ipaCaCategory $ ipaCertProfileCategory $ userCategory $ hostCategory $ serviceCategory $ ipaMemberCa $ ipaMemberCertProfile $ memberService ) X-ORIGIN 'IPA v4.2' )
objectClasses: (2.16.840.1.113730.3.8.21.2.3 NAME 'ipaCa' SUP top STRUCTURAL MUST ( cn $ ipaCaId $ ipaCaSubjectDN $ ipaCaIssuerDN ) MAY ( description $ ipaCaRandomSerialNumberVersion ) X-ORIGIN 'IPA v4.4 Lightweight CAs' )
objectClasses: (2.16.840.1.113730.3.8.21.2.3 NAME 'ipaCa' SUP top STRUCTURAL MUST ( cn $ ipaCaId $ ipaCaSubjectDN $ ipaCaIssuerDN ) MAY ( description $ ipaCaRandomSerialNumberVersion $ ipaCaHSMConfiguration) X-ORIGIN 'IPA v4.4 Lightweight CAs' )
+1 -1
View File
@@ -38,7 +38,6 @@ dist_app_DATA = \
default-trust-view.ldif \
delegation.ldif \
replica-acis.ldif \
replica-prevent-time-skew.ldif \
ds-nfiles.ldif \
ds-ipa-env.conf.template \
dns.ldif \
@@ -101,6 +100,7 @@ dist_app_DATA = \
ipa-kdc-proxy.conf.template \
ipa-pki-proxy.conf.template \
ipa-rewrite.conf.template \
ipa-vhost.conf.template \
ipaca_default.ini \
ipaca_customize.ini \
ipaca_softhsm2.ini \
+1
View File
@@ -239,6 +239,7 @@ objectClass: ipasshuser
uid: admin
krbPrincipalName: admin@$REALM
krbPrincipalName: root@$REALM
krbCanonicalName: admin@$REALM
cn: Administrator
sn: Administrator
uidNumber: $IDSTART
+50
View File
@@ -0,0 +1,50 @@
#
# VERSION 32 - DO NOT REMOVE THIS LINE
#
# This file may be overwritten on upgrades.
#
# FIXME: WSGISocketPrefix is a server-scope directive. The mod_wsgi package
# should really be fixed by adding this its /etc/httpd/conf.d/wsgi.conf:
WSGISocketPrefix $WSGI_PREFIX_DIR
# Configure mod_wsgi handler for /ipa
WSGIDaemonProcess ipa processes=$WSGI_PROCESSES threads=1 maximum-requests=500 \
user=ipaapi group=ipaapi display-name=%{GROUP} socket-timeout=2147483647 \
lang=C.UTF-8 locale=C.UTF-8
<VirtualHost *:80>
ServerName $FQDN
ServerAlias ipa-ca.$DOMAIN
# Logging
CustomLog /var/log/httpd/ipa-access.log combined
ErrorLog /var/log/httpd/ipa-error.log
IncludeOptional $HTTPD_IPA_PKI_PROXY_CONF
Include $HTTPD_IPA_REWRITE_CONF
Include $HTTPD_IPA_CONF
</VirtualHost>
# the below section is only need if you have above 3 lines and want SSL
<VirtualHost *:443>
ServerName $FQDN
ServerAlias ipa-ca.$DOMAIN
# Logging
CustomLog /var/log/httpd/ipa-access.log combined
ErrorLog /var/log/httpd/ipa-error.log
# SSL
SSLEngine on
SSLCertificateFile $HTTPD_CERT_FILE
SSLCertificateKeyFile $HTTPD_KEY_FILE
SSLCACertificateFile $IPA_CA_CRT
SSLVerifyDepth $MOD_SSL_VERIFY_DEPTH
# FreeIPA
IncludeOptional $HTTPD_IPA_KDCPROXY_CONF_SYMLINK
IncludeOptional $HTTPD_IPA_PKI_PROXY_CONF
Include $HTTPD_IPA_REWRITE_CONF
Include $HTTPD_IPA_CONF
</VirtualHost>
-8
View File
@@ -35,19 +35,11 @@ AddOutputFilterByType DEFLATE text/html text/plain text/xml \
application/javascript application/json text/css \
application/x-font-ttf
# FIXME: WSGISocketPrefix is a server-scope directive. The mod_wsgi package
# should really be fixed by adding this its /etc/httpd/conf.d/wsgi.conf:
WSGISocketPrefix $WSGI_PREFIX_DIR
# Configure mod_wsgi handler for /ipa
WSGIDaemonProcess ipa processes=$WSGI_PROCESSES threads=1 maximum-requests=500 \
user=ipaapi group=ipaapi display-name=%{GROUP} socket-timeout=2147483647 \
lang=C.UTF-8 locale=C.UTF-8
WSGIScriptAlias /ipa /usr/share/ipa/wsgi.py process-group=ipa \
application-group=%{GLOBAL}
WSGIScriptReloading Off
# Turn off mod_msgi handler for errors, config, crl:
<Location "/ipa/errors">
SetHandler None
+3 -2
View File
@@ -87,8 +87,6 @@ pki_sslserver_subject_dn=cn=%(ipa_fqdn)s,%(ipa_subject_base)s
pki_subsystem_nickname=subsystemCert cert-pki-ca
pki_subsystem_subject_dn=cn=CA Subsystem,%(ipa_subject_base)s
pki_theme_enable=True
pki_theme_server_dir=/usr/share/pki/common-ui
pki_audit_group=pkiaudit
pki_group=pkiuser
pki_user=pkiuser
@@ -166,3 +164,6 @@ pki_audit_signing_subject_dn=cn=KRA Audit,%(ipa_subject_base)s
# We will use the dbuser created for the CA.
pki_share_db=True
pki_share_dbuser_dn=uid=pkidbuser,ou=people,o=ipaca
# KRA padding, set RSA-OAEP in FIPS mode
pki_use_oaep_rsa_keywrap=%(fips_use_oaep_rsa_keywrap)s
@@ -1,4 +0,0 @@
dn: cn=config
changetype: modify
replace: nsslapd-ignore-time-skew
nsslapd-ignore-time-skew: $SKEWVALUE
+5 -23
View File
@@ -1,34 +1,16 @@
dn: cn=krbPrincipalName uniqueness,cn=plugins,cn=config
dn: cn=kerberos name uniqueness,cn=plugins,cn=config
changetype: add
objectClass: top
objectClass: nsSlapdPlugin
objectClass: extensibleObject
cn: krbPrincipalName uniqueness
cn: kerberos name uniqueness
nsslapd-pluginPath: libattr-unique-plugin
nsslapd-pluginInitfunc: NSUniqueAttr_Init
nsslapd-pluginType: preoperation
nsslapd-pluginEnabled: on
uniqueness-attribute-name: krbPrincipalName
nsslapd-plugin-depends-on-type: database
nsslapd-pluginId: NSUniqueAttr
nsslapd-pluginVersion: 1.1.0
nsslapd-pluginVendor: Fedora Project
nsslapd-pluginDescription: Enforce unique attribute values
uniqueness-subtrees: $SUFFIX
uniqueness-exclude-subtrees: cn=staged users,cn=accounts,cn=provisioning,$SUFFIX
uniqueness-across-all-subtrees: on
dn: cn=krbCanonicalName uniqueness,cn=plugins,cn=config
changetype: add
objectClass: top
objectClass: nsSlapdPlugin
objectClass: extensibleObject
cn: krbCanonicalName uniqueness
nsslapd-pluginPath: libattr-unique-plugin
nsslapd-pluginInitfunc: NSUniqueAttr_Init
nsslapd-pluginType: preoperation
nsslapd-pluginEnabled: on
uniqueness-attribute-name: krbCanonicalName
uniqueness-attribute-name: krbPrincipalName:CaseIgnoreMatch:
uniqueness-attribute-name: krbPrincipalAlias:CaseIgnoreMatch:
uniqueness-attribute-name: krbCanonicalName:CaseIgnoreMatch:
nsslapd-plugin-depends-on-type: database
nsslapd-pluginId: NSUniqueAttr
nsslapd-pluginVersion: 1.1.0
+2
View File
@@ -39,6 +39,7 @@ dist_noinst_DATA = \
ipa-pki-wait-running.in \
ipa-acme-manage.in \
ipa-subids.in \
ipa-migrate.in \
$(NULL)
nodist_sbin_SCRIPTS = \
@@ -68,6 +69,7 @@ nodist_sbin_SCRIPTS = \
ipa-crlgen-manage \
ipa-cert-fix \
ipa-acme-manage \
ipa-migrate \
$(NULL)
appdir = $(libexecdir)/ipa/
+3 -4
View File
@@ -29,19 +29,17 @@ import sys
import six
from optparse import SUPPRESS_HELP # pylint: disable=deprecated-module
from ipalib.install import sysrestore
from ipaserver.install import adtrust, service
from ipaserver.install.installutils import (
read_password,
check_server_configuration,
run_script)
from ipapython.admintool import ScriptError
from ipapython.admintool import ScriptError, admin_cleanup_global_argv
from ipapython import version
from ipapython import ipautil
from ipalib import api, errors, krb_utils
from ipapython.config import IPAOptionParser
from ipapython.config import IPAOptionParser, SUPPRESS_HELP
from ipaplatform.paths import paths
from ipapython.ipa_log_manager import standard_logging_setup
@@ -95,6 +93,7 @@ def parse_options():
options, _args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
admin_cleanup_global_argv(parser, options, sys.argv)
return safe_options, options
+24
View File
@@ -42,6 +42,7 @@ from ipalib.constants import DOMAIN_LEVEL_1
from ipapython.config import IPAOptionParser
from ipapython.ipa_log_manager import standard_logging_setup
from ipaplatform.paths import paths
from ipapython.admintool import admin_cleanup_global_argv
logger = logging.getLogger(os.path.basename(__file__))
@@ -101,6 +102,26 @@ def parse_options():
"The CA certificate subject DN "
"(default CN=Certificate Authority,O=<realm-name>). "
"RDNs are in LDAP order (most specific RDN first)."))
parser.add_option("--token-name", dest="token_name",
default=None,
help=(
"The PKCS#11 token name if using an HSM to store "
"and generate private keys."))
parser.add_option("--token-library-path", dest="token_library_path",
default=None,
help=(
"The full path to the PKCS#11 shared library "
"needed to access the HSM device."))
parser.add_option("--token-password", dest="token_password",
default=None,
sensitive=True,
help=(
"The PKCS#11 token password for the HSM."))
parser.add_option("--token-password-file", dest="token_password_file",
default=None,
help=(
"The full path to a file containing the PKCS#11 "
" token password."))
parser.add_option("--pki-config-override", dest="pki_config_override",
default=None,
@@ -112,6 +133,7 @@ def parse_options():
options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
admin_cleanup_global_argv(parser, options, sys.argv)
if args:
parser.error("Too many arguments provided")
@@ -166,7 +188,9 @@ def install_replica(safe_options, options):
# Run ipa-certupdate to ensure we have the CA cert. This is
# necessary if the admin has just promoted the topology from
# CA-less to CA-ful, and ipa-certupdate has not been run yet.
print("Running ipa-certupdate...", end="", flush=True)
ipa_certupdate.run_with_args(api)
print("done")
# CertUpdate restarts DS causing broken pipe on the original
# connection, so reconnect the backend.
+4 -2
View File
@@ -24,13 +24,13 @@ from __future__ import print_function
import sys
from ipaplatform.paths import paths
try:
from optparse import OptionParser # pylint: disable=deprecated-module
from ipapython import ipautil, config
from ipaserver.install import installutils
from ipaserver.install.ldapupdate import LDAPUpdate
from ipalib import api, errors
from ipapython.ipa_log_manager import standard_logging_setup
from ipapython.dn import DN
from ipapython.admintool import admin_cleanup_global_argv
except ImportError as e:
print("""\
There was a problem importing one of the required Python modules. The
@@ -46,7 +46,8 @@ nis_config_dn = DN(('cn', 'NIS Server'), ('cn', 'plugins'), ('cn', 'config'))
def parse_options():
usage = "%prog [options] <enable|disable|status>\n"
usage += "%prog [options]\n"
parser = OptionParser(usage=usage, formatter=config.IPAFormatter())
parser = config.IPAOptionParser(usage=usage,
formatter=config.IPAFormatter())
parser.add_option("-d", "--debug", action="store_true", dest="debug",
help="Display debugging information about the update(s)")
@@ -55,6 +56,7 @@ def parse_options():
config.add_standard_options(parser)
options, args = parser.parse_args()
admin_cleanup_global_argv(parser, options, sys.argv)
return options, args
+6 -6
View File
@@ -32,8 +32,8 @@ from ipaserver.install import (replication, installutils, bindinstance,
from ipalib import api, errors
from ipalib.constants import FQDN
from ipalib.util import has_managed_topology, print_replication_status
from ipapython import ipautil, ipaldap, version
from ipapython.admintool import ScriptError
from ipapython import ipautil, ipaldap, version, config
from ipapython.admintool import admin_cleanup_global_argv, ScriptError
from ipapython.dn import DN
logger = logging.getLogger(os.path.basename(__file__))
@@ -54,11 +54,10 @@ commands = {
def parse_options():
from optparse import OptionParser # pylint: disable=deprecated-module
parser = OptionParser(version=version.VERSION)
parser = config.IPAOptionParser(version=version.VERSION)
parser.add_option("-H", "--host", dest="host", help="starting host")
parser.add_option("-p", "--password", dest="dirman_passwd", help="Directory Manager password")
parser.add_option("-p", "--password", dest="dirman_passwd", sensitive=True,
help="Directory Manager password")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False,
help="provide additional information")
parser.add_option("-f", "--force", dest="force", action="store_true", default=False,
@@ -66,6 +65,7 @@ def parse_options():
parser.add_option("--from", dest="fromhost", help="Host to get data from")
options, args = parser.parse_args()
admin_cleanup_global_argv(parser, options, sys.argv)
valid_syntax = False
+2 -2
View File
@@ -192,10 +192,10 @@ class IPACustodiaTester:
usage, IPA_CUSTODIA_KEYFILE
))
if pkey.key_id != self.host_spn:
if pkey.get('kid') != self.host_spn:
raise self.error( # pylint: disable=raising-bad-type, #4772
"KID '{}' != host service principal name '{}' "
"(usage: {})".format(pkey.key_id, self.host_spn, usage),
"(usage: {})".format(pkey.get('kid'), self.host_spn, usage),
fatal=True
)
else:
+5 -3
View File
@@ -24,7 +24,6 @@ import logging
import os
import re
import sys
from optparse import OptionParser # pylint: disable=deprecated-module
from ipaplatform.paths import paths
from ipapython import config
@@ -32,6 +31,7 @@ from ipaserver.install import installutils
from ipalib import api, errors
from ipapython.ipa_log_manager import standard_logging_setup
from ipapython.dn import DN
from ipapython.admintool import admin_cleanup_global_argv
logger = logging.getLogger(os.path.basename(__file__))
@@ -39,7 +39,8 @@ logger = logging.getLogger(os.path.basename(__file__))
def parse_options():
usage = "%prog [options] <status|enable|disable>\n"
usage += "%prog [options]\n"
parser = OptionParser(usage=usage, formatter=config.IPAFormatter())
parser = config.IPAOptionParser(usage=usage,
formatter=config.IPAFormatter())
parser.add_option("-d", "--debug", action="store_true", dest="debug",
help="Display debugging information about the update(s)")
@@ -50,9 +51,10 @@ def parse_options():
action="store_true",
help="List available Managed Entries")
parser.add_option("-p", "--password", dest="dirman_password",
help="Directory Manager password")
sensitive=True, help="Directory Manager password")
options, args = parser.parse_args()
admin_cleanup_global_argv(parser, options, sys.argv)
return options, args
+10
View File
@@ -0,0 +1,10 @@
#!/usr/bin/python3
#
# Copyright (C) 2023 FreeIPA Contributors see COPYING for license
#
# PYTHON_ARGCOMPLETE_OK
from ipaserver.install.ipa_migrate import IPAMigrate
ipa_migrate = IPAMigrate()
ipa_migrate.run()
+4 -3
View File
@@ -23,15 +23,15 @@ from __future__ import print_function
import logging
from ipapython import ipachangeconf
from ipapython.config import IPAOptionParser
from ipapython.config import (IPAOptionParser, OptionGroup,
OptionValueError)
from ipapython.admintool import admin_cleanup_global_argv
from ipapython.dn import DN
from ipapython import version
from ipapython import ipautil, certdb
from ipalib import api, errors, x509
from ipalib.constants import FQDN
from ipaserver.install import installutils
# pylint: disable=deprecated-module
from optparse import OptionGroup, OptionValueError
# pylint: enable=deprecated-module
from ipapython.ipa_log_manager import standard_logging_setup
import copy
@@ -189,6 +189,7 @@ def parse_options():
options, _args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
admin_cleanup_global_argv(parser, options, sys.argv)
if options.master and options.replica:
parser.error("on-master and on-replica options are mutually exclusive!")
+60 -31
View File
@@ -26,7 +26,6 @@ import os
import re
import socket
import traceback
from urllib.parse import urlparse
from xmlrpc.client import MAXINT
import ldap
@@ -44,6 +43,7 @@ from ipalib.util import (
print_replication_status,
verify_host_resolvable,
)
from ipapython.admintool import admin_cleanup_global_argv
from ipapython.ipa_log_manager import standard_logging_setup
from ipapython.dn import DN
from ipapython.config import IPAOptionParser
@@ -85,7 +85,8 @@ class NoRUVsFound(Exception):
def parse_options():
parser = IPAOptionParser(version=version.VERSION)
parser.add_option("-H", "--host", dest="host", help="starting host")
parser.add_option("-p", "--password", dest="dirman_passwd", help="Directory Manager password")
parser.add_option("-p", "--password", dest="dirman_passwd", sensitive=True,
help="Directory Manager password")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False,
help="provide additional information")
parser.add_option("-d", "--debug", dest="debug", action="store_true", default=False,
@@ -96,7 +97,7 @@ def parse_options():
help="DANGER: clean up references to a ghost master")
parser.add_option("--binddn", dest="binddn", default=None, type="dn",
help="Bind DN to use with remote server")
parser.add_option("--bindpw", dest="bindpw", default=None,
parser.add_option("--bindpw", dest="bindpw", default=None, sensitive=True,
help="Password for Bind DN to use with remote server")
parser.add_option("--winsync", dest="winsync", action="store_true", default=False,
help="This is a Windows Sync Agreement")
@@ -104,13 +105,15 @@ def parse_options():
help="Full path and filename of CA certificate to use with TLS/SSL to the remote server")
parser.add_option("--win-subtree", dest="win_subtree", default=None,
help="DN of Windows subtree containing the users you want to sync (default cn=Users,<domain suffix)")
parser.add_option("--passsync", dest="passsync", default=None,
parser.add_option("--passsync", dest="passsync",
default=None, sensitive=True,
help="Password for the IPA system user used by the Windows PassSync plugin to synchronize passwords")
parser.add_option("--from", dest="fromhost", help="Host to get data from")
parser.add_option("--no-lookup", dest="nolookup", action="store_true", default=False,
help="do not perform DNS lookup checks")
options, args = parser.parse_args()
admin_cleanup_global_argv(parser, options, sys.argv)
valid_syntax = False
@@ -358,9 +361,14 @@ def del_link(realm, replica1, replica2, dirman_passwd, force=False):
return True
def get_ruv(realm, host, dirman_passwd, nolookup=False, ca=False):
def get_ruv(realm, host, dirman_passwd, nolookup=False, ca=False,
strict=True):
"""
Return the RUV entries as a list of tuples: (hostname, rid)
If strict is True then the RUV must contain the ldap url, otherwise it is
ok to proceed with just the rid
"""
if not nolookup:
@@ -371,10 +379,9 @@ def get_ruv(realm, host, dirman_passwd, nolookup=False, ca=False):
thisrepl = replication.get_cs_replication_manager(realm, host, dirman_passwd)
else:
thisrepl = replication.ReplicationManager(realm, host, dirman_passwd)
except Exception as e:
except Exception as ex:
logger.debug("%s", traceback.format_exc())
raise RuntimeError("Failed to connect to server {host}: {err}"
.format(host=host, err=e))
raise RuntimeError(f"Failed to connect to server {host}: {ex}")
search_filter = '(&(nsuniqueid=ffffffff-ffffffff-ffffffff-ffffffff)(objectclass=nstombstone))'
try:
@@ -386,24 +393,42 @@ def get_ruv(realm, host, dirman_passwd, nolookup=False, ca=False):
raise NoRUVsFound("No RUV records found.")
servers = []
for e in entries:
for ruv in e['nsds50ruv']:
for entry in entries:
for ruv in entry['nsds50ruv']:
if ruv.startswith('{replicageneration'):
continue
data = re.match('\{replica (\d+) (ldap://.*:\d+)\}(\s+\w+\s+\w*){0,1}', ruv)
if data:
rid = data.group(1)
(
_scheme, netloc, _path, _params, _query, _fragment
) = urlparse(data.group(2))
servers.append((netloc, rid))
# Get the RID, this is required in all cases
rid_data = re.match(
r'\{replica (\d+)',
ruv
)
if rid_data:
rid = rid_data.group(1)
else:
print("unable to decode: %s" % ruv)
print(f"unable to decode: {ruv} --> missing replica ID")
continue
# Attempt to extract ldap url from ruv (it's not always present)
netloc = "unknown host"
host_data = re.match(
r'(\{\w+\s+\d+\s+)ldap://(.+:\d+)',
ruv
)
if host_data:
netloc = host_data.group(2)
elif strict:
print(f"unable to decode: {ruv} --> missing LDAP url")
continue
# Ok update server list
servers.append((netloc, rid))
return servers
def get_ruv_both_suffixes(realm, host, dirman_passwd, verbose, nolookup=False):
def get_ruv_both_suffixes(realm, host, dirman_passwd, verbose, nolookup=False,
strict=True):
"""
Get RUVs for both domain and ipaca suffixes
"""
@@ -411,19 +436,20 @@ def get_ruv_both_suffixes(realm, host, dirman_passwd, verbose, nolookup=False):
fail_gracefully = True
try:
ruvs['ca'] = get_ruv(realm, host, dirman_passwd, nolookup, True)
ruvs['ca'] = get_ruv(realm, host, dirman_passwd, nolookup, True,
strict)
except (NoRUVsFound, RuntimeError) as e:
err = "Failed to get CS-RUVs from {host}: {err}".format(host=host,
err=e)
err = f"Failed to get CS-RUVs from {host}: {e}"
if isinstance(e, RuntimeError):
fail_gracefully = False
if verbose:
print(err)
logger.debug('%s', err)
try:
ruvs['domain'] = get_ruv(realm, host, dirman_passwd, nolookup)
ruvs['domain'] = get_ruv(realm, host, dirman_passwd, nolookup, False,
strict)
except (NoRUVsFound, RuntimeError) as e:
err = "Failed to get RUVs from {host}: {err}".format(host=host, err=e)
err = f"Failed to get RUVs from {host}: {e}"
if isinstance(e, RuntimeError):
if not fail_gracefully:
raise
@@ -495,7 +521,8 @@ def clean_ruv(realm, ruv, options):
servers = get_ruv_both_suffixes(realm, options.host,
options.dirman_passwd,
options.verbose,
options.nolookup)
options.nolookup,
strict=False)
except (NoRUVsFound, RuntimeError) as e:
print(e)
sys.exit(0 if isinstance(e, NoRUVsFound) else 1)
@@ -551,7 +578,8 @@ def abort_clean_ruv(realm, ruv, options):
servers = get_ruv_both_suffixes(realm, options.host,
options.dirman_passwd,
options.verbose,
options.nolookup)
options.nolookup,
strict=False)
except (NoRUVsFound, RuntimeError) as e:
print(e)
sys.exit(0 if isinstance(e, NoRUVsFound) else 1)
@@ -710,7 +738,8 @@ def clean_dangling_ruvs(realm, host, options):
ruv_dict = get_ruv_both_suffixes(realm, master_cn,
options.dirman_passwd,
options.verbose,
options.nolookup)
options.nolookup,
strict=False)
except (RuntimeError, NoRUVsFound):
continue
@@ -718,12 +747,12 @@ def clean_dangling_ruvs(realm, host, options):
# This needs needs to be split off
if ruv_dict.get('domain'):
master_info['ruvs'] = {
(re.sub(':\d+', '', x), y)
(re.sub(r':\d+', '', x), y)
for (x, y) in ruv_dict['domain']
}
if ruv_dict.get('ca'):
master_info['csruvs'] = {
(re.sub(':\d+', '', x), y)
(re.sub(r':\d+', '', x), y)
for (x, y) in ruv_dict['ca']
}
except Exception as e:
@@ -1237,12 +1266,12 @@ def force_sync(realm, thishost, fromhost, dirman_passwd, nolookup=False):
repl.force_sync(repl.conn, fromhost)
else:
ds = dsinstance.DsInstance(realm_name=realm)
ds.replica_manage_time_skew(prevent=False)
ds.replica_ignore_initial_time_skew()
repl = replication.ReplicationManager(realm, fromhost, dirman_passwd)
repl.force_sync(repl.conn, thishost)
agreement = repl.get_replication_agreement(thishost)
repl.wait_for_repl_update(repl.conn, agreement.dn)
ds.replica_manage_time_skew(prevent=True)
ds.replica_revert_time_skew()
def show_DNA_ranges(hostname, master, realm, dirman_passwd, nextrange=False,
nolookup=False):
+2 -1
View File
@@ -30,7 +30,8 @@ dist_man1_MANS = \
ipa-crlgen-manage.1 \
ipa-cert-fix.1 \
ipa-acme-manage.1 \
$(NULL)
ipa-migrate.1 \
$(NULL)
dist_man8_MANS = \
ipactl.8 \
+1 -1
View File
@@ -27,7 +27,7 @@ Provides customized advice for various IPA configuration issues.
For the list of possible ADVICEs available, run the ipa\-advise with no arguments.
.SH "OPTIONS"
.TP
\fB\-\-v\fR, \fB\-\-verbose\fR
\fB\-v\fR, \fB\-\-verbose\fR
Print debugging information
.TP
\fB\-d\fR, \fB\-\-debug\fR
+1 -1
View File
@@ -54,7 +54,7 @@ Perform the backup on\-line. Requires the \-\-data option.
\fB\-\-disable\-role\-check\fR
Perform the backup even if this host does not have all the roles in use in the cluster. This is not recommended.
.TP
\fB\-\-v\fR, \fB\-\-verbose\fR
\fB\-v\fR, \fB\-\-verbose\fR
Print debugging information
.TP
\fB\-d\fR, \fB\-\-debug\fR
+12
View File
@@ -85,6 +85,18 @@ Do not use DNS for hostname lookup during installation
\fB\-\-random\-serial\-numbers\fR
Enable Random Serial Numbers. Random serial numbers cannot be used in a mixed environment. Either all CA's have it enabled or none do.
.TP
\fB\-\-token\-name\fR=\fITOKEN_NAME\fR
The PKCS#11 token name if using an HSM to store and generate private keys.
.TP
\fB\-\-token\-library\-path\fR=\fITOKEN_LIBRARY_PATH\fR
The full path to the PKCS#11 shared library needed to access the HSM device.
.TP
\fB\-\-token\-password\fR=\fITOKEN_PASSWORD\fR
The PKCS#11 token password for the HSM.
.TP
\fB\-\-token\-password\-file\fR=\fITOKEN_PASSWORD_FILE\fR
The full path to a file containing the PKCS#11 token password.
.TP
\fB\-\-skip\-conncheck\fR
Skip connection check to remote master
.TP
Loaded 100 of 351 files, more files were not shown because too many files have changed in this diff. Show more