mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Introduce NSS database /etc/ipa/nssdb
This is the new default NSS database for IPA. /etc/pki/nssdb is still maintained for backward compatibility. https://fedorahosted.org/freeipa/ticket/3259 Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
committed by
Martin Kosek
parent
2421b13a9b
commit
231f57cedb
@@ -424,6 +424,7 @@ mkdir -p %{buildroot}/%{_localstatedir}/lib/ipa/backup
|
|||||||
mkdir -p %{buildroot}%{_sysconfdir}/ipa/
|
mkdir -p %{buildroot}%{_sysconfdir}/ipa/
|
||||||
/bin/touch %{buildroot}%{_sysconfdir}/ipa/default.conf
|
/bin/touch %{buildroot}%{_sysconfdir}/ipa/default.conf
|
||||||
/bin/touch %{buildroot}%{_sysconfdir}/ipa/ca.crt
|
/bin/touch %{buildroot}%{_sysconfdir}/ipa/ca.crt
|
||||||
|
mkdir -p %{buildroot}%{_sysconfdir}/ipa/nssdb
|
||||||
mkdir -p %{buildroot}/%{_localstatedir}/lib/ipa-client/sysrestore
|
mkdir -p %{buildroot}/%{_localstatedir}/lib/ipa-client/sysrestore
|
||||||
mkdir -p %{buildroot}%{_sysconfdir}/bash_completion.d
|
mkdir -p %{buildroot}%{_sysconfdir}/bash_completion.d
|
||||||
install -pm 644 contrib/completion/ipa.bash_completion %{buildroot}%{_sysconfdir}/bash_completion.d/ipa
|
install -pm 644 contrib/completion/ipa.bash_completion %{buildroot}%{_sysconfdir}/bash_completion.d/ipa
|
||||||
@@ -538,6 +539,17 @@ if [ $1 -gt 1 ] ; then
|
|||||||
/bin/systemctl condrestart ntpd.service 2>&1 || :
|
/bin/systemctl condrestart ntpd.service 2>&1 || :
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ ! -f '/etc/ipa/nssdb/cert8.db' -a $restore -ge 2 ]; then
|
||||||
|
python2 -c 'from ipapython.certdb import create_ipa_nssdb; create_ipa_nssdb()' >/dev/null 2>&1
|
||||||
|
tempfile=$(mktemp)
|
||||||
|
if certutil -L -d /etc/pki/nssdb -n 'IPA CA' -a >"$tempfile" 2>/var/log/ipaupgrade.log; then
|
||||||
|
certutil -A -d /etc/ipa/nssdb -n 'IPA CA' -t CT,C,C -a -i "$tempfile" >/var/log/ipaupgrade.log 2>&1
|
||||||
|
elif certutil -L -d /etc/pki/nssdb -n 'External CA cert' -a >"$tempfile" 2>/var/log/ipaupgrade.log; then
|
||||||
|
certutil -A -d /etc/ipa/nssdb -n 'External CA cert' -t C,, -a -i "$tempfile" >/var/log/ipaupgrade.log 2>&1
|
||||||
|
fi
|
||||||
|
rm -f "$tempfile"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
%triggerin -n freeipa-client -- openssh-server
|
%triggerin -n freeipa-client -- openssh-server
|
||||||
@@ -798,6 +810,11 @@ fi
|
|||||||
%dir %attr(0755,root,root) %{_sysconfdir}/ipa/
|
%dir %attr(0755,root,root) %{_sysconfdir}/ipa/
|
||||||
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/default.conf
|
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/default.conf
|
||||||
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/ca.crt
|
%ghost %attr(0644,root,apache) %config(noreplace) %{_sysconfdir}/ipa/ca.crt
|
||||||
|
%dir %attr(0755,root,root) %{_sysconfdir}/ipa/nssdb
|
||||||
|
%ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/cert8.db
|
||||||
|
%ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/key3.db
|
||||||
|
%ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/secmod.db
|
||||||
|
%ghost %config(noreplace) %{_sysconfdir}/ipa/nssdb/pwdfile.txt
|
||||||
|
|
||||||
%if ! %{ONLY_CLIENT}
|
%if ! %{ONLY_CLIENT}
|
||||||
%files tests -f tests-python.list
|
%files tests -f tests-python.list
|
||||||
|
@@ -46,7 +46,7 @@ try:
|
|||||||
from ipaplatform import services
|
from ipaplatform import services
|
||||||
from ipaplatform.paths import paths
|
from ipaplatform.paths import paths
|
||||||
from ipapython import ipautil, sysrestore, version, certmonger, ipaldap
|
from ipapython import ipautil, sysrestore, version, certmonger, ipaldap
|
||||||
from ipapython import kernel_keyring
|
from ipapython import kernel_keyring, certdb
|
||||||
from ipapython.config import IPAOptionParser
|
from ipapython.config import IPAOptionParser
|
||||||
from ipalib import api, errors
|
from ipalib import api, errors
|
||||||
from ipalib import x509, certstore
|
from ipalib import x509, certstore
|
||||||
@@ -550,6 +550,15 @@ def uninstall(options, env):
|
|||||||
cmonger.service_name, str(e))
|
cmonger.service_name, str(e))
|
||||||
|
|
||||||
# Remove our host cert and CA cert
|
# Remove our host cert and CA cert
|
||||||
|
for filename in (os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db'),
|
||||||
|
os.path.join(paths.IPA_NSSDB_DIR, 'key3.db'),
|
||||||
|
os.path.join(paths.IPA_NSSDB_DIR, 'secmod.db'),
|
||||||
|
os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')):
|
||||||
|
try:
|
||||||
|
os.remove(filename)
|
||||||
|
except OSError, e:
|
||||||
|
root_logger.error("Failed to remove %s: %s", filename, e)
|
||||||
|
|
||||||
purge_ipa_certs({client_nss_nickname, 'IPA CA', 'External CA cert'})
|
purge_ipa_certs({client_nss_nickname, 'IPA CA', 'External CA cert'})
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -2524,19 +2533,20 @@ def install(options, env, fstore, statestore):
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
tmp_nss_dir = tempfile.mkdtemp()
|
||||||
|
try:
|
||||||
# Add CA certs to a temporary NSS database
|
# Add CA certs to a temporary NSS database
|
||||||
try:
|
try:
|
||||||
os.mkdir(paths.IPA_NSSDB_DIR)
|
|
||||||
pwd_file = ipautil.write_tmp_file(ipautil.ipa_generate_password())
|
pwd_file = ipautil.write_tmp_file(ipautil.ipa_generate_password())
|
||||||
run([paths.CERTUTIL, '-N',
|
run([paths.CERTUTIL, '-N',
|
||||||
'-d', paths.IPA_NSSDB_DIR,
|
'-d', tmp_nss_dir,
|
||||||
'-f', pwd_file.name])
|
'-f', pwd_file.name])
|
||||||
|
|
||||||
ca_certs = x509.load_certificate_list_from_file(CACERT)
|
ca_certs = x509.load_certificate_list_from_file(CACERT)
|
||||||
ca_certs = [cert.der_data for cert in ca_certs]
|
ca_certs = [cert.der_data for cert in ca_certs]
|
||||||
for i, cert in enumerate(ca_certs):
|
for i, cert in enumerate(ca_certs):
|
||||||
run([paths.CERTUTIL, '-A',
|
run([paths.CERTUTIL, '-A',
|
||||||
'-d', paths.IPA_NSSDB_DIR,
|
'-d', tmp_nss_dir,
|
||||||
'-n', 'CA certificate %d' % (i + 1),
|
'-n', 'CA certificate %d' % (i + 1),
|
||||||
'-t', 'C,,'],
|
'-t', 'C,,'],
|
||||||
stdin=cert)
|
stdin=cert)
|
||||||
@@ -2544,42 +2554,48 @@ def install(options, env, fstore, statestore):
|
|||||||
root_logger.info("Failed to add CA to temporary NSS database.")
|
root_logger.info("Failed to add CA to temporary NSS database.")
|
||||||
return CLIENT_INSTALL_ERROR
|
return CLIENT_INSTALL_ERROR
|
||||||
|
|
||||||
# Now, let's try to connect to the server's XML-RPC interface
|
# Now, let's try to connect to the server's RPC interface
|
||||||
connected = False
|
connected = False
|
||||||
try:
|
try:
|
||||||
api.Backend.rpcclient.connect(nss_dir=paths.IPA_NSSDB_DIR)
|
api.Backend.rpcclient.connect(nss_dir=tmp_nss_dir)
|
||||||
connected = True
|
connected = True
|
||||||
root_logger.debug('Try RPC connection')
|
root_logger.debug("Try RPC connection")
|
||||||
api.Backend.rpcclient.forward('ping')
|
api.Backend.rpcclient.forward('ping')
|
||||||
except errors.KerberosError, e:
|
except errors.KerberosError, e:
|
||||||
if connected:
|
if connected:
|
||||||
api.Backend.rpcclient.disconnect()
|
api.Backend.rpcclient.disconnect()
|
||||||
root_logger.info('Cannot connect to the server due to ' +
|
root_logger.info(
|
||||||
'Kerberos error: %s. Trying with delegate=True', str(e))
|
"Cannot connect to the server due to Kerberos error: %s. "
|
||||||
|
"Trying with delegate=True", e)
|
||||||
try:
|
try:
|
||||||
api.Backend.rpcclient.connect(delegate=True, nss_dir=paths.IPA_NSSDB_DIR)
|
api.Backend.rpcclient.connect(delegate=True,
|
||||||
root_logger.debug('Try RPC connection')
|
nss_dir=tmp_nss_dir)
|
||||||
|
root_logger.debug("Try RPC connection")
|
||||||
api.Backend.rpcclient.forward('ping')
|
api.Backend.rpcclient.forward('ping')
|
||||||
|
|
||||||
root_logger.info('Connection with delegate=True successful')
|
root_logger.info("Connection with delegate=True successful")
|
||||||
|
|
||||||
# The remote server is not capable of Kerberos S4U2Proxy delegation
|
# The remote server is not capable of Kerberos S4U2Proxy
|
||||||
# This features is implemented in IPA server version 2.2 and higher
|
# delegation. This features is implemented in IPA server
|
||||||
root_logger.warning("Target IPA server has a lower version than " +
|
# version 2.2 and higher
|
||||||
"the enrolled client")
|
root_logger.warning(
|
||||||
root_logger.warning("Some capabilities including the ipa " +
|
"Target IPA server has a lower version than the enrolled "
|
||||||
"command capability may not be available")
|
"client")
|
||||||
|
root_logger.warning(
|
||||||
|
"Some capabilities including the ipa command capability "
|
||||||
|
"may not be available")
|
||||||
except errors.PublicError, e2:
|
except errors.PublicError, e2:
|
||||||
root_logger.warning(
|
root_logger.warning(
|
||||||
'Second connect with delegate=True also failed: %s', str(e2))
|
"Second connect with delegate=True also failed: %s", e2)
|
||||||
root_logger.error(
|
root_logger.error(
|
||||||
"Cannot connect to the IPA server XML-RPC interface: %s",
|
"Cannot connect to the IPA server RPC interface: %s", e2)
|
||||||
str(e2))
|
|
||||||
return CLIENT_INSTALL_ERROR
|
return CLIENT_INSTALL_ERROR
|
||||||
except errors.PublicError, e:
|
except errors.PublicError, e:
|
||||||
root_logger.error(
|
root_logger.error(
|
||||||
'Cannot connect to the server due to generic error: %s', str(e))
|
"Cannot connect to the server due to generic error: %s", e)
|
||||||
return CLIENT_INSTALL_ERROR
|
return CLIENT_INSTALL_ERROR
|
||||||
|
finally:
|
||||||
|
shutil.rmtree(tmp_nss_dir)
|
||||||
|
|
||||||
# Use the RPC directly so older servers are supported
|
# Use the RPC directly so older servers are supported
|
||||||
result = api.Backend.rpcclient.forward(
|
result = api.Backend.rpcclient.forward(
|
||||||
@@ -2591,14 +2607,38 @@ def install(options, env, fstore, statestore):
|
|||||||
if not remote_env['enable_ra']:
|
if not remote_env['enable_ra']:
|
||||||
disable_ra()
|
disable_ra()
|
||||||
|
|
||||||
|
# Create IPA NSS database
|
||||||
|
try:
|
||||||
|
certdb.create_ipa_nssdb()
|
||||||
|
except ipautil.CalledProcessError, e:
|
||||||
|
root_logger.error("Failed to create IPA NSS database: %s", e)
|
||||||
|
return CLIENT_INSTALL_ERROR
|
||||||
|
|
||||||
# Get CA certificates from the certificate store
|
# Get CA certificates from the certificate store
|
||||||
ca_certs = get_certs_from_ldap(cli_server[0], cli_basedn, cli_realm,
|
ca_certs = get_certs_from_ldap(cli_server[0], cli_basedn, cli_realm,
|
||||||
remote_env['enable_ra'])
|
remote_env['enable_ra'])
|
||||||
|
ca_certs_trust = [(c, n, certstore.key_policy_to_trust_flags(t, True, u))
|
||||||
|
for (c, n, t, u) in ca_certs]
|
||||||
|
|
||||||
# Add the CA to the platform-dependant systemwide CA store
|
# Add the CA certificates to the IPA NSS database
|
||||||
|
root_logger.debug("Adding CA certificates to the IPA NSS database.")
|
||||||
|
for cert, nickname, trust_flags in ca_certs_trust:
|
||||||
|
try:
|
||||||
|
run([paths.CERTUTIL,
|
||||||
|
"-A",
|
||||||
|
"-d", paths.IPA_NSSDB_DIR,
|
||||||
|
"-n", nickname,
|
||||||
|
"-t", trust_flags],
|
||||||
|
stdin=cert)
|
||||||
|
except CalledProcessError, e:
|
||||||
|
root_logger.error(
|
||||||
|
"Failed to add %s to the IPA NSS database.", nickname)
|
||||||
|
return CLIENT_INSTALL_ERROR
|
||||||
|
|
||||||
|
# Add the CA certificates to the platform-dependant systemwide CA store
|
||||||
tasks.insert_ca_certs_into_systemwide_ca_store(ca_certs)
|
tasks.insert_ca_certs_into_systemwide_ca_store(ca_certs)
|
||||||
|
|
||||||
# Add the CA to the default NSS database and trust it
|
# Add the CA certificates to the default NSS database
|
||||||
if not purge_ipa_certs():
|
if not purge_ipa_certs():
|
||||||
root_logger.info(
|
root_logger.info(
|
||||||
"Failed to remove old IPA certificates from the default NSS "
|
"Failed to remove old IPA certificates from the default NSS "
|
||||||
@@ -2611,12 +2651,10 @@ def install(options, env, fstore, statestore):
|
|||||||
root_logger.error("Failed to open /etc/pki/nssdb/ipa.txt: %s", e)
|
root_logger.error("Failed to open /etc/pki/nssdb/ipa.txt: %s", e)
|
||||||
return CLIENT_INSTALL_ERROR
|
return CLIENT_INSTALL_ERROR
|
||||||
|
|
||||||
for cert, nickname, trusted, ext_key_usage in ca_certs:
|
root_logger.debug(
|
||||||
|
"Attempting to add CA certificates to the default NSS database.")
|
||||||
|
for cert, nickname, trust_flags in ca_certs_trust:
|
||||||
try:
|
try:
|
||||||
root_logger.debug("Attempting to add CA directly to the "
|
|
||||||
"default NSS database.")
|
|
||||||
trust_flags = certstore.key_policy_to_trust_flags(
|
|
||||||
trusted, True, ext_key_usage)
|
|
||||||
run([paths.CERTUTIL,
|
run([paths.CERTUTIL,
|
||||||
"-A",
|
"-A",
|
||||||
"-d", paths.NSS_DB_DIR,
|
"-d", paths.NSS_DB_DIR,
|
||||||
@@ -2624,12 +2662,13 @@ def install(options, env, fstore, statestore):
|
|||||||
"-t", trust_flags],
|
"-t", trust_flags],
|
||||||
stdin=cert)
|
stdin=cert)
|
||||||
except CalledProcessError, e:
|
except CalledProcessError, e:
|
||||||
root_logger.info("Failed to add CA to the default NSS database.")
|
root_logger.error(
|
||||||
|
"Failed to add %s to the default NSS database.", nickname)
|
||||||
list_file.close()
|
list_file.close()
|
||||||
return CLIENT_INSTALL_ERROR
|
return CLIENT_INSTALL_ERROR
|
||||||
else:
|
else:
|
||||||
root_logger.info('Added the CA to the default NSS database.')
|
|
||||||
list_file.write(nickname + '\n')
|
list_file.write(nickname + '\n')
|
||||||
|
root_logger.info("Added CA certificates to the default NSS database.")
|
||||||
|
|
||||||
list_file.close()
|
list_file.close()
|
||||||
|
|
||||||
@@ -2855,7 +2894,3 @@ finally:
|
|||||||
os.remove(CCACHE_FILE)
|
os.remove(CCACHE_FILE)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
try:
|
|
||||||
shutil.rmtree(paths.IPA_NSSDB_DIR)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
@@ -70,6 +70,15 @@ class CertUpdate(admintool.AdminTool):
|
|||||||
|
|
||||||
def update_client(self, certs):
|
def update_client(self, certs):
|
||||||
self.update_file(paths.IPA_CA_CRT, certs)
|
self.update_file(paths.IPA_CA_CRT, certs)
|
||||||
|
self.update_db(paths.IPA_NSSDB_DIR, certs)
|
||||||
|
|
||||||
|
for nickname in ('IPA CA', 'External CA cert'):
|
||||||
|
try:
|
||||||
|
ipautil.run([paths.CERTUTIL, '-D',
|
||||||
|
'-d', paths.NSS_DB_DIR,
|
||||||
|
'-n', nickname])
|
||||||
|
except ipautil.CalledProcessError, e:
|
||||||
|
pass
|
||||||
|
|
||||||
self.update_db(paths.NSS_DB_DIR, certs)
|
self.update_db(paths.NSS_DB_DIR, certs)
|
||||||
|
|
||||||
|
@@ -483,7 +483,7 @@ class SSLTransport(LanguageAwareTransport):
|
|||||||
if self._connection and host == self._connection[0]:
|
if self._connection and host == self._connection[0]:
|
||||||
return self._connection[1]
|
return self._connection[1]
|
||||||
|
|
||||||
dbdir = getattr(context, 'nss_dir', paths.NSS_DB_DIR)
|
dbdir = getattr(context, 'nss_dir', paths.IPA_NSSDB_DIR)
|
||||||
no_init = self.__nss_initialized(dbdir)
|
no_init = self.__nss_initialized(dbdir)
|
||||||
if sys.version_info < (2, 7):
|
if sys.version_info < (2, 7):
|
||||||
conn = NSSHTTPS(host, 443, dbdir=dbdir, no_init=no_init)
|
conn = NSSHTTPS(host, 443, dbdir=dbdir, no_init=no_init)
|
||||||
|
@@ -63,7 +63,7 @@ class BasePathNamespace(object):
|
|||||||
IPA_DNS_UPDATE_TXT = "/etc/ipa/.dns_update.txt"
|
IPA_DNS_UPDATE_TXT = "/etc/ipa/.dns_update.txt"
|
||||||
IPA_CA_CRT = "/etc/ipa/ca.crt"
|
IPA_CA_CRT = "/etc/ipa/ca.crt"
|
||||||
IPA_DEFAULT_CONF = "/etc/ipa/default.conf"
|
IPA_DEFAULT_CONF = "/etc/ipa/default.conf"
|
||||||
IPA_NSSDB_DIR = "/etc/ipa/.nssdb"
|
IPA_NSSDB_DIR = "/etc/ipa/nssdb"
|
||||||
KRB5_CONF = "/etc/krb5.conf"
|
KRB5_CONF = "/etc/krb5.conf"
|
||||||
KRB5_KEYTAB = "/etc/krb5.keytab"
|
KRB5_KEYTAB = "/etc/krb5.keytab"
|
||||||
LDAP_CONF = "/etc/ldap.conf"
|
LDAP_CONF = "/etc/ldap.conf"
|
||||||
|
@@ -17,6 +17,34 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from ipaplatform.paths import paths
|
||||||
|
from ipapython import ipautil
|
||||||
|
|
||||||
CA_NICKNAME_FMT = "%s IPA CA"
|
CA_NICKNAME_FMT = "%s IPA CA"
|
||||||
|
|
||||||
|
|
||||||
def get_ca_nickname(realm, format=CA_NICKNAME_FMT):
|
def get_ca_nickname(realm, format=CA_NICKNAME_FMT):
|
||||||
return format % realm
|
return format % realm
|
||||||
|
|
||||||
|
|
||||||
|
def create_ipa_nssdb():
|
||||||
|
pwdfile = os.path.join(paths.IPA_NSSDB_DIR, 'pwdfile.txt')
|
||||||
|
|
||||||
|
ipautil.backup_file(pwdfile)
|
||||||
|
ipautil.backup_file(os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db'))
|
||||||
|
ipautil.backup_file(os.path.join(paths.IPA_NSSDB_DIR, 'key3.db'))
|
||||||
|
ipautil.backup_file(os.path.join(paths.IPA_NSSDB_DIR, 'secmod.db'))
|
||||||
|
|
||||||
|
with open(pwdfile, 'w') as f:
|
||||||
|
f.write(ipautil.ipa_generate_password(pwd_len=40))
|
||||||
|
os.chmod(pwdfile, 0600)
|
||||||
|
|
||||||
|
ipautil.run([paths.CERTUTIL,
|
||||||
|
"-N",
|
||||||
|
"-d", paths.IPA_NSSDB_DIR,
|
||||||
|
"-f", pwdfile])
|
||||||
|
os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'cert8.db'), 0644)
|
||||||
|
os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'key3.db'), 0644)
|
||||||
|
os.chmod(os.path.join(paths.IPA_NSSDB_DIR, 'secmod.db'), 0644)
|
||||||
|
Reference in New Issue
Block a user