mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-01-26 16:16:31 -06:00
Use tasks to configure automount nsswitch settings
authselect doesn't allow one to directly write to /etc/nsswitch.conf. It will complain bitterly if it detects it and will refuse to work until reset. Instead it wants the user to write to /etc/authselect/user-nsswitch.conf and then it will handle merging in any differences. To complicate matters some databases are not user configurable like passwd, group and of course, automount. There are some undocumented options to allow one to override these though so we utilize that. tasks are used so that authselect-based installations can still write directly to /etc/nsswitch.conf and operate as it used to. Reviewed-By: Francois Cami <fcami@redhat.com> Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
parent
e5af8c19a9
commit
41ef8fba31
@ -66,7 +66,7 @@ from ipapython import version
|
||||
|
||||
from . import automount, timeconf, sssd
|
||||
from ipaclient import discovery
|
||||
from .ipachangeconf import IPAChangeConf
|
||||
from ipapython.ipachangeconf import IPAChangeConf
|
||||
|
||||
NoneType = type(None)
|
||||
|
||||
@ -281,72 +281,6 @@ def is_ipa_client_installed(fstore, on_master=False):
|
||||
return installed
|
||||
|
||||
|
||||
def configure_nsswitch_database(fstore, database, services, preserve=True,
|
||||
append=True, default_value=()):
|
||||
"""
|
||||
Edits the specified nsswitch.conf database (e.g. passwd, group, sudoers)
|
||||
to use the specified service(s).
|
||||
|
||||
Arguments:
|
||||
fstore - FileStore to backup the nsswitch.conf
|
||||
database - database configuration that should be ammended,
|
||||
e.g. 'sudoers'
|
||||
service - list of services that should be added, e.g. ['sss']
|
||||
preserve - if True, the already configured services will be preserved
|
||||
|
||||
The next arguments modify the behaviour if preserve=True:
|
||||
append - if True, the services will be appended, if False, prepended
|
||||
default_value - list of services that are considered as default (if
|
||||
the database is not mentioned in nsswitch.conf), e.g.
|
||||
['files']
|
||||
"""
|
||||
|
||||
# Backup the original version of nsswitch.conf, we're going to edit it now
|
||||
if not fstore.has_file(paths.NSSWITCH_CONF):
|
||||
fstore.backup_file(paths.NSSWITCH_CONF)
|
||||
|
||||
conf = IPAChangeConf("IPA Installer")
|
||||
conf.setOptionAssignment(':')
|
||||
|
||||
if preserve:
|
||||
# Read the existing configuration
|
||||
with open(paths.NSSWITCH_CONF, 'r') as f:
|
||||
opts = conf.parse(f)
|
||||
raw_database_entry = conf.findOpts(opts, 'option', database)[1]
|
||||
|
||||
# Detect the list of already configured services
|
||||
if not raw_database_entry:
|
||||
# If there is no database entry, database is not present in
|
||||
# the nsswitch.conf. Set the list of services to the
|
||||
# default list, if passed.
|
||||
configured_services = list(default_value)
|
||||
else:
|
||||
configured_services = raw_database_entry['value'].strip().split()
|
||||
|
||||
# Make sure no service is added if already mentioned in the list
|
||||
added_services = [s for s in services
|
||||
if s not in configured_services]
|
||||
|
||||
# Prepend / append the list of new services
|
||||
if append:
|
||||
new_value = ' ' + ' '.join(configured_services + added_services)
|
||||
else:
|
||||
new_value = ' ' + ' '.join(added_services + configured_services)
|
||||
|
||||
else:
|
||||
# Preserve not set, let's rewrite existing configuration
|
||||
new_value = ' ' + ' '.join(services)
|
||||
|
||||
# Set new services as sources for database
|
||||
opts = [
|
||||
conf.setOption(database, new_value),
|
||||
conf.emptyLine(),
|
||||
]
|
||||
|
||||
conf.changeConf(paths.NSSWITCH_CONF, opts)
|
||||
logger.info("Configured %s in %s", database, paths.NSSWITCH_CONF)
|
||||
|
||||
|
||||
def configure_ipa_conf(
|
||||
fstore, cli_basedn, cli_realm, cli_domain, cli_server, hostname):
|
||||
ipaconf = IPAChangeConf("IPA Installer")
|
||||
@ -948,9 +882,7 @@ def configure_sssd_conf(
|
||||
"Unable to activate the SUDO service in SSSD config.")
|
||||
|
||||
sssdconfig.activate_service('sudo')
|
||||
configure_nsswitch_database(
|
||||
fstore, 'sudoers', ['sss'],
|
||||
default_value=['files'])
|
||||
tasks.enable_sssd_sudo(fstore)
|
||||
|
||||
domain.add_provider('ipa', 'id')
|
||||
|
||||
|
@ -41,7 +41,8 @@ from six.moves.urllib.parse import urlsplit
|
||||
|
||||
# pylint: enable=import-error
|
||||
from optparse import OptionParser # pylint: disable=deprecated-module
|
||||
from ipaclient.install import ipachangeconf, ipadiscovery
|
||||
from ipapython import ipachangeconf
|
||||
from ipaclient.install import ipadiscovery
|
||||
from ipaclient.install.client import (
|
||||
CLIENT_NOT_CONFIGURED,
|
||||
CLIENT_ALREADY_CONFIGURED,
|
||||
@ -177,44 +178,6 @@ def configure_xml(fstore):
|
||||
print("Configured %s" % authconf)
|
||||
|
||||
|
||||
def configure_nsswitch(statestore, options):
|
||||
"""
|
||||
Point automount to ldap in nsswitch.conf.
|
||||
This function is for non-SSSD setups only.
|
||||
"""
|
||||
conf = ipachangeconf.IPAChangeConf("IPA Installer")
|
||||
conf.setOptionAssignment(':')
|
||||
|
||||
with open(paths.NSSWITCH_CONF, 'r') as f:
|
||||
current_opts = conf.parse(f)
|
||||
current_nss_value = conf.findOpts(
|
||||
current_opts, name='automount', type='option'
|
||||
)[1]
|
||||
if current_nss_value is None:
|
||||
# no automount database present
|
||||
current_nss_value = False # None cannot be backed up
|
||||
else:
|
||||
current_nss_value = current_nss_value['value']
|
||||
statestore.backup_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount',
|
||||
current_nss_value
|
||||
)
|
||||
|
||||
nss_value = ' files ldap'
|
||||
opts = [
|
||||
{
|
||||
'name': 'automount',
|
||||
'type': 'option',
|
||||
'action': 'set',
|
||||
'value': nss_value,
|
||||
},
|
||||
{'name': 'empty', 'type': 'empty'},
|
||||
]
|
||||
conf.changeConf(paths.NSSWITCH_CONF, opts)
|
||||
|
||||
print("Configured %s" % paths.NSSWITCH_CONF)
|
||||
|
||||
|
||||
def configure_autofs_sssd(fstore, statestore, autodiscover, options):
|
||||
try:
|
||||
sssdconfig = SSSDConfig.SSSDConfig()
|
||||
@ -339,41 +302,8 @@ def uninstall(fstore, statestore):
|
||||
]
|
||||
STATES = ['autofs', 'rpcidmapd', 'rpcgssd']
|
||||
|
||||
if statestore.get_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
) is False:
|
||||
# Previous nsswitch.conf had no automount database configured
|
||||
# so remove it.
|
||||
conf = ipachangeconf.IPAChangeConf("IPA automount installer")
|
||||
conf.setOptionAssignment(':')
|
||||
changes = [conf.rmOption('automount')]
|
||||
conf.changeConf(paths.NSSWITCH_CONF, changes)
|
||||
tasks.restore_context(paths.NSSWITCH_CONF)
|
||||
statestore.delete_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
)
|
||||
elif statestore.get_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
) is not None:
|
||||
nss_value = statestore.get_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
)
|
||||
opts = [
|
||||
{
|
||||
'name': 'automount',
|
||||
'type': 'option',
|
||||
'action': 'set',
|
||||
'value': nss_value,
|
||||
},
|
||||
{'name': 'empty', 'type': 'empty'},
|
||||
]
|
||||
conf = ipachangeconf.IPAChangeConf("IPA automount installer")
|
||||
conf.setOptionAssignment(':')
|
||||
conf.changeConf(paths.NSSWITCH_CONF, opts)
|
||||
tasks.restore_context(paths.NSSWITCH_CONF)
|
||||
statestore.delete_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
)
|
||||
if not statestore.get_state('autofs', 'sssd'):
|
||||
tasks.disable_ldap_automount(statestore)
|
||||
|
||||
if not any(fstore.has_file(f) for f in RESTORE_FILES) or not any(
|
||||
statestore.has_state(s) for s in STATES
|
||||
@ -627,7 +557,7 @@ def configure_automount():
|
||||
|
||||
try:
|
||||
if not options.sssd:
|
||||
configure_nsswitch(statestore, options)
|
||||
tasks.enable_ldap_automount(statestore)
|
||||
configure_nfs(fstore, statestore, options)
|
||||
if options.sssd:
|
||||
configure_autofs_sssd(fstore, statestore, autodiscover, options)
|
||||
|
@ -32,6 +32,7 @@ from pkg_resources import parse_version
|
||||
from ipaplatform.constants import constants
|
||||
from ipaplatform.paths import paths
|
||||
from ipapython import ipautil
|
||||
from ipapython.ipachangeconf import IPAChangeConf
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -337,5 +338,157 @@ class BaseTaskNamespace:
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def configure_nsswitch_database(self, fstore, database, services,
|
||||
preserve=True, append=True,
|
||||
default_value=()):
|
||||
"""
|
||||
Edits the specified nsswitch.conf database (e.g. passwd, group,
|
||||
sudoers) to use the specified service(s).
|
||||
|
||||
Arguments:
|
||||
fstore - FileStore to backup the nsswitch.conf
|
||||
database - database configuration that should be ammended,
|
||||
e.g. 'sudoers'
|
||||
service - list of services that should be added, e.g. ['sss']
|
||||
preserve - if True, the already configured services will be
|
||||
preserved
|
||||
|
||||
The next arguments modify the behaviour if preserve=True:
|
||||
append - if True, the services will be appended, if False,
|
||||
prepended
|
||||
default_value - list of services that are considered as default (if
|
||||
the database is not mentioned in nsswitch.conf),
|
||||
e.g. ['files']
|
||||
"""
|
||||
|
||||
# Backup the original version of nsswitch.conf, we're going to edit it
|
||||
# now
|
||||
if not fstore.has_file(paths.NSSWITCH_CONF):
|
||||
fstore.backup_file(paths.NSSWITCH_CONF)
|
||||
|
||||
conf = IPAChangeConf("IPA Installer")
|
||||
conf.setOptionAssignment(':')
|
||||
|
||||
if preserve:
|
||||
# Read the existing configuration
|
||||
with open(paths.NSSWITCH_CONF, 'r') as f:
|
||||
opts = conf.parse(f)
|
||||
raw_database_entry = conf.findOpts(opts, 'option', database)[1]
|
||||
|
||||
# Detect the list of already configured services
|
||||
if not raw_database_entry:
|
||||
# If there is no database entry, database is not present in
|
||||
# the nsswitch.conf. Set the list of services to the
|
||||
# default list, if passed.
|
||||
configured_services = list(default_value)
|
||||
else:
|
||||
configured_services = raw_database_entry[
|
||||
'value'].strip().split()
|
||||
|
||||
# Make sure no service is added if already mentioned in the list
|
||||
added_services = [s for s in services
|
||||
if s not in configured_services]
|
||||
|
||||
# Prepend / append the list of new services
|
||||
if append:
|
||||
new_value = ' ' + ' '.join(configured_services +
|
||||
added_services)
|
||||
else:
|
||||
new_value = ' ' + ' '.join(added_services +
|
||||
configured_services)
|
||||
|
||||
else:
|
||||
# Preserve not set, let's rewrite existing configuration
|
||||
new_value = ' ' + ' '.join(services)
|
||||
|
||||
# Set new services as sources for database
|
||||
opts = [
|
||||
conf.setOption(database, new_value),
|
||||
conf.emptyLine(),
|
||||
]
|
||||
|
||||
conf.changeConf(paths.NSSWITCH_CONF, opts)
|
||||
logger.info("Configured %s in %s", database, paths.NSSWITCH_CONF)
|
||||
|
||||
def enable_sssd_sudo(self, fstore):
|
||||
"""Configure nsswitch.conf to use sssd for sudo"""
|
||||
self.configure_nsswitch_database(
|
||||
fstore, 'sudoers', ['sss'],
|
||||
default_value=['files'])
|
||||
|
||||
def enable_ldap_automount(self, statestore):
|
||||
"""
|
||||
Point automount to ldap in nsswitch.conf.
|
||||
This function is for non-SSSD setups only.
|
||||
"""
|
||||
conf = IPAChangeConf("IPA Installer")
|
||||
conf.setOptionAssignment(':')
|
||||
|
||||
with open(paths.NSSWITCH_CONF, 'r') as f:
|
||||
current_opts = conf.parse(f)
|
||||
current_nss_value = conf.findOpts(
|
||||
current_opts, name='automount', type='option'
|
||||
)[1]
|
||||
if current_nss_value is None:
|
||||
# no automount database present
|
||||
current_nss_value = False # None cannot be backed up
|
||||
else:
|
||||
current_nss_value = current_nss_value['value']
|
||||
statestore.backup_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount',
|
||||
current_nss_value
|
||||
)
|
||||
|
||||
nss_value = ' files ldap'
|
||||
opts = [
|
||||
{
|
||||
'name': 'automount',
|
||||
'type': 'option',
|
||||
'action': 'set',
|
||||
'value': nss_value,
|
||||
},
|
||||
{'name': 'empty', 'type': 'empty'},
|
||||
]
|
||||
conf.changeConf(paths.NSSWITCH_CONF, opts)
|
||||
|
||||
logger.info("Configured %s", paths.NSSWITCH_CONF)
|
||||
|
||||
def disable_ldap_automount(self, statestore):
|
||||
"""Disable automount using LDAP"""
|
||||
if statestore.get_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
) is False:
|
||||
# Previous nsswitch.conf had no automount database configured
|
||||
# so remove it.
|
||||
conf = IPAChangeConf("IPA automount installer")
|
||||
conf.setOptionAssignment(':')
|
||||
changes = [conf.rmOption('automount')]
|
||||
conf.changeConf(paths.NSSWITCH_CONF, changes)
|
||||
self.restore_context(paths.NSSWITCH_CONF)
|
||||
statestore.delete_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
)
|
||||
elif statestore.get_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
) is not None:
|
||||
nss_value = statestore.get_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
)
|
||||
opts = [
|
||||
{
|
||||
'name': 'automount',
|
||||
'type': 'option',
|
||||
'action': 'set',
|
||||
'value': nss_value,
|
||||
},
|
||||
{'name': 'empty', 'type': 'empty'},
|
||||
]
|
||||
conf = IPAChangeConf("IPA automount installer")
|
||||
conf.setOptionAssignment(':')
|
||||
conf.changeConf(paths.NSSWITCH_CONF, opts)
|
||||
self.restore_context(paths.NSSWITCH_CONF)
|
||||
statestore.delete_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
)
|
||||
|
||||
tasks = BaseTaskNamespace()
|
||||
|
@ -39,6 +39,7 @@ class RedHatPathNamespace(BasePathNamespace):
|
||||
AUTHCONFIG = '/usr/sbin/authconfig'
|
||||
AUTHSELECT = '/usr/bin/authselect'
|
||||
SYSCONF_NETWORK = '/etc/sysconfig/network'
|
||||
NSSWITCH_CONF = '/etc/authselect/user-nsswitch.conf'
|
||||
|
||||
|
||||
paths = RedHatPathNamespace()
|
||||
|
@ -744,4 +744,23 @@ class RedHatTaskNamespace(BaseTaskNamespace):
|
||||
|
||||
return filenames
|
||||
|
||||
def enable_ldap_automount(self, statestore):
|
||||
"""
|
||||
Point automount to ldap in nsswitch.conf.
|
||||
This function is for non-SSSD setups only.
|
||||
"""
|
||||
super(RedHatTaskNamespace, self).enable_ldap_automount(statestore)
|
||||
|
||||
authselect_cmd = [paths.AUTHSELECT, "enable-feature",
|
||||
"with-custom-automount"]
|
||||
ipautil.run(authselect_cmd)
|
||||
|
||||
def disable_ldap_automount(self, statestore):
|
||||
"""Disable ldap-based automount"""
|
||||
super(RedHatTaskNamespace, self).disable_ldap_automount(statestore)
|
||||
|
||||
authselect_cmd = [paths.AUTHSELECT, "disable-feature",
|
||||
"with-custom-automount"]
|
||||
ipautil.run(authselect_cmd)
|
||||
|
||||
tasks = RedHatTaskNamespace()
|
||||
|
Loading…
Reference in New Issue
Block a user