ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# Authors: Simo Sorce <ssorce@redhat.com>
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# Alexander Bokovoy <abokovoy@redhat.com>
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# Tomas Babej <tbabej@redhat.com>
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R#
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# Copyright (C) 2007-2014 Red Hat
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# see file 'COPYING' for use and warranty information
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R#
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# This program is free software; you can redistribute it and/or modify
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# it under the terms of the GNU General Public License as published by
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# the Free Software Foundation, either version 3 of the License, or
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# (at your option) any later version.
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R#
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# This program is distributed in the hope that it will be useful,
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# but WITHOUT ANY WARRANTY; without even the implied warranty of
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# GNU General Public License for more details.
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R#
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# You should have received a copy of the GNU General Public License
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R# along with this program. If not, see <http://www.gnu.org/licenses/>.
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R""" Authconfig Module """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.Rfrom __future__ import print_function
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.Rfrom subprocess import CalledProcessError
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.Rimport os
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.RFILES_TO_NOT_BACKUP = ['passwd', 'group', 'shadow', 'gshadow']
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.Rclass RedHatAuthConfig(object):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
b6ece28856aa36dba6304dca4bac57f552ff0a6aRené Genz AuthConfig class implements a system-independent interface to configure
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R system authentication resources. In Red Hat systems this is done with
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R authconfig(8) utility.
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R AuthConfig class is nothing more than a tool to gather configuration
b6ece28856aa36dba6304dca4bac57f552ff0a6aRené Genz options and execute their processing. These options are then converted by
b6ece28856aa36dba6304dca4bac57f552ff0a6aRené Genz an actual implementation to a series of system calls to appropriate
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R utilities performing real configuration.
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R If you need to re-use existing AuthConfig instance for multiple runs,
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R make sure to call 'AuthConfig.reset()' between the runs.
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R def __init__(self, host):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """ Initialize host
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R :param str host: hostname
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R self.host = host
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R self.parameters = {}
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R def enable(self, option):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R Option to be passed to authconfig
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R :param str option: authconfig options
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R self.parameters[option] = True
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R return self
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R def disable(self, option):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R Disable options
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R :param str option: authconfig options
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R self.parameters[option] = False
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R return self
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R def add_option(self, option):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R Add option
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R :param str option: authconfig options
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R self.parameters[option] = None
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R return self
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R def add_parameter(self, option, value):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
b6ece28856aa36dba6304dca4bac57f552ff0a6aRené Genz Add parameters
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R :param str option: authconfig options
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R :param str values: values
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R self.parameters[option] = [value]
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R return self
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R def reset(self):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R Reset to the default
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R self.parameters = {}
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R return self
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R def build_args(self):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R Build argument list from options provided
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R args = []
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R print("parameters passed: ", self.parameters)
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R for (option, value) in self.parameters.items():
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R if type(value) is bool:
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R if value:
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R args.append("--enable%s" % (option))
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R else:
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R args.append("--disable%s" % (option))
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R elif type(value) in (tuple, list):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R args.append("--%s" % (option))
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R args.append("%s" % (value[0]))
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R elif value is None:
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R args.append("--%s" % (option))
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R else:
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R args.append("--%s%s" % (option, value))
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R return args
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R def execute(self, update=True):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """ Execute authconfig command """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R if update:
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R self.add_option("update")
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R args = self.build_args()
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R auth_cmd = ['/usr/sbin/authconfig'] + args
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R cmd = self.host.run_command(auth_cmd, set_env=False, raiseonerr=False)
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R if cmd.returncode != 0:
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R raise Exception("Failed to run Authconfig")
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R def backup(self, path):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """ Backup existing authconfig options
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R :param str path: path where existing files are backed
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R cmd = self.host.run_command(['/usr/sbin/authconfig', '--savebackup',
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R path], set_env=False, raiseonerr=False)
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R if cmd.returncode != 0:
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R raise Exception("Unable to save backup")
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R # do not backup these files since we don't want to mess with
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R # users/groups during restore. Authconfig doesn't seem to mind about
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R # having them deleted from backup dir
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R files_to_remove = [os.path.join(path, f) for f in FILES_TO_NOT_BACKUP]
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R for filename in files_to_remove:
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R try:
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R self.host.run_command(['rm', '-f', filename], set_env=False)
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R except CalledProcessError:
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R pass
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R def restore(self, path):
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """ Restore from backup
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R :param str path: backup path
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R """
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R self.host.run_command(["/usr/sbin/authconfig", "--restorebackup",
ee1e4c0fa7e8a973ecf16b7535664b8f47fc7e75Niranjan M.R path], set_env=False, raiseonerr=False)