Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe005dd388 | ||
|
|
430054db41 | ||
|
|
e459e5b8bc | ||
|
|
f9075f9f77 | ||
|
|
b22605ee54 | ||
|
|
48cfe6848c | ||
|
|
fe223cde95 | ||
|
|
843f4a7458 | ||
|
|
1a2cd7f408 | ||
|
|
6aebfe74fb | ||
|
|
8b70ee1ea8 | ||
|
|
4af05dde48 | ||
|
|
496e3ace85 | ||
|
|
7ddf7711f3 | ||
|
|
32721c4132 | ||
|
|
f248b22ef4 | ||
|
|
dade02d5bb | ||
|
|
6aa3c3b628 | ||
|
|
f123b01d81 | ||
|
|
d355761f23 | ||
|
|
2bc247d831 | ||
|
|
953c7cc076 | ||
|
|
45fa43540f | ||
|
|
8f25b2a74a | ||
|
|
0654fb3737 | ||
|
|
317e7061d0 | ||
|
|
ed52142c40 | ||
|
|
8d081ce894 | ||
|
|
1251c15fae |
No files matched your search
@@ -16,6 +16,7 @@ Developers:
|
||||
Alexander Bokovoy
|
||||
Alexander Koksharov
|
||||
Alexander Scheel
|
||||
Alexandra Nikandrova
|
||||
Alexandre Mulatinho
|
||||
Alexey Slaykovsky
|
||||
Alexey Tikhonov
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
# -> "1.0.0" #
|
||||
########################################################
|
||||
define(IPA_VERSION_MAJOR, 4)
|
||||
define(IPA_VERSION_MINOR, 11)
|
||||
define(IPA_VERSION_MINOR, 12)
|
||||
define(IPA_VERSION_RELEASE, 0)
|
||||
|
||||
########################################################
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1839,6 +1839,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 */
|
||||
|
||||
@@ -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,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>`.
|
||||
@@ -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``
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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>`.
|
||||
@@ -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>`.
|
||||
@@ -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.
|
||||
@@ -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>`.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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>`.
|
||||
@@ -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.
|
||||
@@ -1,3 +1,5 @@
|
||||
.. _building:
|
||||
|
||||
Building Vagrant box images
|
||||
===========================
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,5 @@
|
||||
dn: $SUFFIX
|
||||
add:aci: (targetattr = "memberPrincipal")(targattrfilters="add=objectclass:(objectclass=resourcedelegation)")(version 3.0;acl "permission:RBCD:Kerberos principals can manage resource-based constrained delegation for themselves";allow (write) userdn = "ldap:///self";)
|
||||
add:aci: (targetattr = "memberPrincipal")(targattrfilters="add=objectclass:(objectclass=resourcedelegation)")(version 3.0;acl "permission:RBCD:Managing principals can manage resource-based constrained delegation for other principals";allow (write) userattr = "managedby#GROUPDN" or userattr = "managedby#USERDN";)
|
||||
add:aci: (targetattr = "memberPrincipal")(targattrfilters="add=objectclass:(objectclass=resourcedelegation)")(version 3.0;acl "permission:RBCD:Delegated permission to manage resource-based constrained delegation for other principals";allow (write) userattr="ipaAllowedToPerform;write_delegation#GROUPDN" or userattr="ipaAllowedToPerform;write_delegation#USERDN" ;)
|
||||
|
||||
@@ -67,6 +67,7 @@ app_DATA = \
|
||||
73-winsync.update \
|
||||
73-certmap.update \
|
||||
73-passkey.update \
|
||||
73-service-rbcd.update \
|
||||
75-user-trust-attributes.update \
|
||||
80-schema_compat.update \
|
||||
81-externalmembers.update \
|
||||
|
||||
@@ -67,6 +67,7 @@ from ipapython.ipautil import (
|
||||
)
|
||||
from ipapython.ssh import SSHPublicKey
|
||||
from ipapython import version
|
||||
from ipapython.errors import SetseboolError
|
||||
|
||||
from . import automount, timeconf, sssd
|
||||
from ipaclient import discovery
|
||||
@@ -98,6 +99,7 @@ cli_realm = None
|
||||
cli_kdc = None
|
||||
client_domain = None
|
||||
cli_basedn = None
|
||||
selinux_works = None
|
||||
# end of global variables
|
||||
|
||||
|
||||
@@ -2153,6 +2155,7 @@ def install_check(options):
|
||||
global cli_kdc
|
||||
global client_domain
|
||||
global cli_basedn
|
||||
global selinux_works
|
||||
|
||||
print("This program will set up IPA client.")
|
||||
print("Version {}".format(version.VERSION))
|
||||
@@ -2166,7 +2169,7 @@ def install_check(options):
|
||||
"You must be root to run ipa-client-install.",
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
tasks.check_selinux_status()
|
||||
selinux_works = tasks.check_selinux_status()
|
||||
|
||||
if is_ipa_client_configured(on_master=options.on_master):
|
||||
logger.error("IPA client is already configured on this system.")
|
||||
@@ -2674,6 +2677,20 @@ def restore_time_sync(statestore, fstore):
|
||||
logger.error('Failed to restore time synchronization service: %s', e)
|
||||
|
||||
|
||||
def configure_selinux_for_client(statestore):
|
||||
def backup_state(key, value):
|
||||
statestore.backup_state('selinux', key, value)
|
||||
|
||||
try:
|
||||
tasks.set_selinux_booleans(constants.SELINUX_BOOLEAN_SSSD,
|
||||
backup_state)
|
||||
except SetseboolError as e:
|
||||
for c in constants.SELINUX_BOOLEAN_SSSD:
|
||||
if c in e.failed:
|
||||
logger.warning(
|
||||
"SELinux does not support SSSD boolean %s, ignoring", c)
|
||||
|
||||
|
||||
def install(options):
|
||||
try:
|
||||
_install(options, dict())
|
||||
@@ -3198,6 +3215,9 @@ def _install(options, tdict):
|
||||
logger.info("%s enabled", "SSSD" if options.sssd else "LDAP")
|
||||
|
||||
if options.sssd:
|
||||
if selinux_works:
|
||||
configure_selinux_for_client(statestore)
|
||||
|
||||
sssd = services.service('sssd', api)
|
||||
try:
|
||||
sssd.restart()
|
||||
@@ -3322,6 +3342,8 @@ def _install(options, tdict):
|
||||
|
||||
|
||||
def uninstall_check(options):
|
||||
global selinux_works
|
||||
|
||||
if not is_ipa_client_configured():
|
||||
if options.on_master:
|
||||
rval = SUCCESS
|
||||
@@ -3337,6 +3359,8 @@ def uninstall_check(options):
|
||||
logger.info("Refer to ipa-server-install for uninstallation.")
|
||||
raise ScriptError(rval=CLIENT_NOT_CONFIGURED)
|
||||
|
||||
selinux_works = tasks.check_selinux_status()
|
||||
|
||||
|
||||
def uninstall(options):
|
||||
env = {'PATH': SECURE_PATH}
|
||||
@@ -3600,6 +3624,15 @@ def uninstall(options):
|
||||
"Failed to disable automatic startup of the SSSD daemon: %s",
|
||||
e)
|
||||
|
||||
if statestore.has_state('selinux'):
|
||||
# Restore SELinux boolean states
|
||||
boolean_states = {name: statestore.restore_state('selinux', name)
|
||||
for name in constants.SELINUX_BOOLEAN_SSSD}
|
||||
try:
|
||||
tasks.set_selinux_booleans(boolean_states)
|
||||
except SetseboolError as e:
|
||||
logger.warning("Unable to reset SELinux variable: %s", str(e))
|
||||
|
||||
tasks.restore_hostname(fstore, statestore)
|
||||
|
||||
if fstore.has_files():
|
||||
|
||||
@@ -33,7 +33,8 @@ import ssl
|
||||
import time
|
||||
|
||||
from collections import deque
|
||||
from datetime import datetime, timedelta, UTC
|
||||
from datetime import datetime, timedelta, timezone
|
||||
UTC = timezone.utc
|
||||
from email.utils import formataddr, formatdate
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
|
||||
@@ -936,6 +936,68 @@ Registry = plugable.Registry
|
||||
class API(plugable.API):
|
||||
bases = (Command, Object, Method, Backend, Updater)
|
||||
|
||||
def __enter__(self):
|
||||
"""Context manager for IPA API
|
||||
|
||||
The context manager connects the backend connect on enter and
|
||||
disconnects on exit. The process must have access to a valid Kerberos
|
||||
ticket or have automatic authentication with a keytab or gssproxy
|
||||
set up. The connection type depends on ``in_server`` and ``context``
|
||||
options. Server connections use LDAP while clients use JSON-RPC over
|
||||
HTTPS.
|
||||
|
||||
The context manager also finalizes the API object, in case it hasn't
|
||||
been finalized yet. It is possible to use a custom API object. In
|
||||
that case, the global API object must be finalized, first. Some
|
||||
options like logging only apply to global ``ipalib.api`` object.
|
||||
|
||||
Usage with global api object::
|
||||
|
||||
import os
|
||||
import ipalib
|
||||
|
||||
# optional: automatic authentication with a KRB5 keytab
|
||||
os.environ.update(
|
||||
KRB5_CLIENT_KTNAME="/path/to/service.keytab",
|
||||
KRB5RCACHENAME="FILE:/path/to/tmp/service.ccache",
|
||||
)
|
||||
|
||||
# optional: override settings (once per process)
|
||||
overrides = {}
|
||||
ipalib.api.bootstrap(**overrides)
|
||||
|
||||
with ipalib.api as api:
|
||||
host = api.Command.host_show(api.env.host)
|
||||
user = api.Command.user_show("admin")
|
||||
|
||||
"""
|
||||
# Several IPA module require api.env at import time, some even
|
||||
# a fully finalized ipalib.ap, e.g. register() with MethodOverride.
|
||||
if self is not api and not api.isdone("finalize"):
|
||||
raise RuntimeError("global ipalib.api must be finalized first.")
|
||||
# initialize this api
|
||||
if not self.isdone("finalize"):
|
||||
self.finalize()
|
||||
# connect backend, server and client use different backends.
|
||||
if self.env.in_server:
|
||||
conn = self.Backend.ldap2
|
||||
else:
|
||||
conn = self.Backend.rpcclient
|
||||
if conn.isconnected():
|
||||
raise RuntimeError("API is already connected")
|
||||
else:
|
||||
conn.connect()
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
"""Disconnect backend on exit"""
|
||||
if self.env.in_server:
|
||||
conn = self.Backend.ldap2
|
||||
else:
|
||||
conn = self.Backend.rpcclient
|
||||
if conn.isconnected():
|
||||
conn.disconnect()
|
||||
|
||||
@property
|
||||
def packages(self):
|
||||
if self.env.in_server:
|
||||
|
||||
@@ -1836,7 +1836,7 @@ class DateTime(Param):
|
||||
def _convert_scalar(self, value, index=None):
|
||||
if isinstance(value, str):
|
||||
if value == u'now':
|
||||
time = datetime.datetime.now(tz=datetime.UTC)
|
||||
time = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
return time
|
||||
else:
|
||||
for date_format in self.accepted_formats:
|
||||
|
||||
+3
-2
@@ -819,7 +819,8 @@ class KerbTransport(SSLTransport):
|
||||
session_cookie = (
|
||||
Cookie.get_named_cookie_from_string(
|
||||
cookie, COOKIE_NAME, request_url,
|
||||
timestamp=datetime.datetime.now(tz=datetime.UTC))
|
||||
timestamp=datetime.datetime.now(
|
||||
tz=datetime.timezone.utc))
|
||||
)
|
||||
if session_cookie is not None:
|
||||
break
|
||||
@@ -922,7 +923,7 @@ class RPCClient(Connectible):
|
||||
try:
|
||||
session_cookie = Cookie.get_named_cookie_from_string(
|
||||
cookie_string, COOKIE_NAME,
|
||||
timestamp=datetime.datetime.now(tz=datetime.UTC))
|
||||
timestamp=datetime.datetime.now(tz=datetime.timezone.utc))
|
||||
except Exception as e:
|
||||
logger.debug(
|
||||
'Error retrieving cookie from the persistent storage: %s',
|
||||
|
||||
+2
-2
@@ -267,12 +267,12 @@ class IPACertificate(crypto_x509.Certificate):
|
||||
@property
|
||||
def not_valid_before(self):
|
||||
return datetime.datetime.fromtimestamp(
|
||||
self._cert.not_valid_before.timestamp(), tz=datetime.UTC)
|
||||
self._cert.not_valid_before.timestamp(), tz=datetime.timezone.utc)
|
||||
|
||||
@property
|
||||
def not_valid_after(self):
|
||||
return datetime.datetime.fromtimestamp(
|
||||
self._cert.not_valid_after.timestamp(), tz=datetime.UTC)
|
||||
self._cert.not_valid_after.timestamp(), tz=datetime.timezone.utc)
|
||||
|
||||
@property
|
||||
def tbs_certificate_bytes(self):
|
||||
|
||||
@@ -21,10 +21,11 @@ class IpaMetaImporter:
|
||||
def __init__(self, platform):
|
||||
self.platform = platform
|
||||
|
||||
def find_module(self, fullname, path=None):
|
||||
def find_spec(self, fullname, path=None, target=None):
|
||||
"""Meta importer hook"""
|
||||
if fullname in self.modules:
|
||||
return self
|
||||
module = self.load_module(fullname)
|
||||
return module.__spec__
|
||||
return None
|
||||
|
||||
def load_module(self, fullname):
|
||||
|
||||
@@ -151,6 +151,9 @@ class BaseConstantsNamespace:
|
||||
'samba_share_nfs': 'on',
|
||||
},
|
||||
}
|
||||
SELINUX_BOOLEAN_SSSD = {
|
||||
'sssd_use_usb': 'on',
|
||||
}
|
||||
SELINUX_MCS_MAX = 1023
|
||||
SELINUX_MCS_REGEX = r"^c(\d+)([.,-]c(\d+))*$"
|
||||
SELINUX_MLS_MAX = 15
|
||||
|
||||
+1
-1
@@ -943,7 +943,7 @@ class NSSDatabase:
|
||||
def _verify_cert_validity(self, cert):
|
||||
"""Common checks for cert validity
|
||||
"""
|
||||
utcnow = datetime.datetime.now(tz=datetime.UTC)
|
||||
utcnow = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
if cert.not_valid_before > utcnow:
|
||||
raise ValueError(
|
||||
f"not valid before {cert.not_valid_before} UTC is in the "
|
||||
|
||||
+1
-1
@@ -652,7 +652,7 @@ class Cookie:
|
||||
|
||||
cookie_expiration = self.get_expiration()
|
||||
if cookie_expiration is not None:
|
||||
now = datetime.datetime.now(tz=datetime.UTC)
|
||||
now = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
if cookie_expiration < now:
|
||||
raise Cookie.Expired("cookie named '%s'; expired at %s'" % \
|
||||
(cookie_name,
|
||||
|
||||
@@ -740,7 +740,7 @@ class _CrossProcessLock:
|
||||
self._do(self._release, owner)
|
||||
|
||||
def _acquire(self, owner):
|
||||
now = datetime.datetime.now(tz=datetime.UTC)
|
||||
now = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
|
||||
if self._locked and now >= self._expire:
|
||||
self._locked = False
|
||||
@@ -800,7 +800,7 @@ class _CrossProcessLock:
|
||||
try:
|
||||
self._expire = datetime.datetime.strptime(
|
||||
expire, self._DATETIME_FORMAT).replace(
|
||||
tzinfo=datetime.UTC)
|
||||
tzinfo=datetime.timezone.utc)
|
||||
except ValueError:
|
||||
raise configparser.Error
|
||||
except configparser.Error:
|
||||
|
||||
@@ -31,6 +31,7 @@ from lib389.idm.ipadomain import IpaDomain
|
||||
from lib389.instance.options import General2Base, Slapd2Base
|
||||
from lib389.instance.remove import remove_ds_instance as lib389_remove_ds
|
||||
from lib389.instance.setup import SetupDs
|
||||
from lib389.utils import get_default_db_lib
|
||||
|
||||
from ipalib import x509
|
||||
from ipalib.install import certmonger, certstore
|
||||
@@ -227,7 +228,8 @@ class DsInstance(service.Service):
|
||||
def __common_setup(self):
|
||||
|
||||
self.step("creating directory server instance", self.__create_instance)
|
||||
self.step("tune ldbm plugin", self.__tune_ldbm)
|
||||
if get_default_db_lib() == 'bdb':
|
||||
self.step("tune ldbm plugin", self.__tune_ldbm)
|
||||
if self.config_ldif is not None:
|
||||
self.step("stopping directory server", self.__stop_instance)
|
||||
self.step(
|
||||
|
||||
@@ -556,7 +556,7 @@ class CACertManage(admintool.AdminTool):
|
||||
api.env.realm,
|
||||
False)
|
||||
|
||||
now = datetime.datetime.now(tz=datetime.UTC)
|
||||
now = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
for ca_cert, ca_nickname, _ca_trust_flags in ca_certs:
|
||||
if ca_cert.not_valid_after < now:
|
||||
expired_certs.append(ca_nickname)
|
||||
|
||||
@@ -129,7 +129,7 @@ class IPACertFix(AdminTool):
|
||||
ca_subject_dn = ca.lookup_ca_subject(api, subject_base)
|
||||
|
||||
now = (
|
||||
datetime.datetime.now(tz=datetime.UTC)
|
||||
datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
+ datetime.timedelta(weeks=2))
|
||||
certs, extra_certs, non_renewed = expired_certs(now)
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import six
|
||||
|
||||
from ipaclient.install.client import check_ldap_conf, sssd_enable_ifp
|
||||
import ipaclient.install.timeconf
|
||||
from ipalib.install import certstore, sysrestore
|
||||
from ipalib.install import sysrestore
|
||||
from ipalib.install.kinit import kinit_keytab
|
||||
from ipapython import ipaldap, ipautil
|
||||
from ipapython.dn import DN
|
||||
@@ -32,7 +32,7 @@ from ipapython.ipachangeconf import IPAChangeConf
|
||||
from ipaplatform import services
|
||||
from ipaplatform.tasks import tasks
|
||||
from ipaplatform.paths import paths
|
||||
from ipalib import api, constants, create_api, errors, rpc, x509
|
||||
from ipalib import api, constants, create_api, errors, rpc
|
||||
from ipalib.config import Env
|
||||
from ipalib.facts import is_ipa_configured, is_ipa_client_configured
|
||||
from ipalib.util import no_matching_interface_for_ip_address_warning
|
||||
@@ -132,24 +132,6 @@ def install_krb(config, setup_pkinit=False, pkcs12_info=None, fstore=None):
|
||||
return krb
|
||||
|
||||
|
||||
def install_ca_cert(ldap, base_dn, realm, cafile, destfile=paths.IPA_CA_CRT):
|
||||
try:
|
||||
try:
|
||||
certs = certstore.get_ca_certs(ldap, base_dn, realm, False)
|
||||
except errors.NotFound:
|
||||
try:
|
||||
shutil.copy(cafile, destfile)
|
||||
except shutil.Error:
|
||||
# cafile == IPA_CA_CRT
|
||||
pass
|
||||
else:
|
||||
certs = [c[0] for c in certs if c[2] is not False]
|
||||
x509.write_certificate_list(certs, destfile, mode=0o644)
|
||||
except Exception as e:
|
||||
raise ScriptError("error copying files: " + str(e))
|
||||
return destfile
|
||||
|
||||
|
||||
def install_http(config, auto_redirect, ca_is_configured, ca_file,
|
||||
pkcs12_info=None, fstore=None):
|
||||
# if we have a pkcs12 file, create the cert db from
|
||||
@@ -781,6 +763,20 @@ def promotion_check_host_principal_auth_ind(conn, hostdn):
|
||||
)
|
||||
|
||||
|
||||
def remote_connection(config):
|
||||
ldapuri = 'ldaps://%s' % ipautil.format_netloc(config.master_host_name)
|
||||
xmlrpc_uri = 'https://{}/ipa/xml'.format(
|
||||
ipautil.format_netloc(config.master_host_name))
|
||||
remote_api = create_api(mode=None)
|
||||
remote_api.bootstrap(in_server=True,
|
||||
context='installer',
|
||||
confdir=paths.ETC_IPA,
|
||||
ldap_uri=ldapuri,
|
||||
xmlrpc_uri=xmlrpc_uri)
|
||||
remote_api.finalize()
|
||||
return remote_api
|
||||
|
||||
|
||||
@common_cleanup
|
||||
@preserve_enrollment_state
|
||||
def promote_check(installer):
|
||||
@@ -797,7 +793,8 @@ def promote_check(installer):
|
||||
raise ScriptError("--setup-ca and --*-cert-file options are "
|
||||
"mutually exclusive")
|
||||
|
||||
if not is_ipa_client_configured(on_master=True):
|
||||
ipa_client_installed = is_ipa_client_configured(on_master=True)
|
||||
if not ipa_client_installed:
|
||||
# One-step replica installation
|
||||
if options.password and options.admin_password:
|
||||
raise ScriptError("--password and --admin-password options are "
|
||||
@@ -938,21 +935,15 @@ def promote_check(installer):
|
||||
paths.KRB5_KEYTAB,
|
||||
ccache)
|
||||
|
||||
cafile = paths.IPA_CA_CRT
|
||||
if not os.path.isfile(cafile):
|
||||
raise RuntimeError("CA cert file is not available! Please reinstall"
|
||||
"the client and try again.")
|
||||
if ipa_client_installed:
|
||||
# host was already an IPA client, refresh client cert stores to
|
||||
# ensure we have up to date CA certs.
|
||||
try:
|
||||
ipautil.run([paths.IPA_CERTUPDATE])
|
||||
except ipautil.CalledProcessError:
|
||||
raise RuntimeError("ipa-certupdate failed to refresh certs.")
|
||||
|
||||
ldapuri = 'ldaps://%s' % ipautil.format_netloc(config.master_host_name)
|
||||
xmlrpc_uri = 'https://{}/ipa/xml'.format(
|
||||
ipautil.format_netloc(config.master_host_name))
|
||||
remote_api = create_api(mode=None)
|
||||
remote_api.bootstrap(in_server=True,
|
||||
context='installer',
|
||||
confdir=paths.ETC_IPA,
|
||||
ldap_uri=ldapuri,
|
||||
xmlrpc_uri=xmlrpc_uri)
|
||||
remote_api.finalize()
|
||||
remote_api = remote_connection(config)
|
||||
installer._remote_api = remote_api
|
||||
|
||||
with rpc_client(remote_api) as client:
|
||||
@@ -997,7 +988,7 @@ def promote_check(installer):
|
||||
raise errors.ACIError(info="Not authorized")
|
||||
|
||||
if installer._ccache is None:
|
||||
del os.environ['KRB5CCNAME']
|
||||
os.environ.pop('KRB5CCNAME', None)
|
||||
else:
|
||||
os.environ['KRB5CCNAME'] = installer._ccache
|
||||
|
||||
@@ -1082,7 +1073,16 @@ def promote_check(installer):
|
||||
'CA', conn, preferred_cas
|
||||
)
|
||||
if ca_host is not None:
|
||||
if config.master_host_name != ca_host:
|
||||
conn.disconnect()
|
||||
del remote_api
|
||||
config.master_host_name = ca_host
|
||||
remote_api = remote_connection(config)
|
||||
installer._remote_api = remote_api
|
||||
conn = remote_api.Backend.ldap2
|
||||
conn.connect(ccache=installer._ccache)
|
||||
config.ca_host_name = ca_host
|
||||
config.master_host_name = ca_host
|
||||
ca_enabled = True
|
||||
if options.dirsrv_cert_files:
|
||||
logger.error("Certificates could not be provided when "
|
||||
@@ -1121,7 +1121,17 @@ def promote_check(installer):
|
||||
'KRA', conn, preferred_kras
|
||||
)
|
||||
if kra_host is not None:
|
||||
if config.master_host_name != kra_host:
|
||||
conn.disconnect()
|
||||
del remote_api
|
||||
config.master_host_name = kra_host
|
||||
remote_api = remote_connection(config)
|
||||
installer._remote_api = remote_api
|
||||
conn = remote_api.Backend.ldap2
|
||||
conn.connect(ccache=installer._ccache)
|
||||
config.kra_host_name = kra_host
|
||||
config.ca_host_name = kra_host
|
||||
config.master_host_name = kra_host
|
||||
kra_enabled = True
|
||||
if options.setup_kra and options.server and \
|
||||
kra_host != options.server:
|
||||
@@ -1187,7 +1197,7 @@ def promote_check(installer):
|
||||
if add_to_ipaservers:
|
||||
# use user's credentials when the server host is not ipaservers
|
||||
if installer._ccache is None:
|
||||
del os.environ['KRB5CCNAME']
|
||||
os.environ.pop('KRB5CCNAME', None)
|
||||
else:
|
||||
os.environ['KRB5CCNAME'] = installer._ccache
|
||||
|
||||
@@ -1196,14 +1206,14 @@ def promote_check(installer):
|
||||
config.master_host_name, config.host_name, config.realm_name,
|
||||
options.setup_ca, 389,
|
||||
options.admin_password, principal=options.principal,
|
||||
ca_cert_file=cafile)
|
||||
ca_cert_file=paths.IPA_CA_CRT)
|
||||
finally:
|
||||
if add_to_ipaservers:
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
|
||||
installer._ca_enabled = ca_enabled
|
||||
installer._kra_enabled = kra_enabled
|
||||
installer._ca_file = cafile
|
||||
installer._ca_file = paths.IPA_CA_CRT
|
||||
installer._fstore = fstore
|
||||
installer._sstore = sstore
|
||||
installer._config = config
|
||||
@@ -1224,7 +1234,6 @@ def install(installer):
|
||||
fstore = installer._fstore
|
||||
sstore = installer._sstore
|
||||
config = installer._config
|
||||
cafile = installer._ca_file
|
||||
dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
|
||||
http_pkcs12_info = installer._http_pkcs12_info
|
||||
pkinit_pkcs12_info = installer._pkinit_pkcs12_info
|
||||
@@ -1239,6 +1248,24 @@ def install(installer):
|
||||
if tasks.configure_pkcs11_modules(fstore):
|
||||
print("Disabled p11-kit-proxy")
|
||||
|
||||
_hostname, _sep, host_domain = config.host_name.partition('.')
|
||||
fstore.backup_file(paths.KRB5_CONF)
|
||||
|
||||
# Write a new krb5.conf in case any values changed finding the
|
||||
# right server to configure against (for CA, KRA).
|
||||
logger.debug("Installing against server %s", config.master_host_name)
|
||||
configure_krb5_conf(
|
||||
cli_realm=api.env.realm,
|
||||
cli_domain=api.env.domain,
|
||||
cli_server=[config.master_host_name],
|
||||
cli_kdc=[config.master_host_name],
|
||||
dnsok=False,
|
||||
filename=paths.KRB5_CONF,
|
||||
client_domain=host_domain,
|
||||
client_hostname=config.host_name,
|
||||
configure_sssd=False
|
||||
)
|
||||
|
||||
if installer._add_to_ipaservers:
|
||||
try:
|
||||
conn.connect(ccache=installer._ccache)
|
||||
@@ -1258,18 +1285,10 @@ def install(installer):
|
||||
|
||||
try:
|
||||
conn.connect(ccache=ccache)
|
||||
|
||||
# Update and istall updated CA file
|
||||
cafile = install_ca_cert(conn, api.env.basedn, api.env.realm, cafile)
|
||||
install_ca_cert(conn, api.env.basedn, api.env.realm, cafile,
|
||||
destfile=paths.KDC_CA_BUNDLE_PEM)
|
||||
install_ca_cert(conn, api.env.basedn, api.env.realm, cafile,
|
||||
destfile=paths.CA_BUNDLE_PEM)
|
||||
|
||||
# Configure dirsrv
|
||||
ds = install_replica_ds(config, options, ca_enabled,
|
||||
remote_api,
|
||||
ca_file=cafile,
|
||||
ca_file=paths.IPA_CA_CRT,
|
||||
pkcs12_info=dirsrv_pkcs12_info,
|
||||
fstore=fstore)
|
||||
|
||||
@@ -1320,7 +1339,7 @@ def install(installer):
|
||||
auto_redirect=not options.no_ui_redirect,
|
||||
pkcs12_info=http_pkcs12_info,
|
||||
ca_is_configured=ca_enabled,
|
||||
ca_file=cafile,
|
||||
ca_file=paths.IPA_CA_CRT,
|
||||
fstore=fstore)
|
||||
|
||||
# Need to point back to ourself after the cert for HTTP is obtained
|
||||
|
||||
@@ -127,6 +127,8 @@ def find_providing_servers(svcname, conn=None, preferred_hosts=(), api=api):
|
||||
)
|
||||
else:
|
||||
servers.insert(0, host_name)
|
||||
logger.debug("Discovery: available servers for service '%s' are %s",
|
||||
svcname, ', '.join(servers))
|
||||
return servers
|
||||
|
||||
|
||||
@@ -143,8 +145,11 @@ def find_providing_server(svcname, conn=None, preferred_hosts=(), api=api):
|
||||
svcname, conn=conn, preferred_hosts=preferred_hosts, api=api
|
||||
)
|
||||
if not servers:
|
||||
logger.debug("Discovery: no '%s' service found.", svcname)
|
||||
return None
|
||||
else:
|
||||
logger.debug("Discovery: using %s for '%s' service",
|
||||
servers[0], svcname)
|
||||
return servers[0]
|
||||
|
||||
|
||||
|
||||
@@ -612,7 +612,10 @@ class baseuser_add(LDAPCreate):
|
||||
if entry_attrs.get('ipauserauthtype', None):
|
||||
add_missing_object_class(ldap, u'ipauserauthtypeclass', dn,
|
||||
entry_attrs, update=False)
|
||||
if entry_attrs.get('ipaidpconfiglink', None):
|
||||
if (
|
||||
entry_attrs.get('ipaidpconfiglink', None)
|
||||
or entry_attrs.get('ipaidpsub', None)
|
||||
):
|
||||
add_missing_object_class(ldap, 'ipaidpuser', dn,
|
||||
entry_attrs, update=False)
|
||||
|
||||
@@ -720,7 +723,7 @@ class baseuser_mod(LDAPUpdate):
|
||||
# Some attributes may require additional object classes
|
||||
special_attrs = {'ipasshpubkey', 'ipauserauthtype', 'userclass',
|
||||
'ipatokenradiusconfiglink', 'ipatokenradiususername',
|
||||
'ipaidpconfiglink'}
|
||||
'ipaidpconfiglink', 'ipaidpsub'}
|
||||
if special_attrs.intersection(entry_attrs):
|
||||
if 'objectclass' in entry_attrs:
|
||||
obj_classes = entry_attrs['objectclass']
|
||||
@@ -749,6 +752,10 @@ class baseuser_mod(LDAPUpdate):
|
||||
answer = self.api.Object['radiusproxy'].get_dn_if_exists(cl)
|
||||
entry_attrs['ipatokenradiusconfiglink'] = answer
|
||||
|
||||
if 'ipaidpsub' in entry_attrs:
|
||||
if 'ipaidpuser' not in obj_classes:
|
||||
entry_attrs['objectclass'].append('ipaidpuser')
|
||||
|
||||
if 'ipaidpconfiglink' in entry_attrs:
|
||||
cl = entry_attrs['ipaidpconfiglink']
|
||||
if cl:
|
||||
|
||||
+300
-754
File diff suppressed because it is too large.
Load diff
@@ -32,10 +32,10 @@ vms:
|
||||
clients: 1
|
||||
resources:
|
||||
replica:
|
||||
mem_limit: "2200m"
|
||||
mem_limit: "2300m"
|
||||
memswap_limit: "3300m"
|
||||
client:
|
||||
mem_limit: "768m"
|
||||
mem_limit: "805m"
|
||||
memswap_limit: "1024m"
|
||||
tests:
|
||||
- test_integration/test_forced_client_reenrollment.py
|
||||
@@ -187,7 +187,7 @@ vms:
|
||||
containers:
|
||||
resources:
|
||||
server:
|
||||
mem_limit: "2200m"
|
||||
mem_limit: "2450m"
|
||||
memswap_limit: "3300m"
|
||||
tests:
|
||||
- test_integration/test_upgrade.py
|
||||
|
||||
@@ -35,7 +35,7 @@ class ExternalCA:
|
||||
"""
|
||||
|
||||
def __init__(self, days=365, key_size=None):
|
||||
self.now = datetime.datetime.now(tz=datetime.UTC)
|
||||
self.now = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
self.delta = datetime.timedelta(days=days)
|
||||
self.ca_key = None
|
||||
self.ca_public_key = None
|
||||
|
||||
@@ -36,7 +36,7 @@ def setup_scim_server(host, version="main"):
|
||||
host.run_command(["pip", "install", "-r", f"{django_reqs}"])
|
||||
|
||||
# Prepare models and database
|
||||
host.run_command(["python", "manage.py", "makemigrations", "ipatuura"],
|
||||
host.run_command(["python", "manage.py", "makemigrations", "scim"],
|
||||
cwd=f"{dir}/src/ipa-tuura")
|
||||
host.run_command(["python", "manage.py", "migrate"],
|
||||
cwd=f"{dir}/src/ipa-tuura")
|
||||
|
||||
@@ -102,7 +102,7 @@ class KRB5PrincipalName(univ.Sequence):
|
||||
|
||||
|
||||
def profile_ca(builder, ca_nick, ca):
|
||||
now = datetime.datetime.now(tz=datetime.UTC)
|
||||
now = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
|
||||
builder = builder.not_valid_before(now)
|
||||
builder = builder.not_valid_after(now + 10 * YEAR)
|
||||
@@ -174,7 +174,7 @@ def profile_ca(builder, ca_nick, ca):
|
||||
def profile_server(builder, ca_nick, ca,
|
||||
warp=datetime.timedelta(days=0), dns_name=None,
|
||||
badusage=False, wildcard=False):
|
||||
now = datetime.datetime.now(tz=datetime.UTC) + warp
|
||||
now = datetime.datetime.now(tz=datetime.timezone.utc) + warp
|
||||
|
||||
builder = builder.not_valid_before(now)
|
||||
builder = builder.not_valid_after(now + YEAR)
|
||||
@@ -231,7 +231,7 @@ def profile_server(builder, ca_nick, ca,
|
||||
def profile_kdc(builder, ca_nick, ca,
|
||||
warp=datetime.timedelta(days=0), dns_name=None,
|
||||
badusage=False):
|
||||
now = datetime.datetime.now(tz=datetime.UTC) + warp
|
||||
now = datetime.datetime.now(tz=datetime.timezone.utc) + warp
|
||||
|
||||
builder = builder.not_valid_before(now)
|
||||
builder = builder.not_valid_after(now + YEAR)
|
||||
@@ -347,7 +347,7 @@ def gen_cert(profile, nick_base, subject, ca=None, **kwargs):
|
||||
|
||||
|
||||
def revoke_cert(ca, serial):
|
||||
now = datetime.datetime.now(tz=datetime.UTC)
|
||||
now = datetime.datetime.now(tz=datetime.timezone.utc)
|
||||
|
||||
crl_builder = x509.CertificateRevocationListBuilder()
|
||||
crl_builder = crl_builder.issuer_name(ca.cert.subject)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import os
|
||||
|
||||
import ipalib
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
# authenticate with host keytab and custom ccache
|
||||
os.environ.update(
|
||||
KRB5_CLIENT_KTNAME=paths.KRB5_KEYTAB,
|
||||
)
|
||||
|
||||
# custom options
|
||||
overrides = {"context": "example_cli"}
|
||||
ipalib.api.bootstrap(**overrides)
|
||||
|
||||
with ipalib.api as api:
|
||||
user = api.Command.user_show("admin")
|
||||
print(user)
|
||||
|
||||
assert not api.Backend.rpcclient.isconnected()
|
||||
@@ -604,7 +604,7 @@ def issue_and_expire_acme_cert():
|
||||
# move system date to expire acme cert
|
||||
for host in hosts:
|
||||
tasks.kdestroy_all(host)
|
||||
tasks.move_date(host, 'stop', '+90days+60minutes')
|
||||
tasks.move_date(host, 'stop', '+90days+2hours')
|
||||
|
||||
# restart ipa services as date moved and wait to get things settle
|
||||
time.sleep(10)
|
||||
@@ -630,7 +630,7 @@ def issue_and_expire_acme_cert():
|
||||
|
||||
# move back date
|
||||
for host in hosts:
|
||||
tasks.move_date(host, 'start', '-90days-60minutes')
|
||||
tasks.move_date(host, 'start', '-90days-2hours')
|
||||
|
||||
# restart ipa services as date moved and wait to get things settle
|
||||
# if the internal fixture was not called (for instance because the test
|
||||
|
||||
@@ -13,6 +13,7 @@ import random
|
||||
import shlex
|
||||
import ssl
|
||||
from itertools import chain, repeat
|
||||
import sys
|
||||
import textwrap
|
||||
import time
|
||||
import pytest
|
||||
@@ -1557,6 +1558,34 @@ class TestIPACommand(IntegrationTest):
|
||||
|
||||
assert 'Discovered server %s' % self.master.hostname in result
|
||||
|
||||
def test_ipa_context_manager(self):
|
||||
"""Exercise ipalib.api context manager and KRB5_CLIENT_KTNAME auth
|
||||
|
||||
The example_cli.py script uses the context manager to connect and
|
||||
disconnect the global ipalib.api object. The test also checks whether
|
||||
KRB5_CLIENT_KTNAME env var automatically acquires a TGT.
|
||||
"""
|
||||
host = self.clients[0]
|
||||
tasks.kdestroy_all(host)
|
||||
|
||||
here = os.path.abspath(os.path.dirname(__file__))
|
||||
with open(os.path.join(here, "example_cli.py")) as f:
|
||||
contents = f.read()
|
||||
|
||||
# upload script and run with Python executable
|
||||
script = "/tmp/example_cli.py"
|
||||
host.put_file_contents(script, contents)
|
||||
result = host.run_command([sys.executable, script])
|
||||
|
||||
# script prints admin account
|
||||
admin_princ = f"admin@{host.domain.realm}"
|
||||
assert admin_princ in result.stdout_text
|
||||
|
||||
# verify that auto-login did use correct principal
|
||||
host_princ = f"host/{host.hostname}@{host.domain.realm}"
|
||||
result = host.run_command([paths.KLIST])
|
||||
assert host_princ in result.stdout_text
|
||||
|
||||
|
||||
class TestIPACommandWithoutReplica(IntegrationTest):
|
||||
"""
|
||||
|
||||
@@ -467,7 +467,8 @@ class TestEPN(IntegrationTest):
|
||||
extra_args=[
|
||||
"--password-expiration",
|
||||
datetime_to_generalized_time(
|
||||
datetime.datetime.now(tz=datetime.UTC) + datetime.timedelta(
|
||||
datetime.datetime.now(
|
||||
tz=datetime.timezone.utc) + datetime.timedelta(
|
||||
days=7)
|
||||
),
|
||||
],
|
||||
@@ -496,7 +497,8 @@ class TestEPN(IntegrationTest):
|
||||
uid=uid,
|
||||
days=i,
|
||||
krbpasswordexpiration=datetime_to_generalized_time(
|
||||
datetime.datetime.now(tz=datetime.UTC) + datetime.timedelta(
|
||||
datetime.datetime.now(
|
||||
tz=datetime.timezone.utc) + datetime.timedelta(
|
||||
days=i)
|
||||
),
|
||||
)
|
||||
@@ -812,7 +814,8 @@ class TestEPN(IntegrationTest):
|
||||
self.master.run_command(
|
||||
['ipa', 'user-mod', 'admin', '--password-expiration',
|
||||
datetime_to_generalized_time(
|
||||
datetime.datetime.now(tz=datetime.UTC) + datetime.timedelta(
|
||||
datetime.datetime.now(
|
||||
tz=datetime.timezone.utc) + datetime.timedelta(
|
||||
days=7)
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -695,7 +695,7 @@ def get_pki_tomcatd_pid(host):
|
||||
def get_ipa_services_pids(host):
|
||||
ipa_services_name = [
|
||||
"krb5kdc", "kadmin", "named", "httpd", "ipa-custodia",
|
||||
"pki_tomcatd", "ipa-dnskeysyncd"
|
||||
"pki_tomcatd"
|
||||
]
|
||||
pids_of_ipa_services = {}
|
||||
for name in ipa_services_name:
|
||||
|
||||
@@ -408,6 +408,9 @@ class TestCertFixReplica(IntegrationTest):
|
||||
# move system date to expire certs
|
||||
for host in self.master, self.replicas[0]:
|
||||
tasks.move_date(host, 'stop', '+3years+1days')
|
||||
host.run_command(
|
||||
['ipactl', 'restart', '--ignore-service-failures']
|
||||
)
|
||||
|
||||
yield
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ Tests to verify that the ipa-healthcheck scenarios
|
||||
from __future__ import absolute_import
|
||||
|
||||
from configparser import RawConfigParser, NoOptionError
|
||||
from datetime import datetime, timedelta, UTC
|
||||
from datetime import datetime, timedelta, timezone
|
||||
UTC = timezone.utc
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
@@ -1639,13 +1640,19 @@ class TestIpaHealthCheckWithoutDNS(IntegrationTest):
|
||||
"Got {count} ipa-ca AAAA records, expected {expected}",
|
||||
"Expected URI record missing",
|
||||
}
|
||||
else:
|
||||
elif (parse_version(version) < parse_version('0.13')):
|
||||
expected_msgs = {
|
||||
"Expected SRV record missing",
|
||||
"Unexpected ipa-ca address {ipaddr}",
|
||||
"expected ipa-ca to contain {ipaddr} for {server}",
|
||||
"Expected URI record missing",
|
||||
}
|
||||
else:
|
||||
expected_msgs = {
|
||||
"Expected SRV record missing",
|
||||
"Expected URI record missing",
|
||||
"missing IP address for ipa-ca server {server}",
|
||||
}
|
||||
|
||||
tasks.install_packages(self.master, HEALTHCHECK_PKG)
|
||||
returncode, data = run_healthcheck(
|
||||
@@ -2405,12 +2412,19 @@ class TestIpaHealthCLI(IntegrationTest):
|
||||
cmd = self.base_cmd + ["--indent", option]
|
||||
result = self.master.run_command(cmd, raiseonerr=False)
|
||||
assert result.returncode == 2
|
||||
assert 'invalid int value' in result.stderr_text
|
||||
assert ('invalid int value' in result.stderr_text
|
||||
or 'is not an integer' in result.stderr_text)
|
||||
|
||||
# unusual success, arguably odd but not invalid :-)
|
||||
version = tasks.get_healthcheck_version(self.master)
|
||||
for option in ('-1', '5000'):
|
||||
cmd = self.base_cmd + ["--indent", option]
|
||||
result = self.master.run_command(cmd)
|
||||
result = self.master.run_command(cmd, raiseonerr=False)
|
||||
if parse_version(version) >= parse_version('0.13'):
|
||||
assert result.returncode == 2
|
||||
assert 'is not in the range 0-32' in result.stderr_text
|
||||
else:
|
||||
# Older versions did not check for a given allowed range
|
||||
assert result.returncode == 0
|
||||
|
||||
def test_severity(self):
|
||||
"""
|
||||
|
||||
@@ -234,8 +234,10 @@ class test_x509:
|
||||
# Verify certificate contents. This exercises python-cryptography
|
||||
# more than anything but confirms our usage of it.
|
||||
|
||||
not_before = datetime.datetime(2010, 6, 25, 13, 0, 42, 0, datetime.UTC)
|
||||
not_after = datetime.datetime(2015, 6, 25, 13, 0, 42, 0, datetime.UTC)
|
||||
not_before = datetime.datetime(2010, 6, 25, 13, 0, 42, 0,
|
||||
datetime.timezone.utc)
|
||||
not_after = datetime.datetime(2015, 6, 25, 13, 0, 42, 0,
|
||||
datetime.timezone.utc)
|
||||
cert = x509.load_pem_x509_certificate(goodcert_headers)
|
||||
|
||||
assert DN(cert.subject) == DN(('CN', 'ipa.example.com'), ('O', 'IPA'))
|
||||
@@ -279,8 +281,10 @@ class test_x509:
|
||||
assert DN(cert.issuer) == DN(
|
||||
"CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US")
|
||||
assert cert.serial_number == 0x03ad42a2a5ada59a131327cb0979623cb605
|
||||
not_before = datetime.datetime(2018, 7, 25, 5, 36, 59, 0, datetime.UTC)
|
||||
not_after = datetime.datetime(2018, 10, 23, 5, 36, 59, 0, datetime.UTC)
|
||||
not_before = datetime.datetime(2018, 7, 25, 5, 36, 59, 0,
|
||||
datetime.timezone.utc)
|
||||
not_after = datetime.datetime(2018, 10, 23, 5, 36, 59, 0,
|
||||
datetime.timezone.utc)
|
||||
assert cert.not_valid_before == not_before
|
||||
assert cert.not_valid_after == not_after
|
||||
assert cert.san_general_names == [DNSName('ipa.demo1.freeipa.org')]
|
||||
|
||||
@@ -402,7 +402,9 @@ class TestHTTPReturn:
|
||||
assert cookie.http_return_ok(self.url)
|
||||
|
||||
def test_expires(self):
|
||||
now = datetime.datetime.now(tz=datetime.UTC).replace(microsecond=0)
|
||||
now = datetime.datetime.now(
|
||||
tz=datetime.timezone.utc).replace(
|
||||
microsecond=0)
|
||||
|
||||
# expires 1 day from now
|
||||
expires = now + datetime.timedelta(days=1)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
# Copyright (C) 2018 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
from datetime import datetime, timedelta, UTC
|
||||
|
||||
from datetime import datetime, timedelta, timezone
|
||||
UTC = timezone.utc
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization, hashes
|
||||
|
||||
@@ -473,14 +473,23 @@ class test_cert_revocation(BaseCert):
|
||||
add=True, all=True)['result']
|
||||
serial_number = res['serial_number']
|
||||
|
||||
# REMOVE_FROM_CRL (8) needs to be on hold to revoke per RFC 5280
|
||||
if reason == 8:
|
||||
assert 'result' in api.Command['cert_revoke'](
|
||||
serial_number, revocation_reason=6)
|
||||
|
||||
# revoke created certificate
|
||||
assert 'result' in api.Command['cert_revoke'](
|
||||
serial_number, revocation_reason=reason)
|
||||
|
||||
# verify that certificate is revoked with correct reason
|
||||
res2 = api.Command['cert_show'](serial_number, all=True)['result']
|
||||
assert res2['revoked']
|
||||
assert res2['revocation_reason'] == reason
|
||||
|
||||
if reason == 8:
|
||||
assert res2['revoked'] is False
|
||||
else:
|
||||
assert res2['revoked']
|
||||
assert res2['revocation_reason'] == reason
|
||||
|
||||
# remove host
|
||||
assert 'result' in api.Command['host_del'](self.host_fqdn)
|
||||
|
||||
@@ -166,6 +166,20 @@ def user_radius(request, xmlrpc_setup):
|
||||
return tracker.make_fixture(request)
|
||||
|
||||
|
||||
@pytest.fixture(scope='class')
|
||||
def user_idp(request, xmlrpc_setup):
|
||||
""" User tracker fixture for testing users with idp user id """
|
||||
tracker = UserTracker(name='idpuser', givenname='idp',
|
||||
sn='user', ipaidpsub='myidpuserid')
|
||||
tracker.track_create()
|
||||
tracker.attrs.update(ipaidpsub=['myidpuserid'])
|
||||
tracker.attrs.update(objectclass=fuzzy_set_optional_oc(
|
||||
objectclasses.user + [u'ipaidpuser'],
|
||||
'ipantuserattrs'),
|
||||
)
|
||||
return tracker.make_fixture(request)
|
||||
|
||||
|
||||
@pytest.fixture(scope='class')
|
||||
def group(request, xmlrpc_setup):
|
||||
tracker = GroupTracker(name=u'group1')
|
||||
@@ -557,6 +571,15 @@ class TestUpdate(XMLRPC_test):
|
||||
)):
|
||||
command()
|
||||
|
||||
def test_update_add_idpsub(self, user):
|
||||
""" Test user-mod --idp-user-id"""
|
||||
user.ensure_exists()
|
||||
command = user.make_update_command(
|
||||
updates=dict(ipaidpsub=u'myidp_user_id')
|
||||
)
|
||||
command()
|
||||
user.delete()
|
||||
|
||||
|
||||
@pytest.mark.tier1
|
||||
class TestCreate(XMLRPC_test):
|
||||
@@ -796,6 +819,13 @@ class TestCreate(XMLRPC_test):
|
||||
)):
|
||||
testuser.create()
|
||||
|
||||
def test_create_with_idpsub(self, user_idp):
|
||||
""" Test creation of a user with --idp-user-id"""
|
||||
command = user_idp.make_create_command()
|
||||
result = command()
|
||||
user_idp.check_create(result, ['ipaidpsub'])
|
||||
user_idp.delete()
|
||||
|
||||
|
||||
@pytest.mark.tier1
|
||||
class TestUserWithGroup(XMLRPC_test):
|
||||
|
||||
+8241
-8240
File diff suppressed because it is too large.
Load diff
@@ -106,6 +106,8 @@ corenet_tcp_connect_radius_port(ipa_otpd_t)
|
||||
|
||||
dev_read_urand(ipa_otpd_t)
|
||||
dev_read_rand(ipa_otpd_t)
|
||||
dev_read_sysfs(ipa_otpd_t)
|
||||
dev_rw_generic_usb_dev(ipa_otpd_t)
|
||||
|
||||
sysnet_dns_name_resolve(ipa_otpd_t)
|
||||
|
||||
|
||||
Reference in new issue
Block a user