X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fipsilon.git;a=blobdiff_plain;f=ipsilon%2Finfo%2Finfosssd.py;h=69d68c03197b6cc9beb4d094c025c30c68b82c55;hp=b187567a1a683def448c5c8e8c1dd6b5b36c9bc3;hb=aa5dc3b417db962a075a092d0d3528010c1059f7;hpb=0e53d1f95b3bb04f82f9ceefde1ac17484986e4d diff --git a/ipsilon/info/infosssd.py b/ipsilon/info/infosssd.py index b187567..69d68c0 100644 --- a/ipsilon/info/infosssd.py +++ b/ipsilon/info/infosssd.py @@ -7,13 +7,15 @@ from ipsilon.info.common import InfoProviderBase from ipsilon.info.common import InfoProviderInstaller -from ipsilon.info.common import InfoMapping from ipsilon.util.plugin import PluginObject +from ipsilon.util.policy import Policy +from ipsilon.util import config as pconfig from string import Template import cherrypy import time import subprocess import SSSDConfig +import logging SSSD_CONF = '/etc/sssd/sssd.conf' @@ -28,26 +30,31 @@ SSSD_ATTRS = ['mail', # Map the mod_lookup_identity env variables to Ipsilon. The inverse of # this is in the httpd template. -sssd_mapping = { - 'REMOTE_USER_GECOS': 'fullname', - 'REMOTE_USER_EMAIL': 'email', - 'REMOTE_USER_FIRSTNAME': 'givenname', - 'REMOTE_USER_LASTNAME': 'surname', - 'REMOTE_USER_STREET': 'street', - 'REMOTE_USER_STATE': 'state', - 'REMOTE_USER_POSTALCODE': 'postcode', - 'REMOTE_USER_TELEPHONENUMBER': 'phone', -} +sssd_mapping = [ + ['REMOTE_USER_GECOS', 'fullname'], + ['REMOTE_USER_EMAIL', 'email'], + ['REMOTE_USER_FIRSTNAME', 'givenname'], + ['REMOTE_USER_LASTNAME', 'surname'], + ['REMOTE_USER_STREET', 'street'], + ['REMOTE_USER_STATE', 'state'], + ['REMOTE_USER_POSTALCODE', 'postcode'], + ['REMOTE_USER_TELEPHONENUMBER', 'phone'], +] class InfoProvider(InfoProviderBase): def __init__(self, *pargs): super(InfoProvider, self).__init__(*pargs) - self.mapper = InfoMapping() - self.mapper.set_mapping(sssd_mapping) + self.mapper = Policy(sssd_mapping) self.name = 'sssd' - self.new_config(self.name) + self.new_config( + self.name, + pconfig.Condition( + 'preconfigured', + 'SSSD can only be used when pre-configured', + False), + ) def _get_user_data(self, user): reply = dict() @@ -71,16 +78,28 @@ class InfoProvider(InfoProviderBase): reply = dict() try: attrs, groups = self._get_user_data(user) - userattrs, extras = self.mapper.map_attrs(attrs) - reply['userdata'] = userattrs - reply['groups'] = groups - reply['extras'] = {'sssd': extras} + userattrs, extras = self.mapper.map_attributes(attrs) + reply = userattrs + reply['_groups'] = groups + reply['_extras'] = {'sssd': extras} except KeyError: pass return reply + def save_plugin_config(self, *args, **kwargs): + raise ValueError('Configuration cannot be modified live for SSSD') + + def get_config_obj(self): + return None + + def enable(self): + self.refresh_plugin_config() + if not self.get_config_value('preconfigured'): + raise Exception("SSSD Can be enabled only if pre-configured") + super(InfoProvider, self).enable() + CONF_TEMPLATE = """ LoadModule lookup_identity_module modules/mod_lookup_identity.so @@ -110,7 +129,7 @@ class Installer(InfoProviderInstaller): default='no', help='Use mod_lookup_identity and SSSD to populate' ' user attrs') - group.add_argument('--info-sssd-domain', action='store', + group.add_argument('--info-sssd-domain', action='append', help='SSSD domain to enable mod_lookup_identity' ' for') @@ -118,9 +137,7 @@ class Installer(InfoProviderInstaller): if opts['info_sssd'] != 'yes': return - if not opts['info_sssd_domain']: - print 'info-identity-domain is required' - return False + configured = 0 confopts = {'instance': opts['instance']} @@ -135,17 +152,32 @@ class Installer(InfoProviderInstaller): except Exception as e: # pylint: disable=broad-except # Unable to read existing SSSD config so it is probably not # configured. - print 'Loading SSSD config failed: %s' % e + logging.info('Loading SSSD config failed: %s', e) return False - try: - domain = sssdconfig.get_domain(opts['info_sssd_domain']) - except SSSDConfig.NoDomainError: - print 'No domain %s' % opts['info_sssd_domain'] + if not opts['info_sssd_domain']: + domains = sssdconfig.list_domains() + else: + domains = opts['info_sssd_domain'] + + for domain in domains: + try: + sssd_domain = sssdconfig.get_domain(domain) + except SSSDConfig.NoDomainError: + logging.info('No SSSD domain %s', domain) + continue + else: + sssd_domain.set_option( + 'ldap_user_extra_attrs', ', '.join(SSSD_ATTRS) + ) + sssdconfig.save_domain(sssd_domain) + configured += 1 + logging.info("Configured SSSD domain %s", domain) + + if configured == 0: + logging.info('No SSSD domains configured') return False - domain.set_option('ldap_user_extra_attrs', ', '.join(SSSD_ATTRS)) - try: sssdconfig.new_service('ifp') except SSSDConfig.ServiceAlreadyExists: @@ -158,9 +190,15 @@ class Installer(InfoProviderInstaller): ifp.set_option('user_attributes', '+' + ', +'.join(SSSD_ATTRS)) sssdconfig.save_service(ifp) - sssdconfig.save_domain(domain) sssdconfig.write(SSSD_CONF) + # for selinux enabled platforms, ignore if it fails just report + try: + subprocess.call(['/usr/sbin/setsebool', '-P', + 'httpd_dbus_sssd=on']) + except Exception: # pylint: disable=broad-except + pass + try: subprocess.call(['/sbin/service', 'sssd', 'restart']) except Exception: # pylint: disable=broad-except @@ -174,6 +212,8 @@ class Installer(InfoProviderInstaller): po.name = 'sssd' po.wipe_data() po.wipe_config_values() + config = {'preconfigured': True} + po.save_plugin_config(config) # Update global config to add info plugin po.is_enabled = True