"Fossies" - the Fresh Open Source Software Archive

Member "sssd-2.4.2/src/config/SSSDConfigTest.py" (19 Feb 2021, 86556 Bytes) of package /linux/misc/sssd-2.4.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "SSSDConfigTest.py" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.4.1_vs_2.4.2.

    1 #!/usr/bin/env python
    2 #  SSSD
    3 #
    4 #  SSSD Config API tests
    5 #
    6 #  Copyright (C) Red Hat
    7 #
    8 #  This program is free software; you can redistribute it and/or modify
    9 #  it under the terms of the GNU General Public License as published by
   10 #  the Free Software Foundation; either version 3 of the License, or
   11 #  (at your option) any later version.
   12 #
   13 #  This program is distributed in the hope that it will be useful,
   14 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
   15 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16 #  GNU General Public License for more details.
   17 #
   18 #  You should have received a copy of the GNU General Public License
   19 #  along with this program.  If not, see <http://www.gnu.org/licenses/>.
   20 '''
   21 Created on Sep 18, 2009
   22 
   23 @author: sgallagh
   24 '''
   25 import unittest
   26 import os
   27 import shutil
   28 import tempfile
   29 from stat import *
   30 
   31 import sys
   32 
   33 srcdir = os.getenv('srcdir')
   34 if srcdir:
   35     sys.path.insert(0, "./src/config")
   36     srcdir = srcdir + "/src/config"
   37 else:
   38     srcdir = "."
   39 import SSSDConfig
   40 
   41 
   42 def create_temp_dir():
   43     test_dir = os.environ.get('SSS_TEST_DIR') or "."
   44     return tempfile.mkdtemp(dir=test_dir)
   45 
   46 
   47 def striplist(l):
   48     return([x.strip() for x in l])
   49 
   50 
   51 class SSSDConfigTestValid(unittest.TestCase):
   52     def setUp(self):
   53         self.tmp_dir = create_temp_dir()
   54 
   55     def tearDown(self):
   56         shutil.rmtree(self.tmp_dir)
   57 
   58     def testServices(self):
   59         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
   60                                 srcdir + "/etc/sssd.api.d")
   61         sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf")
   62 
   63         # Validate services
   64         services = sssdconfig.list_services()
   65         self.assertTrue('sssd' in services)
   66         self.assertTrue('nss' in services)
   67         self.assertTrue('pam' in services)
   68 
   69         #Verify service attributes
   70         sssd_service = sssdconfig.get_service('sssd')
   71         service_opts = sssd_service.list_options()
   72 
   73 
   74         self.assertTrue('services' in service_opts.keys())
   75         service_list = sssd_service.get_option('services')
   76         self.assertTrue('nss' in service_list)
   77         self.assertTrue('pam' in service_list)
   78 
   79         self.assertTrue('domains' in service_opts)
   80 
   81         self.assertTrue('reconnection_retries' in service_opts)
   82 
   83         del sssdconfig
   84         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
   85                                      srcdir + "/etc/sssd.api.d")
   86         sssdconfig.new_config()
   87         sssdconfig.delete_service('sssd')
   88         new_sssd_service = sssdconfig.new_service('sssd');
   89         new_options = new_sssd_service.list_options();
   90 
   91         self.assertTrue('debug_level' in new_options)
   92         self.assertEqual(new_options['debug_level'][0], int)
   93 
   94         self.assertTrue('command' in new_options)
   95         self.assertEqual(new_options['command'][0], str)
   96 
   97         self.assertTrue('reconnection_retries' in new_options)
   98         self.assertEqual(new_options['reconnection_retries'][0], int)
   99 
  100         self.assertTrue('services' in new_options)
  101         self.assertEqual(new_options['debug_level'][0], int)
  102 
  103         self.assertTrue('domains' in new_options)
  104         self.assertEqual(new_options['domains'][0], list)
  105         self.assertEqual(new_options['domains'][1], str)
  106 
  107         self.assertTrue('sbus_timeout' in new_options)
  108         self.assertEqual(new_options['sbus_timeout'][0], int)
  109 
  110         self.assertTrue('re_expression' in new_options)
  111         self.assertEqual(new_options['re_expression'][0], str)
  112 
  113         self.assertTrue('full_name_format' in new_options)
  114         self.assertEqual(new_options['full_name_format'][0], str)
  115 
  116         self.assertTrue('default_domain_suffix' in new_options)
  117         self.assertEqual(new_options['default_domain_suffix'][0], str)
  118 
  119         self.assertTrue('domain_resolution_order' in new_options)
  120         self.assertEqual(new_options['domain_resolution_order'][0], list)
  121         self.assertEqual(new_options['domain_resolution_order'][1], str)
  122 
  123         del sssdconfig
  124 
  125     def testDomains(self):
  126         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
  127                                 srcdir + "/etc/sssd.api.d")
  128         sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf")
  129 
  130         #Validate domain list
  131         domains = sssdconfig.list_domains()
  132         self.assertTrue('LOCAL' in domains)
  133         self.assertTrue('LDAP' in domains)
  134         self.assertTrue('PROXY' in domains)
  135         self.assertTrue('IPA' in domains)
  136 
  137         #Verify domain attributes
  138         ipa_domain = sssdconfig.get_domain('IPA')
  139         domain_opts = ipa_domain.list_options()
  140         self.assertTrue('debug_level' in domain_opts.keys())
  141         self.assertTrue('id_provider' in domain_opts.keys())
  142         self.assertTrue('auth_provider' in domain_opts.keys())
  143         self.assertEqual(ipa_domain.get_option('debug_level'), 0xff0)
  144 
  145         proxy_domain = sssdconfig.get_domain('PROXY')
  146         self.assertEqual(proxy_domain.get_option('debug_level'), 1)
  147 
  148         # Verify attributes in responders
  149         pam_responder = sssdconfig.get_service('pam')
  150         self.assertEqual(pam_responder.get_option('debug_level'), 2)
  151 
  152         sudo_responder = sssdconfig.get_service('sudo')
  153         self.assertEqual(sudo_responder.get_option('debug_level'), 0xfc10)
  154 
  155         del sssdconfig
  156 
  157     def testListProviders(self):
  158         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
  159                                 srcdir + "/etc/sssd.api.d")
  160 
  161         sssdconfig.new_config()
  162         junk_domain = sssdconfig.new_domain('junk')
  163         providers = junk_domain.list_providers()
  164         self.assertTrue('ldap' in providers.keys())
  165 
  166     def testCreateNewLocalConfig(self):
  167         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
  168                                 srcdir + "/etc/sssd.api.d")
  169 
  170         sssdconfig.new_config()
  171 
  172         local_domain = sssdconfig.new_domain('LOCAL')
  173         local_domain.add_provider('local', 'id')
  174         local_domain.set_option('debug_level', 1)
  175         local_domain.set_option('default_shell', '/bin/tcsh')
  176         local_domain.set_active(True)
  177         sssdconfig.save_domain(local_domain)
  178 
  179         of = self.tmp_dir + '/testCreateNewLocalConfig.conf'
  180 
  181         #Ensure the output file doesn't exist
  182         try:
  183             os.unlink(of)
  184         except:
  185             pass
  186 
  187         #Write out the file
  188         sssdconfig.write(of)
  189 
  190         #Verify that the output file has the correct permissions
  191         mode = os.stat(of)[ST_MODE]
  192 
  193         #Output files should not be readable or writable by
  194         #non-owners, and should not be executable by anyone
  195         self.assertFalse(S_IMODE(mode) & 0o177)
  196 
  197         # try to import saved configuration file
  198         config = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
  199                                        srcdir + "/etc/sssd.api.d")
  200         config.import_config(configfile=of)
  201 
  202         #Remove the output file
  203         os.unlink(of)
  204 
  205     def testCreateNewLDAPConfig(self):
  206         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
  207                                 srcdir + "/etc/sssd.api.d")
  208 
  209         sssdconfig.new_config()
  210 
  211         ldap_domain = sssdconfig.new_domain('LDAP')
  212         ldap_domain.add_provider('ldap', 'id')
  213         ldap_domain.set_option('debug_level', 1)
  214         ldap_domain.set_active(True)
  215         sssdconfig.save_domain(ldap_domain)
  216 
  217         of = self.tmp_dir + '/testCreateNewLDAPConfig.conf'
  218 
  219         #Ensure the output file doesn't exist
  220         try:
  221             os.unlink(of)
  222         except:
  223             pass
  224 
  225         #Write out the file
  226         sssdconfig.write(of)
  227 
  228         #Verify that the output file has the correct permissions
  229         mode = os.stat(of)[ST_MODE]
  230 
  231         #Output files should not be readable or writable by
  232         #non-owners, and should not be executable by anyone
  233         self.assertFalse(S_IMODE(mode) & 0o177)
  234 
  235         # try to import saved configuration file
  236         config = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
  237                                        srcdir + "/etc/sssd.api.d")
  238         config.import_config(configfile=of)
  239 
  240         #Remove the output file
  241         os.unlink(of)
  242 
  243 
  244     def testModifyExistingConfig(self):
  245         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
  246                                 srcdir + "/etc/sssd.api.d")
  247         sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf")
  248 
  249         ldap_domain = sssdconfig.get_domain('LDAP')
  250         ldap_domain.set_option('debug_level', 3)
  251 
  252         ldap_domain.remove_provider('auth')
  253         ldap_domain.add_provider('krb5', 'auth')
  254         ldap_domain.set_active(True)
  255         sssdconfig.save_domain(ldap_domain)
  256 
  257         proxy_domain = sssdconfig.get_domain('PROXY')
  258         proxy_domain.set_option('debug_level', 0x1f10)
  259         sssdconfig.save_domain(proxy_domain)
  260 
  261         sudo_responder = sssdconfig.get_service('sudo')
  262         sudo_responder.set_option('debug_level', 0x2210)
  263         sssdconfig.save_service(sudo_responder)
  264 
  265         pam_responder = sssdconfig.get_service('pam')
  266         pam_responder.set_option('debug_level', 9)
  267         sssdconfig.save_service(pam_responder)
  268 
  269         of = self.tmp_dir + '/testModifyExistingConfig.conf'
  270 
  271         #Ensure the output file doesn't exist
  272         try:
  273             os.unlink(of)
  274         except:
  275             pass
  276 
  277         #Write out the file
  278         sssdconfig.write(of)
  279 
  280         #Verify that the output file has the correct permissions
  281         mode = os.stat(of)[ST_MODE]
  282 
  283         #Output files should not be readable or writable by
  284         #non-owners, and should not be executable by anyone
  285         self.assertFalse(S_IMODE(mode) & 0o177)
  286 
  287         # try to import saved configuration file
  288         config = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
  289                                        srcdir + "/etc/sssd.api.d")
  290         config.import_config(configfile=of)
  291 
  292         # test set_option 'debug_level' value
  293 
  294         # check internal state before parsing strings which is done in
  295         # get_domain or get_service
  296         debug_option = [ x for x in config.options('domain/LDAP')
  297                            if x['name'] == 'debug_level']
  298         self.assertEqual(len(debug_option), 1)
  299         self.assertEqual(debug_option[0]['value'], '3')
  300 
  301         debug_option = [ x for x in config.options('domain/PROXY')
  302                            if x['name'] == 'debug_level']
  303         self.assertEqual(len(debug_option), 1)
  304         self.assertEqual(debug_option[0]['value'], '0x1f10')
  305 
  306         debug_option = [ x for x in config.options('sudo')
  307                            if x['name'] == 'debug_level']
  308         self.assertEqual(len(debug_option), 1)
  309         self.assertEqual(debug_option[0]['value'], '0x2210')
  310 
  311         debug_option = [ x for x in config.options('pam')
  312                            if x['name'] == 'debug_level']
  313         self.assertEqual(len(debug_option), 1)
  314         self.assertEqual(debug_option[0]['value'], '9')
  315 
  316         #Remove the output file
  317         os.unlink(of)
  318 
  319     def testSpaces(self):
  320         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
  321                                            srcdir + "/etc/sssd.api.d")
  322         sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf")
  323         ldap_domain = sssdconfig.get_domain('LDAP')
  324         self.assertEqual(ldap_domain.get_option('auth_provider'), 'ldap')
  325         self.assertEqual(ldap_domain.get_option('id_provider'), 'ldap')
  326 
  327 class SSSDConfigTestInvalid(unittest.TestCase):
  328     def setUp(self):
  329         pass
  330 
  331     def tearDown(self):
  332         pass
  333 
  334     def testBadBool(self):
  335         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
  336                                            srcdir + "/etc/sssd.api.d")
  337         sssdconfig.import_config(srcdir + "/testconfigs/sssd-invalid-badbool.conf")
  338         self.assertRaises(TypeError,
  339                           sssdconfig.get_domain,'IPA')
  340 
  341 class SSSDConfigTestSSSDService(unittest.TestCase):
  342     def setUp(self):
  343         self.schema = SSSDConfig.SSSDConfigSchema(srcdir + "/etc/sssd.api.conf",
  344                                                   srcdir + "/etc/sssd.api.d")
  345 
  346     def tearDown(self):
  347         pass
  348 
  349     def testInit(self):
  350         # Positive test
  351         service = SSSDConfig.SSSDService('sssd', self.schema)
  352 
  353         # Type Error test
  354         # Name is not a string
  355         self.assertRaises(TypeError, SSSDConfig.SSSDService, 3, self.schema)
  356 
  357         # TypeError test
  358         # schema is not an SSSDSchema
  359         self.assertRaises(TypeError, SSSDConfig.SSSDService, '3', self)
  360 
  361         # ServiceNotRecognizedError test
  362         self.assertRaises(SSSDConfig.ServiceNotRecognizedError,
  363                           SSSDConfig.SSSDService, 'ssd', self.schema)
  364 
  365     def testListOptions(self):
  366         service = SSSDConfig.SSSDService('sssd', self.schema)
  367 
  368         options = service.list_options()
  369         control_list = [
  370             'config_file_version',
  371             'services',
  372             'domains',
  373             'timeout',
  374             'sbus_timeout',
  375             're_expression',
  376             'full_name_format',
  377             'krb5_rcache_dir',
  378             'user',
  379             'default_domain_suffix',
  380             'debug',
  381             'debug_level',
  382             'debug_timestamps',
  383             'debug_microseconds',
  384             'debug_to_files',
  385             'command',
  386             'reconnection_retries',
  387             'fd_limit',
  388             'client_idle_timeout',
  389             'responder_idle_timeout',
  390             'cache_first',
  391             'description',
  392             'certificate_verification',
  393             'override_space',
  394             'disable_netlink',
  395             'enable_files_domain',
  396             'domain_resolution_order',
  397             'try_inotify',
  398             'monitor_resolv_conf',
  399         ]
  400 
  401         self.assertTrue(type(options) == dict,
  402                         "Options should be a dictionary")
  403 
  404         # Ensure that all of the expected defaults are there
  405         for option in control_list:
  406             self.assertTrue(option in options.keys(),
  407                             "Option [%s] missing" %
  408                             option)
  409 
  410         # Ensure that there aren't any unexpected options listed
  411         for option in options.keys():
  412             self.assertTrue(option in control_list,
  413                             'Option [%s] unexpectedly found' %
  414                             option)
  415 
  416         self.assertTrue(type(options['reconnection_retries']) == tuple,
  417                         "Option values should be a tuple")
  418 
  419         self.assertTrue(options['reconnection_retries'][0] == int,
  420                         "reconnection_retries should require an int. " +
  421                         "list_options is requiring a %s" %
  422                         options['reconnection_retries'][0])
  423 
  424         self.assertTrue(options['reconnection_retries'][1] == None,
  425                         "reconnection_retries should not require a subtype. " +
  426                         "list_options is requiring a %s" %
  427                         options['reconnection_retries'][1])
  428 
  429         self.assertTrue(options['reconnection_retries'][3] == None,
  430                         "reconnection_retries should have no default")
  431 
  432         self.assertTrue(type(options['services']) == tuple,
  433                         "Option values should be a tuple")
  434 
  435         self.assertTrue(options['services'][0] == list,
  436                         "services should require an list. " +
  437                         "list_options is requiring a %s" %
  438                         options['services'][0])
  439 
  440         self.assertTrue(options['services'][1] == str,
  441                         "services should require a subtype of str. " +
  442                         "list_options is requiring a %s" %
  443                         options['services'][1])
  444 
  445     def testListMandatoryOptions(self):
  446         service = SSSDConfig.SSSDService('sssd', self.schema)
  447 
  448         options = service.list_mandatory_options()
  449         control_list = [
  450             'services',
  451             'domains']
  452 
  453         self.assertTrue(type(options) == dict,
  454                         "Options should be a dictionary")
  455 
  456         # Ensure that all of the expected defaults are there
  457         for option in control_list:
  458             self.assertTrue(option in options.keys(),
  459                             "Option [%s] missing" %
  460                             option)
  461 
  462         # Ensure that there aren't any unexpected options listed
  463         for option in options.keys():
  464             self.assertTrue(option in control_list,
  465                             'Option [%s] unexpectedly found' %
  466                             option)
  467 
  468         self.assertTrue(type(options['services']) == tuple,
  469                         "Option values should be a tuple")
  470 
  471         self.assertTrue(options['services'][0] == list,
  472                         "services should require an list. " +
  473                         "list_options is requiring a %s" %
  474                         options['services'][0])
  475 
  476         self.assertTrue(options['services'][1] == str,
  477                         "services should require a subtype of str. " +
  478                         "list_options is requiring a %s" %
  479                         options['services'][1])
  480 
  481     def testSetOption(self):
  482         service = SSSDConfig.SSSDService('sssd', self.schema)
  483 
  484         # Positive test - Exactly right
  485         service.set_option('debug_level', 2)
  486         self.assertEqual(service.get_option('debug_level'), 2)
  487 
  488         # Positive test - Allow converting "safe" values
  489         service.set_option('debug_level', '2')
  490         self.assertEqual(service.get_option('debug_level'), 2)
  491 
  492         # Positive test - Remove option if value is None
  493         service.set_option('debug_level', None)
  494         self.assertTrue('debug_level' not in service.options.keys())
  495 
  496         # Negative test - Nonexistent Option
  497         self.assertRaises(SSSDConfig.NoOptionError, service.set_option, 'nosuchoption', 1)
  498 
  499         # Negative test - Incorrect type
  500         self.assertRaises(TypeError, service.set_option, 'debug_level', 'two')
  501 
  502     def testGetOption(self):
  503         service = SSSDConfig.SSSDService('sssd', self.schema)
  504 
  505         # Positive test - List of values
  506         self.assertEqual(service.get_option('services'), ['nss', 'pam'])
  507 
  508         # Negative Test - Bad Option
  509         self.assertRaises(SSSDConfig.NoOptionError, service.get_option, 'nosuchoption')
  510 
  511     def testGetAllOptions(self):
  512         service = SSSDConfig.SSSDService('sssd', self.schema)
  513 
  514         #Positive test
  515         options = service.get_all_options()
  516         control_list = ['services']
  517 
  518         self.assertTrue(type(options) == dict,
  519                         "Options should be a dictionary")
  520 
  521         # Ensure that all of the expected defaults are there
  522         for option in control_list:
  523             self.assertTrue(option in options.keys(),
  524                             "Option [%s] missing" %
  525                             option)
  526 
  527         # Ensure that there aren't any unexpected options listed
  528         for option in options.keys():
  529             self.assertTrue(option in control_list,
  530                             'Option [%s] unexpectedly found' %
  531                             option)
  532 
  533     def testRemoveOption(self):
  534         service = SSSDConfig.SSSDService('sssd', self.schema)
  535 
  536         # Positive test - Remove an option that exists
  537         self.assertEqual(service.get_option('services'), ['nss', 'pam'])
  538         service.remove_option('services')
  539         self.assertRaises(SSSDConfig.NoOptionError, service.get_option, 'debug_level')
  540 
  541         # Positive test - Remove an option that doesn't exist
  542         self.assertRaises(SSSDConfig.NoOptionError, service.get_option, 'nosuchentry')
  543         service.remove_option('nosuchentry')
  544 
  545 class SSSDConfigTestSSSDDomain(unittest.TestCase):
  546     def setUp(self):
  547         self.schema = SSSDConfig.SSSDConfigSchema(srcdir + "/etc/sssd.api.conf",
  548                                                   srcdir + "/etc/sssd.api.d")
  549 
  550     def tearDown(self):
  551         pass
  552 
  553     def testInit(self):
  554         # Positive Test
  555         domain = SSSDConfig.SSSDDomain('mydomain', self.schema)
  556 
  557         # Negative Test - Name not a string
  558         self.assertRaises(TypeError, SSSDConfig.SSSDDomain, 2, self.schema)
  559 
  560         # Negative Test - Schema is not an SSSDSchema
  561         self.assertRaises(TypeError, SSSDConfig.SSSDDomain, 'mydomain', self)
  562 
  563     def testGetName(self):
  564         # Positive Test
  565         domain = SSSDConfig.SSSDDomain('mydomain', self.schema)
  566 
  567         self.assertEqual(domain.get_name(), 'mydomain')
  568 
  569     def testSetActive(self):
  570         #Positive Test
  571         domain = SSSDConfig.SSSDDomain('mydomain', self.schema)
  572 
  573         # Should default to inactive
  574         self.assertFalse(domain.active)
  575         domain.set_active(True)
  576         self.assertTrue(domain.active)
  577         domain.set_active(False)
  578         self.assertFalse(domain.active)
  579 
  580     def testListOptions(self):
  581         domain = SSSDConfig.SSSDDomain('sssd', self.schema)
  582 
  583         # First test default options
  584         options = domain.list_options()
  585         control_list = [
  586             'description',
  587             'enabled',
  588             'debug',
  589             'debug_level',
  590             'debug_timestamps',
  591             'domain_type',
  592             'min_id',
  593             'max_id',
  594             'timeout',
  595             'offline_timeout',
  596             'offline_timeout_max',
  597             'command',
  598             'enumerate',
  599             'cache_credentials',
  600             'cache_credentials_minimal_first_factor_length',
  601             'use_fully_qualified_names',
  602             'ignore_group_members',
  603             'filter_users',
  604             'filter_groups',
  605             'entry_cache_timeout',
  606             'entry_cache_user_timeout',
  607             'entry_cache_group_timeout',
  608             'entry_cache_netgroup_timeout',
  609             'entry_cache_service_timeout',
  610             'entry_cache_autofs_timeout',
  611             'entry_cache_sudo_timeout',
  612             'entry_cache_ssh_host_timeout',
  613             'entry_cache_resolver_timeout',
  614             'refresh_expired_interval',
  615             'lookup_family_order',
  616             'account_cache_expiration',
  617             'dns_resolver_server_timeout',
  618             'dns_resolver_op_timeout',
  619             'dns_resolver_timeout',
  620             'dns_discovery_domain',
  621             'dyndns_update',
  622             'dyndns_ttl',
  623             'dyndns_iface',
  624             'dyndns_refresh_interval',
  625             'dyndns_update_ptr',
  626             'dyndns_force_tcp',
  627             'dyndns_auth',
  628             'dyndns_server',
  629             'subdomain_enumerate',
  630             'override_gid',
  631             'case_sensitive',
  632             'override_homedir',
  633             'fallback_homedir',
  634             'homedir_substring',
  635             'override_shell',
  636             'default_shell',
  637             'pwd_expiration_warning',
  638             'id_provider',
  639             'auth_provider',
  640             'access_provider',
  641             'chpass_provider',
  642             'sudo_provider',
  643             'autofs_provider',
  644             'hostid_provider',
  645             'subdomains_provider',
  646             'selinux_provider',
  647             'session_provider',
  648             'resolver_provider',
  649             'realmd_tags',
  650             'subdomain_refresh_interval',
  651             'subdomain_inherit',
  652             'subdomain_homedir',
  653             'full_name_format',
  654             're_expression',
  655             'cached_auth_timeout',
  656             'auto_private_groups',
  657             'pam_gssapi_services',
  658             'pam_gssapi_check_upn',
  659             'pam_gssapi_indicators_map']
  660 
  661         self.assertTrue(type(options) == dict,
  662                         "Options should be a dictionary")
  663 
  664         # Ensure that all of the expected defaults are there
  665         for option in control_list:
  666             self.assertTrue(option in options.keys(),
  667                             "Option [%s] missing" %
  668                             option)
  669 
  670         # Ensure that there aren't any unexpected options listed
  671         for option in options.keys():
  672             self.assertTrue(option in control_list,
  673                             'Option [%s] unexpectedly found' %
  674                             option)
  675 
  676         self.assertTrue(type(options['max_id']) == tuple,
  677                         "Option values should be a tuple")
  678 
  679         self.assertTrue(options['max_id'][0] == int,
  680                         "max_id should require an int. " +
  681                         "list_options is requiring a %s" %
  682                         options['max_id'][0])
  683 
  684         self.assertTrue(options['max_id'][1] == None,
  685                         "max_id should not require a subtype. " +
  686                         "list_options is requiring a %s" %
  687                         options['max_id'][1])
  688 
  689         # Add a provider and verify that the new options appear
  690         domain.add_provider('local', 'id')
  691         control_list.extend(
  692             ['default_shell',
  693              'base_directory',
  694              'create_homedir',
  695              'remove_homedir',
  696              'homedir_umask',
  697              'skel_dir',
  698              'mail_dir',
  699              'userdel_cmd'])
  700 
  701         options = domain.list_options()
  702 
  703         self.assertTrue(type(options) == dict,
  704                         "Options should be a dictionary")
  705 
  706         # Ensure that all of the expected defaults are there
  707         for option in control_list:
  708             self.assertTrue(option in options.keys(),
  709                             "Option [%s] missing" %
  710                             option)
  711 
  712         # Ensure that there aren't any unexpected options listed
  713         for option in options.keys():
  714             self.assertTrue(option in control_list,
  715                             'Option [%s] unexpectedly found' %
  716                             option)
  717 
  718         # Add a provider that has global options and verify that
  719         # The new options appear.
  720         domain.add_provider('krb5', 'auth')
  721 
  722         backup_list = control_list[:]
  723         control_list.extend(
  724             ['krb5_server',
  725              'krb5_backup_server',
  726              'krb5_realm',
  727              'krb5_kpasswd',
  728              'krb5_backup_kpasswd',
  729              'krb5_ccachedir',
  730              'krb5_ccname_template',
  731              'krb5_keytab',
  732              'krb5_validate',
  733              'krb5_store_password_if_offline',
  734              'krb5_auth_timeout',
  735              'krb5_renewable_lifetime',
  736              'krb5_lifetime',
  737              'krb5_renew_interval',
  738              'krb5_use_fast',
  739              'krb5_fast_principal',
  740              'krb5_canonicalize',
  741              'krb5_use_enterprise_principal',
  742              'krb5_use_subdomain_realm',
  743              'krb5_use_kdcinfo',
  744              'krb5_map_user'])
  745 
  746         options = domain.list_options()
  747 
  748         self.assertTrue(type(options) == dict,
  749                         "Options should be a dictionary")
  750 
  751         # Ensure that all of the expected defaults are there
  752         for option in control_list:
  753             self.assertTrue(option in options.keys(),
  754                             "Option [%s] missing" %
  755                             option)
  756 
  757         control_list.extend(['krb5_kdcip'])
  758 
  759         # Ensure that there aren't any unexpected options listed
  760         for option in options.keys():
  761             self.assertTrue(option in control_list,
  762                             'Option [%s] unexpectedly found' %
  763                             option)
  764 
  765         # Remove the auth domain and verify that the options
  766         # revert to the backup_list
  767         domain.remove_provider('auth')
  768         options = domain.list_options()
  769 
  770         self.assertTrue(type(options) == dict,
  771                         "Options should be a dictionary")
  772 
  773         # Ensure that all of the expected defaults are there
  774         for option in backup_list:
  775             self.assertTrue(option in options.keys(),
  776                             "Option [%s] missing" %
  777                             option)
  778 
  779         # Ensure that there aren't any unexpected options listed
  780         for option in options.keys():
  781             self.assertTrue(option in backup_list,
  782                             'Option [%s] unexpectedly found' %
  783                             option)
  784 
  785     def testListMandatoryOptions(self):
  786         domain = SSSDConfig.SSSDDomain('sssd', self.schema)
  787 
  788         # First test default options
  789         options = domain.list_mandatory_options()
  790         control_list = ['id_provider']
  791 
  792         self.assertTrue(type(options) == dict,
  793                         "Options should be a dictionary")
  794 
  795         # Ensure that all of the expected defaults are there
  796         for option in control_list:
  797             self.assertTrue(option in options.keys(),
  798                             "Option [%s] missing" %
  799                             option)
  800 
  801         # Ensure that there aren't any unexpected options listed
  802         for option in options.keys():
  803             self.assertTrue(option in control_list,
  804                             'Option [%s] unexpectedly found' %
  805                             option)
  806 
  807         # Add a provider that has global options and verify that
  808         # The new options appear.
  809         domain.add_provider('krb5', 'auth')
  810 
  811         backup_list = control_list[:]
  812         control_list.extend(['krb5_realm'])
  813 
  814         options = domain.list_mandatory_options()
  815 
  816         self.assertTrue(type(options) == dict,
  817                         "Options should be a dictionary")
  818 
  819         # Ensure that all of the expected defaults are there
  820         for option in control_list:
  821             self.assertTrue(option in options.keys(),
  822                             "Option [%s] missing" %
  823                             option)
  824 
  825         # Ensure that there aren't any unexpected options listed
  826         for option in options.keys():
  827             self.assertTrue(option in control_list,
  828                             'Option [%s] unexpectedly found' %
  829                             option)
  830 
  831         # Remove the auth domain and verify that the options
  832         # revert to the backup_list
  833         domain.remove_provider('auth')
  834         options = domain.list_mandatory_options()
  835 
  836         self.assertTrue(type(options) == dict,
  837                         "Options should be a dictionary")
  838 
  839         # Ensure that all of the expected defaults are there
  840         for option in backup_list:
  841             self.assertTrue(option in options.keys(),
  842                             "Option [%s] missing" %
  843                             option)
  844 
  845         # Ensure that there aren't any unexpected options listed
  846         for option in options.keys():
  847             self.assertTrue(option in backup_list,
  848                             'Option [%s] unexpectedly found' %
  849                             option)
  850 
  851     def testListProviders(self):
  852         domain = SSSDConfig.SSSDDomain('sssd', self.schema)
  853 
  854         control_provider_dict = {
  855             'ipa': ['id', 'auth', 'access', 'chpass', 'sudo', 'autofs',
  856                     'session', 'hostid', 'subdomains'],
  857             'ad': ['id', 'auth', 'access', 'chpass', 'sudo', 'autofs',
  858                    'subdomains', 'resolver'],
  859             'local': ['id', 'auth', 'chpass'],
  860             'ldap': ['id', 'auth', 'access', 'chpass', 'sudo', 'autofs',
  861                      'resolver'],
  862             'krb5': ['auth', 'access', 'chpass'],
  863             'proxy': ['id', 'auth', 'chpass'],
  864             'simple': ['access'],
  865             'permit': ['access'],
  866             'deny': ['access']}
  867 
  868         providers = domain.list_providers()
  869 
  870         # Ensure that all of the expected defaults are there
  871         for provider in control_provider_dict.keys():
  872             for ptype in control_provider_dict[provider]:
  873                 self.assertTrue(provider in providers)
  874                 self.assertTrue(ptype in providers[provider])
  875 
  876         for provider in providers.keys():
  877             for ptype in providers[provider]:
  878                 self.assertTrue(provider in control_provider_dict)
  879                 self.assertTrue(ptype in control_provider_dict[provider])
  880 
  881     def testListProviderOptions(self):
  882         domain = SSSDConfig.SSSDDomain('sssd', self.schema)
  883 
  884         # Test looking up a specific provider type
  885         options = domain.list_provider_options('krb5', 'auth')
  886         control_list = [
  887             'krb5_server',
  888             'krb5_backup_server',
  889             'krb5_kdcip',
  890             'krb5_realm',
  891             'krb5_kpasswd',
  892             'krb5_backup_kpasswd',
  893             'krb5_ccachedir',
  894             'krb5_ccname_template',
  895             'krb5_keytab',
  896             'krb5_validate',
  897             'krb5_store_password_if_offline',
  898             'krb5_auth_timeout',
  899             'krb5_renewable_lifetime',
  900             'krb5_lifetime',
  901             'krb5_renew_interval',
  902             'krb5_use_fast',
  903             'krb5_fast_principal',
  904             'krb5_canonicalize',
  905             'krb5_use_enterprise_principal',
  906             'krb5_use_subdomain_realm',
  907             'krb5_use_kdcinfo',
  908             'krb5_map_user']
  909 
  910         self.assertTrue(type(options) == dict,
  911                         "Options should be a dictionary")
  912 
  913         # Ensure that all of the expected defaults are there
  914         for option in control_list:
  915             self.assertTrue(option in options.keys(),
  916                             "Option [%s] missing" %
  917                             option)
  918 
  919         # Ensure that there aren't any unexpected options listed
  920         for option in options.keys():
  921             self.assertTrue(option in control_list,
  922                             'Option [%s] unexpectedly found' %
  923                             option)
  924 
  925         #Test looking up all provider values
  926         options = domain.list_provider_options('krb5')
  927         control_list.extend(['krb5_kpasswd'])
  928 
  929         self.assertTrue(type(options) == dict,
  930                         "Options should be a dictionary")
  931 
  932         # Ensure that all of the expected defaults are there
  933         for option in control_list:
  934             self.assertTrue(option in options.keys(),
  935                             "Option [%s] missing" %
  936                             option)
  937 
  938         # Ensure that there aren't any unexpected options listed
  939         for option in options.keys():
  940             self.assertTrue(option in control_list,
  941                             'Option [%s] unexpectedly found' %
  942                             option)
  943 
  944     def testAddProvider(self):
  945         domain = SSSDConfig.SSSDDomain('sssd', self.schema)
  946 
  947         # Positive Test
  948         domain.add_provider('local', 'id')
  949 
  950         # Negative Test - No such backend type
  951         self.assertRaises(SSSDConfig.NoSuchProviderError,
  952                           domain.add_provider, 'nosuchbackend', 'auth')
  953 
  954         # Negative Test - No such backend subtype
  955         self.assertRaises(SSSDConfig.NoSuchProviderSubtypeError,
  956                           domain.add_provider, 'ldap', 'nosuchsubtype')
  957 
  958         # Negative Test - Try to add a second provider of the same type
  959         self.assertRaises(SSSDConfig.ProviderSubtypeInUse,
  960                           domain.add_provider, 'ldap', 'id')
  961 
  962     def testRemoveProvider(self):
  963         domain = SSSDConfig.SSSDDomain('sssd', self.schema)
  964 
  965         # First test default options
  966         options = domain.list_options()
  967         control_list = [
  968             'description',
  969             'enabled',
  970             'debug',
  971             'debug_level',
  972             'debug_timestamps',
  973             'domain_type',
  974             'min_id',
  975             'max_id',
  976             'timeout',
  977             'offline_timeout',
  978             'offline_timeout_max',
  979             'command',
  980             'enumerate',
  981             'cache_credentials',
  982             'cache_credentials_minimal_first_factor_length',
  983             'use_fully_qualified_names',
  984             'ignore_group_members',
  985             'filter_users',
  986             'filter_groups',
  987             'entry_cache_timeout',
  988             'entry_cache_user_timeout',
  989             'entry_cache_group_timeout',
  990             'entry_cache_netgroup_timeout',
  991             'entry_cache_service_timeout',
  992             'entry_cache_autofs_timeout',
  993             'entry_cache_sudo_timeout',
  994             'entry_cache_ssh_host_timeout',
  995             'entry_cache_resolver_timeout',
  996             'refresh_expired_interval',
  997             'account_cache_expiration',
  998             'lookup_family_order',
  999             'dns_resolver_server_timeout',
 1000             'dns_resolver_op_timeout',
 1001             'dns_resolver_timeout',
 1002             'dns_discovery_domain',
 1003             'dyndns_update',
 1004             'dyndns_ttl',
 1005             'dyndns_iface',
 1006             'dyndns_refresh_interval',
 1007             'dyndns_update_ptr',
 1008             'dyndns_force_tcp',
 1009             'dyndns_auth',
 1010             'dyndns_server',
 1011             'subdomain_enumerate',
 1012             'override_gid',
 1013             'case_sensitive',
 1014             'override_homedir',
 1015             'fallback_homedir',
 1016             'homedir_substring',
 1017             'override_shell',
 1018             'default_shell',
 1019             'pwd_expiration_warning',
 1020             'id_provider',
 1021             'auth_provider',
 1022             'access_provider',
 1023             'chpass_provider',
 1024             'sudo_provider',
 1025             'autofs_provider',
 1026             'hostid_provider',
 1027             'subdomains_provider',
 1028             'selinux_provider',
 1029             'session_provider',
 1030             'resolver_provider',
 1031             'realmd_tags',
 1032             'subdomain_refresh_interval',
 1033             'subdomain_inherit',
 1034             'subdomain_homedir',
 1035             'full_name_format',
 1036             're_expression',
 1037             'cached_auth_timeout',
 1038             'auto_private_groups',
 1039             'pam_gssapi_services',
 1040             'pam_gssapi_check_upn',
 1041             'pam_gssapi_indicators_map']
 1042 
 1043         self.assertTrue(type(options) == dict,
 1044                         "Options should be a dictionary")
 1045 
 1046         # Ensure that all of the expected defaults are there
 1047         for option in control_list:
 1048             self.assertTrue(option in options.keys(),
 1049                             "Option [%s] missing" %
 1050                             option)
 1051 
 1052         # Ensure that there aren't any unexpected options listed
 1053         for option in options.keys():
 1054             self.assertTrue(option in control_list,
 1055                             'Option [%s] unexpectedly found' %
 1056                             option)
 1057 
 1058         self.assertTrue(type(options['max_id']) == tuple,
 1059                         "Option values should be a tuple")
 1060 
 1061         self.assertTrue(options['max_id'][0] == int,
 1062                         "config_file_version should require an int. " +
 1063                         "list_options is requiring a %s" %
 1064                         options['max_id'][0])
 1065 
 1066         self.assertTrue(options['max_id'][1] == None,
 1067                         "config_file_version should not require a subtype. " +
 1068                         "list_options is requiring a %s" %
 1069                         options['max_id'][1])
 1070 
 1071         # Add a provider and verify that the new options appear
 1072         domain.add_provider('local', 'id')
 1073         control_list.extend(
 1074             ['default_shell',
 1075              'base_directory',
 1076              'create_homedir',
 1077              'remove_homedir',
 1078              'homedir_umask',
 1079              'skel_dir',
 1080              'mail_dir',
 1081              'userdel_cmd'])
 1082 
 1083         options = domain.list_options()
 1084 
 1085         self.assertTrue(type(options) == dict,
 1086                         "Options should be a dictionary")
 1087 
 1088         # Ensure that all of the expected defaults are there
 1089         for option in control_list:
 1090             self.assertTrue(option in options.keys(),
 1091                             "Option [%s] missing" %
 1092                             option)
 1093 
 1094         # Ensure that there aren't any unexpected options listed
 1095         for option in options.keys():
 1096             self.assertTrue(option in control_list,
 1097                             'Option [%s] unexpectedly found' %
 1098                             option)
 1099 
 1100         # Add a provider that has global options and verify that
 1101         # The new options appear.
 1102         domain.add_provider('krb5', 'auth')
 1103 
 1104         backup_list = control_list[:]
 1105         control_list.extend(
 1106             ['krb5_server',
 1107              'krb5_backup_server',
 1108              'krb5_kdcip',
 1109              'krb5_realm',
 1110              'krb5_kpasswd',
 1111              'krb5_backup_kpasswd',
 1112              'krb5_ccachedir',
 1113              'krb5_ccname_template',
 1114              'krb5_keytab',
 1115              'krb5_validate',
 1116              'krb5_store_password_if_offline',
 1117              'krb5_auth_timeout',
 1118              'krb5_renewable_lifetime',
 1119              'krb5_lifetime',
 1120              'krb5_renew_interval',
 1121              'krb5_use_fast',
 1122              'krb5_fast_principal',
 1123              'krb5_canonicalize',
 1124              'krb5_use_enterprise_principal',
 1125              'krb5_use_subdomain_realm',
 1126              'krb5_use_kdcinfo',
 1127              'krb5_map_user'])
 1128 
 1129         options = domain.list_options()
 1130 
 1131         self.assertTrue(type(options) == dict,
 1132                         "Options should be a dictionary")
 1133 
 1134         # Ensure that all of the expected defaults are there
 1135         for option in control_list:
 1136             self.assertTrue(option in options.keys(),
 1137                             "Option [%s] missing" %
 1138                             option)
 1139 
 1140         # Ensure that there aren't any unexpected options listed
 1141         for option in options.keys():
 1142             self.assertTrue(option in control_list,
 1143                             'Option [%s] unexpectedly found' %
 1144                             option)
 1145 
 1146         # Remove the local ID provider and add an LDAP one
 1147         # LDAP ID providers can also use the krb5_realm
 1148         domain.remove_provider('id')
 1149         self.assertFalse('id_provider' in domain.options)
 1150 
 1151         domain.add_provider('ldap', 'id')
 1152 
 1153         # Set the krb5_realm option and the ldap_uri option
 1154         domain.set_option('krb5_realm', 'EXAMPLE.COM')
 1155         domain.set_option('ldap_uri', 'ldap://ldap.example.com')
 1156 
 1157         self.assertEqual(domain.get_option('krb5_realm'),
 1158                          'EXAMPLE.COM')
 1159         self.assertEqual(domain.get_option('ldap_uri'),
 1160                          'ldap://ldap.example.com')
 1161 
 1162         # Remove the LDAP provider and verify that krb5_realm remains
 1163         domain.remove_provider('id')
 1164         self.assertEqual(domain.get_option('krb5_realm'),
 1165                          'EXAMPLE.COM')
 1166         self.assertFalse('ldap_uri' in domain.options)
 1167 
 1168         # Put the LOCAL provider back
 1169         domain.add_provider('local', 'id')
 1170 
 1171         # Remove the auth domain and verify that the options
 1172         # revert to the backup_list
 1173         domain.remove_provider('auth')
 1174         self.assertFalse('auth_provider' in domain.options)
 1175         options = domain.list_options()
 1176 
 1177         self.assertTrue(type(options) == dict,
 1178                         "Options should be a dictionary")
 1179 
 1180         # Ensure that all of the expected defaults are there
 1181         for option in backup_list:
 1182             self.assertTrue(option in options.keys(),
 1183                             "Option [%s] missing" %
 1184                             option)
 1185 
 1186         # Ensure that there aren't any unexpected options listed
 1187         for option in options.keys():
 1188             self.assertTrue(option in backup_list,
 1189                             'Option [%s] unexpectedly found' %
 1190                             option)
 1191 
 1192         # Ensure that the krb5_realm option is now gone
 1193         self.assertFalse('krb5_realm' in domain.options)
 1194 
 1195         # Test removing nonexistent provider - Real
 1196         domain.remove_provider('id')
 1197         self.assertFalse('id_provider' in domain.options)
 1198 
 1199         # Test removing nonexistent provider - Bad backend type
 1200         # Should pass without complaint
 1201         domain.remove_provider('id')
 1202         self.assertFalse('id_provider' in domain.options)
 1203 
 1204         # Test removing nonexistent provider - Bad provider type
 1205         # Should pass without complaint
 1206         domain.remove_provider('nosuchprovider')
 1207         self.assertFalse('nosuchprovider_provider' in domain.options)
 1208 
 1209     def testGetOption(self):
 1210         domain = SSSDConfig.SSSDDomain('sssd', self.schema)
 1211 
 1212         # Negative Test - Try to get valid option that is not set
 1213         self.assertRaises(SSSDConfig.NoOptionError, domain.get_option, 'max_id')
 1214 
 1215         # Positive Test - Set the above option and get it
 1216         domain.set_option('max_id', 10000)
 1217         self.assertEqual(domain.get_option('max_id'), 10000)
 1218 
 1219         # Negative Test - Try yo get invalid option
 1220         self.assertRaises(SSSDConfig.NoOptionError, domain.get_option, 'nosuchoption')
 1221 
 1222     def testSetOption(self):
 1223         domain = SSSDConfig.SSSDDomain('sssd', self.schema)
 1224 
 1225         # Positive Test
 1226         domain.set_option('max_id', 10000)
 1227         self.assertEqual(domain.get_option('max_id'), 10000)
 1228 
 1229         # Positive Test - Remove option if value is None
 1230         domain.set_option('max_id', None)
 1231         self.assertTrue('max_id' not in domain.get_all_options().keys())
 1232 
 1233         # Negative Test - invalid option
 1234         self.assertRaises(SSSDConfig.NoOptionError, domain.set_option, 'nosuchoption', 1)
 1235 
 1236         # Negative Test - incorrect type
 1237         self.assertRaises(TypeError, domain.set_option, 'max_id', 'a string')
 1238 
 1239         # Positive Test - Coax options to appropriate type
 1240         domain.set_option('max_id', '10000')
 1241         self.assertEqual(domain.get_option('max_id'), 10000)
 1242 
 1243         domain.set_option('max_id', 30.2)
 1244         self.assertEqual(domain.get_option('max_id'), 30)
 1245 
 1246     def testRemoveOption(self):
 1247         domain = SSSDConfig.SSSDDomain('sssd', self.schema)
 1248 
 1249         # Positive test - Remove unset but valid option
 1250         self.assertFalse('max_id' in domain.get_all_options().keys())
 1251         domain.remove_option('max_id')
 1252         self.assertFalse('max_id' in domain.get_all_options().keys())
 1253 
 1254         # Positive test - Remove unset and unknown option
 1255         self.assertFalse('nosuchoption' in domain.get_all_options().keys())
 1256         domain.remove_option('nosuchoption')
 1257         self.assertFalse('nosuchoption' in domain.get_all_options().keys())
 1258 
 1259     def testSetName(self):
 1260         domain = SSSDConfig.SSSDDomain('sssd', self.schema)
 1261 
 1262         # Positive test - Change the name once
 1263         domain.set_name('sssd2');
 1264         self.assertEqual(domain.get_name(), 'sssd2')
 1265         self.assertEqual(domain.oldname, 'sssd')
 1266 
 1267         # Positive test - Change the name a second time
 1268         domain.set_name('sssd3')
 1269         self.assertEqual(domain.get_name(), 'sssd3')
 1270         self.assertEqual(domain.oldname, 'sssd')
 1271 
 1272         # Negative test - try setting the name to a non-string
 1273         self.assertRaises(TypeError,
 1274                           domain.set_name, 4)
 1275 
 1276 class SSSDConfigTestSSSDConfig(unittest.TestCase):
 1277     def setUp(self):
 1278         self.tmp_dir = create_temp_dir()
 1279 
 1280     def tearDown(self):
 1281         shutil.rmtree(self.tmp_dir)
 1282 
 1283     def testInit(self):
 1284         # Positive test
 1285         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1286                                            srcdir + "/etc/sssd.api.d")
 1287 
 1288         # Negative Test - No Such File
 1289         self.assertRaises(IOError,
 1290                           SSSDConfig.SSSDConfig, "nosuchfile.api.conf", srcdir + "/etc/sssd.api.d")
 1291 
 1292         # Negative Test - Schema is not parsable
 1293         self.assertRaises(SSSDConfig.ParsingError,
 1294                           SSSDConfig.SSSDConfig, srcdir + "/testconfigs/noparse.api.conf", srcdir + "/etc/sssd.api.d")
 1295 
 1296     def testImportConfig(self):
 1297         # Positive Test
 1298         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1299                                            srcdir + "/etc/sssd.api.d")
 1300         sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf")
 1301 
 1302         # Verify that all sections were imported
 1303         control_list = [
 1304             'sssd',
 1305             'nss',
 1306             'pam',
 1307             'sudo',
 1308             'domain/PROXY',
 1309             'domain/IPA',
 1310             'domain/LOCAL',
 1311             'domain/LDAP',
 1312             'domain/INVALIDPROVIDER',
 1313             'domain/INVALIDOPTION',
 1314             ]
 1315 
 1316         for section in control_list:
 1317             self.assertTrue(sssdconfig.has_section(section),
 1318                             "Section [%s] missing" %
 1319                             section)
 1320         for section in sssdconfig.sections():
 1321             self.assertTrue(section['name'] in control_list)
 1322 
 1323         # Verify that all options were imported for a section
 1324         control_list = [
 1325             'services',
 1326             'reconnection_retries',
 1327             'domains',
 1328             'debug_timestamps',
 1329             'config_file_version']
 1330 
 1331         for option in control_list:
 1332             self.assertTrue(sssdconfig.has_option('sssd', option),
 1333                             "Option [%s] missing from [sssd]" %
 1334                             option)
 1335         for option in sssdconfig.options('sssd'):
 1336             if option['type'] in ('empty', 'comment'):
 1337                 continue
 1338             self.assertTrue(option['name'] in control_list,
 1339                             "Option [%s] unexpectedly found" %
 1340                             option)
 1341 
 1342         #TODO: Check the types and values of the settings
 1343 
 1344         # Negative Test - Missing config file
 1345         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1346                                            srcdir + "/etc/sssd.api.d")
 1347         self.assertRaises(IOError, sssdconfig.import_config, "nosuchfile.conf")
 1348 
 1349         # Negative Test - Invalid config file
 1350         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1351                                            srcdir + "/etc/sssd.api.d")
 1352         self.assertRaises(SSSDConfig.ParsingError, sssdconfig.import_config, srcdir + "/testconfigs/sssd-invalid.conf")
 1353 
 1354         # Negative Test - Invalid config file version
 1355         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1356                                            srcdir + "/etc/sssd.api.d")
 1357         self.assertRaises(SSSDConfig.ParsingError, sssdconfig.import_config, srcdir + "/testconfigs/sssd-badversion.conf")
 1358 
 1359         # Negative Test - Already initialized
 1360         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1361                                            srcdir + "/etc/sssd.api.d")
 1362         sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf")
 1363         self.assertRaises(SSSDConfig.AlreadyInitializedError,
 1364                           sssdconfig.import_config, srcdir + "/testconfigs/sssd-valid.conf")
 1365 
 1366     def testImportConfigNoVersion(self):
 1367         # Positive Test
 1368         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1369                                            srcdir + "/etc/sssd.api.d")
 1370         sssdconfig.import_config(
 1371             srcdir + "/testconfigs/sssd-noversion.conf"
 1372         )
 1373 
 1374         # Validate services
 1375         services = sssdconfig.list_services()
 1376         self.assertTrue('sssd' in services)
 1377         self.assertTrue('nss' in services)
 1378         self.assertTrue('pam' in services)
 1379         self.assertTrue('dp' in services)
 1380 
 1381         #Verify service attributes
 1382         sssd_service = sssdconfig.get_service('sssd')
 1383         service_opts = sssd_service.list_options()
 1384 
 1385         self.assertTrue('services' in service_opts.keys())
 1386         service_list = sssd_service.get_option('services')
 1387         self.assertTrue('nss' in service_list)
 1388         self.assertTrue('pam' in service_list)
 1389         self.assertTrue('reconnection_retries' in service_opts)
 1390 
 1391         #Validate domain list
 1392         domains = sssdconfig.list_domains()
 1393         self.assertTrue('LOCAL' in domains)
 1394         self.assertTrue('LDAP' in domains)
 1395         self.assertTrue('PROXY' in domains)
 1396         self.assertTrue('IPA' in domains)
 1397 
 1398         # Verify domain attributes
 1399         ipa_domain = sssdconfig.get_domain('IPA')
 1400         domain_opts = ipa_domain.list_options()
 1401         self.assertTrue('debug_level' in domain_opts.keys())
 1402         self.assertTrue('id_provider' in domain_opts.keys())
 1403         self.assertTrue('auth_provider' in domain_opts.keys())
 1404 
 1405         # Verify domain attributes
 1406         proxy_domain = sssdconfig.get_domain('PROXY')
 1407         domain_opts = proxy_domain.list_options()
 1408         self.assertTrue('debug_level' in domain_opts.keys())
 1409         self.assertTrue('id_provider' in domain_opts.keys())
 1410         self.assertTrue('auth_provider' in domain_opts.keys())
 1411 
 1412         # Verify domain attributes
 1413         local_domain = sssdconfig.get_domain('LOCAL')
 1414         domain_opts = local_domain.list_options()
 1415         self.assertTrue('debug_level' in domain_opts.keys())
 1416         self.assertTrue('id_provider' in domain_opts.keys())
 1417         self.assertTrue('auth_provider' in domain_opts.keys())
 1418 
 1419         # Verify domain attributes
 1420         ldap_domain = sssdconfig.get_domain('LDAP')
 1421         domain_opts = ldap_domain.list_options()
 1422         self.assertTrue('debug_level' in domain_opts.keys())
 1423         self.assertTrue('id_provider' in domain_opts.keys())
 1424         self.assertTrue('auth_provider' in domain_opts.keys())
 1425 
 1426         domain_control_list = [
 1427             'cache_credentials',
 1428             'id_provider',
 1429             'auth_provider',
 1430             'access_provider',
 1431             'autofs_provider',
 1432             'chpass_provider',
 1433             'sudo_provider',
 1434             'subdomains_provider',
 1435             'resolver_provider',
 1436             'default_shell',
 1437             'fallback_homedir',
 1438             'cache_credentials',
 1439             'use_fully_qualified_names',
 1440         ]
 1441 
 1442         ad_domain = sssdconfig.get_domain("ad.example.com")
 1443 
 1444         for option in ad_domain.get_all_options():
 1445             self.assertTrue(option in domain_control_list)
 1446 
 1447         negative_domain_control_list = [
 1448             'ad_server',
 1449             'ldap_id_mapping',
 1450             'ldap_sasl_authid',
 1451             'selinux_provider',
 1452             'hostid_provider',
 1453             'session_provider',
 1454         ]
 1455 
 1456         for option in ad_domain.get_all_options():
 1457             self.assertFalse(option in negative_domain_control_list)
 1458 
 1459     def testNewConfig(self):
 1460         # Positive Test
 1461         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1462                                            srcdir + "/etc/sssd.api.d")
 1463         sssdconfig.new_config()
 1464 
 1465         # Check that the defaults were set
 1466         control_list = [
 1467             'sssd',
 1468             'nss',
 1469             'pam',
 1470             'sudo',
 1471             'autofs',
 1472             'ssh',
 1473             'pac',
 1474             'ifp',
 1475             'secrets',
 1476             'session_recording']
 1477         for section in control_list:
 1478             self.assertTrue(sssdconfig.has_section(section),
 1479                             "Section [%s] missing" %
 1480                             section)
 1481         for section in sssdconfig.sections():
 1482             self.assertTrue(section['name'] in control_list)
 1483 
 1484         control_list = ['services']
 1485         for option in control_list:
 1486             self.assertTrue(sssdconfig.has_option('sssd', option),
 1487                             "Option [%s] missing from [sssd]" %
 1488                             option)
 1489         for option in sssdconfig.options('sssd'):
 1490             if option['type'] in ('empty', 'comment'):
 1491                 continue
 1492             self.assertTrue(option['name'] in control_list,
 1493                             "Option [%s] unexpectedly found" %
 1494                             option)
 1495 
 1496         # Negative Test - Already Initialized
 1497         self.assertRaises(SSSDConfig.AlreadyInitializedError, sssdconfig.new_config)
 1498 
 1499     def testWrite(self):
 1500         #TODO Write tests to compare output files
 1501         pass
 1502 
 1503     def testListActiveServices(self):
 1504         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1505                                            srcdir + "/etc/sssd.api.d")
 1506 
 1507         # Negative Test - Not Initialized
 1508         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_active_services)
 1509 
 1510         # Positive Test
 1511         sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf')
 1512 
 1513         control_list = [
 1514             'nss',
 1515             'pam']
 1516         active_services = sssdconfig.list_active_services()
 1517         self.assertTrue(isinstance(active_services, list))
 1518 
 1519         for service in control_list:
 1520             self.assertTrue(service in active_services,
 1521                             "Service [%s] missing" %
 1522                             service)
 1523         for service in active_services:
 1524             self.assertTrue(service in control_list,
 1525                             "Service [%s] unexpectedly found" %
 1526                             service)
 1527 
 1528     def testListInactiveServices(self):
 1529         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1530                                            srcdir + "/etc/sssd.api.d")
 1531 
 1532         # Negative Test - Not Initialized
 1533         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_inactive_services)
 1534 
 1535         # Positive Test
 1536         sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf')
 1537 
 1538         control_list = [
 1539             'sssd',
 1540             'sudo']
 1541         inactive_services = sssdconfig.list_inactive_services()
 1542 
 1543         for service in control_list:
 1544             self.assertTrue(service in inactive_services,
 1545                             "Service [%s] missing" %
 1546                             service)
 1547         for service in inactive_services:
 1548             self.assertTrue(service in control_list,
 1549                             "Service [%s] unexpectedly found" %
 1550                             service)
 1551 
 1552     def testListServices(self):
 1553         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1554                                            srcdir + "/etc/sssd.api.d")
 1555 
 1556         # Negative Test - sssdconfig not initialized
 1557         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_services)
 1558 
 1559         sssdconfig.new_config()
 1560 
 1561         control_list = [
 1562             'sssd',
 1563             'pam',
 1564             'nss',
 1565             'sudo',
 1566             'autofs',
 1567             'ssh',
 1568             'pac',
 1569             'ifp',
 1570             'secrets',
 1571             'session_recording']
 1572         service_list = sssdconfig.list_services()
 1573         for service in control_list:
 1574             self.assertTrue(service in service_list,
 1575                             "Service [%s] missing" %
 1576                             service)
 1577         for service in service_list:
 1578             self.assertTrue(service in control_list,
 1579                             "Service [%s] unexpectedly found" %
 1580                             service)
 1581 
 1582     def testGetService(self):
 1583         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1584                                            srcdir + "/etc/sssd.api.d")
 1585 
 1586         # Negative Test - Not initialized
 1587         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.get_service, 'sssd')
 1588 
 1589         sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf')
 1590 
 1591         service = sssdconfig.get_service('sssd')
 1592         self.assertTrue(isinstance(service, SSSDConfig.SSSDService))
 1593 
 1594         # Verify the contents of this service
 1595         self.assertEqual(type(service.get_option('debug_timestamps')), bool)
 1596         self.assertFalse(service.get_option('debug_timestamps'))
 1597 
 1598         # Negative Test - No such service
 1599         self.assertRaises(SSSDConfig.NoServiceError, sssdconfig.get_service, 'nosuchservice')
 1600 
 1601         # Positive test - Service with invalid option loads
 1602         # but ignores the invalid option
 1603         service = sssdconfig.get_service('pam')
 1604         self.assertFalse('nosuchoption' in service.options)
 1605 
 1606     def testNewService(self):
 1607         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1608                                            srcdir + "/etc/sssd.api.d")
 1609 
 1610         # Negative Test - Not initialized
 1611         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.new_service, 'sssd')
 1612 
 1613         sssdconfig.new_config()
 1614 
 1615         # Positive Test
 1616         # First need to remove the existing service
 1617         sssdconfig.delete_service('sssd')
 1618         service = sssdconfig.new_service('sssd')
 1619         self.assertTrue(service.get_name() in sssdconfig.list_services())
 1620 
 1621         # TODO: check that the values of this new service
 1622         # are set to the defaults from the schema
 1623 
 1624     def testDeleteService(self):
 1625         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1626                                            srcdir + "/etc/sssd.api.d")
 1627 
 1628         # Negative Test - Not initialized
 1629         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.delete_service, 'sssd')
 1630 
 1631         sssdconfig.new_config()
 1632 
 1633         # Positive Test
 1634         service = sssdconfig.delete_service('sssd')
 1635 
 1636     def testSaveService(self):
 1637         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1638                                            srcdir + "/etc/sssd.api.d")
 1639 
 1640         new_service = SSSDConfig.SSSDService('sssd', sssdconfig.schema)
 1641 
 1642         # Negative Test - Not initialized
 1643         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.save_service, new_service)
 1644 
 1645         # Positive Test
 1646         sssdconfig.new_config()
 1647         sssdconfig.save_service(new_service)
 1648 
 1649         # TODO: check that all entries were saved correctly (change a few)
 1650 
 1651         # Negative Test - Type Error
 1652         self.assertRaises(TypeError, sssdconfig.save_service, self)
 1653 
 1654     def testActivateService(self):
 1655         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1656                                            srcdir + "/etc/sssd.api.d")
 1657 
 1658         service_name = 'sudo'
 1659 
 1660         # Negative test - Not initialized
 1661         self.assertRaises(SSSDConfig.NotInitializedError,
 1662                           sssdconfig.activate_service, service_name)
 1663 
 1664         sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf")
 1665 
 1666         # Positive test - Activate an inactive service
 1667         self.assertTrue(service_name in sssdconfig.list_services())
 1668         self.assertFalse(service_name in sssdconfig.list_active_services())
 1669         self.assertTrue(service_name in sssdconfig.list_inactive_services())
 1670 
 1671         sssdconfig.activate_service(service_name)
 1672         self.assertTrue(service_name in sssdconfig.list_services())
 1673         self.assertTrue(service_name in sssdconfig.list_active_services())
 1674         self.assertFalse(service_name in sssdconfig.list_inactive_services())
 1675 
 1676         # Positive test - Activate an active service
 1677         # This should succeed
 1678         sssdconfig.activate_service(service_name)
 1679         self.assertTrue(service_name in sssdconfig.list_services())
 1680         self.assertTrue(service_name in sssdconfig.list_active_services())
 1681         self.assertFalse(service_name in sssdconfig.list_inactive_services())
 1682 
 1683         # Negative test - Invalid service name
 1684         self.assertRaises(SSSDConfig.NoServiceError,
 1685                           sssdconfig.activate_service, 'nosuchservice')
 1686 
 1687         # Negative test - Invalid service name type
 1688         self.assertRaises(SSSDConfig.NoServiceError,
 1689                           sssdconfig.activate_service, self)
 1690 
 1691     def testDeactivateService(self):
 1692         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1693                                            srcdir + "/etc/sssd.api.d")
 1694 
 1695         service_name = 'pam'
 1696 
 1697         # Negative test - Not initialized
 1698         self.assertRaises(SSSDConfig.NotInitializedError,
 1699                           sssdconfig.activate_service, service_name)
 1700 
 1701         sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf")
 1702 
 1703         # Positive test -Deactivate an active service
 1704         self.assertTrue(service_name in sssdconfig.list_services())
 1705         self.assertTrue(service_name in sssdconfig.list_active_services())
 1706         self.assertFalse(service_name in sssdconfig.list_inactive_services())
 1707 
 1708         sssdconfig.deactivate_service(service_name)
 1709         self.assertTrue(service_name in sssdconfig.list_services())
 1710         self.assertFalse(service_name in sssdconfig.list_active_services())
 1711         self.assertTrue(service_name in sssdconfig.list_inactive_services())
 1712 
 1713         # Positive test - Deactivate an inactive service
 1714         # This should succeed
 1715         sssdconfig.deactivate_service(service_name)
 1716         self.assertTrue(service_name in sssdconfig.list_services())
 1717         self.assertFalse(service_name in sssdconfig.list_active_services())
 1718         self.assertTrue(service_name in sssdconfig.list_inactive_services())
 1719 
 1720         # Negative test - Invalid service name
 1721         self.assertRaises(SSSDConfig.NoServiceError,
 1722                           sssdconfig.activate_service, 'nosuchservice')
 1723 
 1724         # Negative test - Invalid service name type
 1725         self.assertRaises(SSSDConfig.NoServiceError,
 1726                           sssdconfig.activate_service, self)
 1727 
 1728     def testListActiveDomains(self):
 1729         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1730                                            srcdir + "/etc/sssd.api.d")
 1731 
 1732         # Negative Test - Not Initialized
 1733         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_active_domains)
 1734 
 1735         # Positive Test
 1736         sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf')
 1737 
 1738         control_list = [
 1739             'IPA',
 1740             'LOCAL']
 1741         active_domains = sssdconfig.list_active_domains()
 1742         self.assertTrue(isinstance(active_domains, list))
 1743 
 1744         for domain in control_list:
 1745             self.assertTrue(domain in active_domains,
 1746                             "Domain [%s] missing" %
 1747                             domain)
 1748         for domain in active_domains:
 1749             self.assertTrue(domain in control_list,
 1750                             "Domain [%s] unexpectedly found" %
 1751                             domain)
 1752 
 1753     def testListInactiveDomains(self):
 1754         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1755                                            srcdir + "/etc/sssd.api.d")
 1756 
 1757         # Negative Test - Not Initialized
 1758         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_inactive_domains)
 1759 
 1760         # Positive Test
 1761         sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf')
 1762 
 1763         control_list = [
 1764             'PROXY',
 1765             'LDAP',
 1766             'INVALIDPROVIDER',
 1767             'INVALIDOPTION',
 1768             ]
 1769         inactive_domains = sssdconfig.list_inactive_domains()
 1770 
 1771         for domain in control_list:
 1772             self.assertTrue(domain in inactive_domains,
 1773                             "Domain [%s] missing" %
 1774                             domain)
 1775         for domain in inactive_domains:
 1776             self.assertTrue(domain in control_list,
 1777                             "Domain [%s] unexpectedly found" %
 1778                             domain)
 1779 
 1780     def testListDomains(self):
 1781         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1782                                            srcdir + "/etc/sssd.api.d")
 1783 
 1784         # Negative Test - Not Initialized
 1785         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.list_domains)
 1786 
 1787         # Positive Test
 1788         sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf')
 1789 
 1790         control_list = [
 1791             'IPA',
 1792             'LOCAL',
 1793             'PROXY',
 1794             'LDAP',
 1795             'INVALIDPROVIDER',
 1796             'INVALIDOPTION',
 1797             ]
 1798         domains = sssdconfig.list_domains()
 1799 
 1800         for domain in control_list:
 1801             self.assertTrue(domain in domains,
 1802                             "Domain [%s] missing" %
 1803                             domain)
 1804         for domain in domains:
 1805             self.assertTrue(domain in control_list,
 1806                             "Domain [%s] unexpectedly found" %
 1807                             domain)
 1808 
 1809     def testListWithInvalidDomain(self):
 1810         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1811                                            srcdir + "/etc/sssd.api.d")
 1812 
 1813         # Negative Test - Not Initialized
 1814         self.assertRaises(SSSDConfig.NotInitializedError,
 1815                           sssdconfig.list_domains)
 1816 
 1817         # Positive Test
 1818         sssdconfig.import_config(
 1819             srcdir + '/testconfigs/sssd-nonexisting-services-domains.conf'
 1820         )
 1821 
 1822         domains = sssdconfig.list_active_domains()
 1823         self.assertTrue("active" in domains and len(domains) == 1,
 1824                         "domain 'active' not found among active domains")
 1825 
 1826         domains = sssdconfig.list_inactive_domains()
 1827         self.assertTrue("inactive" in domains and len(domains) == 1,
 1828                         "domain 'inactive' not found among inactive domains")
 1829 
 1830         services = sssdconfig.list_active_services()
 1831         self.assertTrue("nss" in services and len(services) == 1,
 1832                         "service 'nss' not found among active services")
 1833 
 1834         services = sssdconfig.list_inactive_services()
 1835         self.assertTrue(len(services) == 2,
 1836                         "unexpected count of inactive services")
 1837         for service in ("sssd", "pam"):
 1838             self.assertTrue(service in services,
 1839                             "service '%s' not found among inactive services"
 1840                             % service)
 1841 
 1842     def testGetDomain(self):
 1843         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1844                                            srcdir + "/etc/sssd.api.d")
 1845 
 1846         # Negative Test - Not initialized
 1847         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.get_domain, 'sssd')
 1848 
 1849         sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf')
 1850 
 1851         domain = sssdconfig.get_domain('IPA')
 1852         self.assertTrue(isinstance(domain, SSSDConfig.SSSDDomain))
 1853         self.assertTrue(domain.active)
 1854 
 1855         domain = sssdconfig.get_domain('LDAP')
 1856         self.assertTrue(isinstance(domain, SSSDConfig.SSSDDomain))
 1857         self.assertFalse(domain.active)
 1858 
 1859         # TODO verify the contents of this domain
 1860         self.assertTrue(domain.get_option('ldap_id_use_start_tls'))
 1861         self.assertTrue(domain.get_option('ldap_sudo_include_regexp'))
 1862         self.assertTrue(domain.get_option('ldap_autofs_map_master_name'))
 1863 
 1864         # Negative Test - No such domain
 1865         self.assertRaises(SSSDConfig.NoDomainError, sssdconfig.get_domain, 'nosuchdomain')
 1866 
 1867         # Positive Test - Domain with unknown provider
 1868         # Expected result: Domain is imported, but does not contain the
 1869         # unknown provider entry
 1870         domain = sssdconfig.get_domain('INVALIDPROVIDER')
 1871         self.assertFalse('chpass_provider' in domain.options)
 1872 
 1873         # Positive Test - Domain with unknown option
 1874         # Expected result: Domain is imported, but does not contain the
 1875         # unknown option entry
 1876         domain = sssdconfig.get_domain('INVALIDOPTION')
 1877         self.assertFalse('nosuchoption' in domain.options)
 1878 
 1879     def testNewDomain(self):
 1880         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1881                                            srcdir + "/etc/sssd.api.d")
 1882 
 1883         # Negative Test - Not initialized
 1884         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.new_domain, 'example.com')
 1885 
 1886         sssdconfig.new_config()
 1887 
 1888         # Positive Test
 1889         domain = sssdconfig.new_domain('example.com')
 1890         self.assertTrue(isinstance(domain, SSSDConfig.SSSDDomain))
 1891         self.assertTrue(domain.get_name() in sssdconfig.list_domains())
 1892         self.assertTrue(domain.get_name() in sssdconfig.list_inactive_domains())
 1893 
 1894         # TODO: check that the values of this new domain
 1895         # are set to the defaults from the schema
 1896 
 1897     def testDeleteDomain(self):
 1898         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1899                                            srcdir + "/etc/sssd.api.d")
 1900 
 1901         # Negative Test - Not initialized
 1902         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.delete_domain, 'IPA')
 1903 
 1904         # Positive Test
 1905         sssdconfig.import_config(srcdir + '/testconfigs/sssd-valid.conf')
 1906 
 1907         self.assertTrue('IPA' in sssdconfig.list_domains())
 1908         self.assertTrue('IPA' in sssdconfig.list_active_domains())
 1909         self.assertTrue(sssdconfig.has_section('domain/IPA'))
 1910         sssdconfig.delete_domain('IPA')
 1911         self.assertFalse('IPA' in sssdconfig.list_domains())
 1912         self.assertFalse('IPA' in sssdconfig.list_active_domains())
 1913         self.assertFalse(sssdconfig.has_section('domain/IPA'))
 1914 
 1915     def testSaveDomain(self):
 1916         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 1917                                            srcdir + "/etc/sssd.api.d")
 1918         # Negative Test - Not initialized
 1919         self.assertRaises(SSSDConfig.NotInitializedError, sssdconfig.save_domain, 'IPA')
 1920 
 1921         # Positive Test
 1922         sssdconfig.new_config()
 1923         domain = sssdconfig.new_domain('example.com')
 1924         domain.add_provider('ldap', 'id')
 1925         domain.set_option('ldap_uri', 'ldap://ldap.example.com')
 1926         domain.set_active(True)
 1927         sssdconfig.save_domain(domain)
 1928 
 1929         self.assertTrue('example.com' in sssdconfig.list_domains())
 1930         self.assertTrue('example.com' in sssdconfig.list_active_domains())
 1931         self.assertEqual(sssdconfig.get('domain/example.com', 'ldap_uri'),
 1932                          'ldap://ldap.example.com')
 1933 
 1934         # Negative Test - Type Error
 1935         self.assertRaises(TypeError, sssdconfig.save_domain, self)
 1936 
 1937         # Positive test - Change the domain name and save it
 1938         domain.set_name('example.com2')
 1939         self.assertEqual(domain.name,'example.com2')
 1940         self.assertEqual(domain.oldname,'example.com')
 1941         sssdconfig.save_domain(domain)
 1942 
 1943         self.assertTrue('example.com2' in sssdconfig.list_domains())
 1944         self.assertTrue('example.com2' in sssdconfig.list_active_domains())
 1945         self.assertTrue(sssdconfig.has_section('domain/example.com2'))
 1946         self.assertEqual(sssdconfig.get('domain/example.com2',
 1947                                         'ldap_uri'),
 1948                          'ldap://ldap.example.com')
 1949         self.assertFalse('example.com' in sssdconfig.list_domains())
 1950         self.assertFalse('example.com' in sssdconfig.list_active_domains())
 1951         self.assertFalse('example.com' in sssdconfig.list_inactive_domains())
 1952         self.assertFalse(sssdconfig.has_section('domain/example.com'))
 1953         self.assertEqual(domain.oldname, None)
 1954 
 1955         # Positive test - Set the domain inactive and save it
 1956         activelist = sssdconfig.list_active_domains()
 1957         inactivelist = sssdconfig.list_inactive_domains()
 1958 
 1959         domain.set_active(False)
 1960         sssdconfig.save_domain(domain)
 1961 
 1962         self.assertFalse('example.com2' in sssdconfig.list_active_domains())
 1963         self.assertTrue('example.com2' in sssdconfig.list_inactive_domains())
 1964 
 1965         self.assertEqual(len(sssdconfig.list_active_domains()),
 1966                          len(activelist)-1)
 1967         self.assertEqual(len(sssdconfig.list_inactive_domains()),
 1968                          len(inactivelist)+1)
 1969 
 1970         # Positive test - Set the domain active and save it
 1971         activelist = sssdconfig.list_active_domains()
 1972         inactivelist = sssdconfig.list_inactive_domains()
 1973         domain.set_active(True)
 1974         sssdconfig.save_domain(domain)
 1975 
 1976         self.assertTrue('example.com2' in sssdconfig.list_active_domains())
 1977         self.assertFalse('example.com2' in sssdconfig.list_inactive_domains())
 1978 
 1979         self.assertEqual(len(sssdconfig.list_active_domains()),
 1980                          len(activelist)+1)
 1981         self.assertEqual(len(sssdconfig.list_inactive_domains()),
 1982                          len(inactivelist)-1)
 1983 
 1984         # Positive test - Set the domain inactive and save it
 1985         activelist = sssdconfig.list_active_domains()
 1986         inactivelist = sssdconfig.list_inactive_domains()
 1987 
 1988         sssdconfig.deactivate_domain(domain.get_name())
 1989 
 1990         self.assertFalse('example.com2' in sssdconfig.list_active_domains())
 1991         self.assertTrue('example.com2' in sssdconfig.list_inactive_domains())
 1992 
 1993         self.assertEqual(len(sssdconfig.list_active_domains()),
 1994                          len(activelist)-1)
 1995         self.assertEqual(len(sssdconfig.list_inactive_domains()),
 1996                          len(inactivelist)+1)
 1997 
 1998         # Positive test - Set the domain active and save it
 1999         activelist = sssdconfig.list_active_domains()
 2000         inactivelist = sssdconfig.list_inactive_domains()
 2001 
 2002         sssdconfig.activate_domain(domain.get_name())
 2003 
 2004         self.assertTrue('example.com2' in sssdconfig.list_active_domains())
 2005         self.assertFalse('example.com2' in sssdconfig.list_inactive_domains())
 2006 
 2007         self.assertEqual(len(sssdconfig.list_active_domains()),
 2008                          len(activelist)+1)
 2009         self.assertEqual(len(sssdconfig.list_inactive_domains()),
 2010                          len(inactivelist)-1)
 2011 
 2012         # Positive test - Ensure that saved domains retain values
 2013         domain.set_option('ldap_krb5_init_creds', True)
 2014         domain.set_option('ldap_id_use_start_tls', False)
 2015         domain.set_option('ldap_user_search_base',
 2016                           'cn=accounts, dc=example, dc=com')
 2017         self.assertTrue(domain.get_option('ldap_krb5_init_creds'))
 2018         self.assertFalse(domain.get_option('ldap_id_use_start_tls'))
 2019         self.assertEqual(domain.get_option('ldap_user_search_base'),
 2020                          'cn=accounts, dc=example, dc=com')
 2021 
 2022         sssdconfig.save_domain(domain)
 2023 
 2024         of = self.tmp_dir + '/testSaveDomain.out'
 2025 
 2026         #Ensure the output file doesn't exist
 2027         try:
 2028             os.unlink(of)
 2029         except:
 2030             pass
 2031 
 2032         #Write out the file
 2033         sssdconfig.write(of)
 2034 
 2035         #Verify that the output file has the correct permissions
 2036         mode = os.stat(of)[ST_MODE]
 2037 
 2038         #Output files should not be readable or writable by
 2039         #non-owners, and should not be executable by anyone
 2040         self.assertFalse(S_IMODE(mode) & 0o177)
 2041 
 2042         #Remove the output file
 2043         os.unlink(of)
 2044 
 2045 
 2046         domain2 = sssdconfig.get_domain('example.com2')
 2047         self.assertTrue(domain2.get_option('ldap_krb5_init_creds'))
 2048         self.assertFalse(domain2.get_option('ldap_id_use_start_tls'))
 2049 
 2050     def testActivateDomain(self):
 2051         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 2052                                            srcdir + "/etc/sssd.api.d")
 2053 
 2054         domain_name = 'PROXY'
 2055 
 2056         # Negative test - Not initialized
 2057         self.assertRaises(SSSDConfig.NotInitializedError,
 2058                           sssdconfig.activate_domain, domain_name)
 2059 
 2060         sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf")
 2061 
 2062         # Positive test - Activate an inactive domain
 2063         self.assertTrue(domain_name in sssdconfig.list_domains())
 2064         self.assertFalse(domain_name in sssdconfig.list_active_domains())
 2065         self.assertTrue(domain_name in sssdconfig.list_inactive_domains())
 2066 
 2067         sssdconfig.activate_domain('PROXY')
 2068         self.assertTrue(domain_name in sssdconfig.list_domains())
 2069         self.assertTrue(domain_name in sssdconfig.list_active_domains())
 2070         self.assertFalse(domain_name in sssdconfig.list_inactive_domains())
 2071 
 2072         # Positive test - Activate an active domain
 2073         # This should succeed
 2074         sssdconfig.activate_domain('PROXY')
 2075         self.assertTrue(domain_name in sssdconfig.list_domains())
 2076         self.assertTrue(domain_name in sssdconfig.list_active_domains())
 2077         self.assertFalse(domain_name in sssdconfig.list_inactive_domains())
 2078 
 2079         # Negative test - Invalid domain name
 2080         self.assertRaises(SSSDConfig.NoDomainError,
 2081                           sssdconfig.activate_domain, 'nosuchdomain')
 2082 
 2083         # Negative test - Invalid domain name type
 2084         self.assertRaises(SSSDConfig.NoDomainError,
 2085                           sssdconfig.activate_domain, self)
 2086 
 2087     def testDeactivateDomain(self):
 2088         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 2089                                            srcdir + "/etc/sssd.api.d")
 2090 
 2091         domain_name = 'IPA'
 2092 
 2093         # Negative test - Not initialized
 2094         self.assertRaises(SSSDConfig.NotInitializedError,
 2095                           sssdconfig.activate_domain, domain_name)
 2096 
 2097         sssdconfig.import_config(srcdir + "/testconfigs/sssd-valid.conf")
 2098 
 2099         # Positive test -Deactivate an active domain
 2100         self.assertTrue(domain_name in sssdconfig.list_domains())
 2101         self.assertTrue(domain_name in sssdconfig.list_active_domains())
 2102         self.assertFalse(domain_name in sssdconfig.list_inactive_domains())
 2103 
 2104         sssdconfig.deactivate_domain(domain_name)
 2105         self.assertTrue(domain_name in sssdconfig.list_domains())
 2106         self.assertFalse(domain_name in sssdconfig.list_active_domains())
 2107         self.assertTrue(domain_name in sssdconfig.list_inactive_domains())
 2108 
 2109         # Positive test - Deactivate an inactive domain
 2110         # This should succeed
 2111         sssdconfig.deactivate_domain(domain_name)
 2112         self.assertTrue(domain_name in sssdconfig.list_domains())
 2113         self.assertFalse(domain_name in sssdconfig.list_active_domains())
 2114         self.assertTrue(domain_name in sssdconfig.list_inactive_domains())
 2115 
 2116         # Negative test - Invalid domain name
 2117         self.assertRaises(SSSDConfig.NoDomainError,
 2118                           sssdconfig.activate_domain, 'nosuchdomain')
 2119 
 2120         # Negative test - Invalid domain name type
 2121         self.assertRaises(SSSDConfig.NoDomainError,
 2122                           sssdconfig.activate_domain, self)
 2123 
 2124     def testParse(self):
 2125         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 2126                                            srcdir + "/etc/sssd.api.d")
 2127 
 2128         with open(srcdir + "/testconfigs/sssd-test-parse.conf", "r") as f:
 2129             data = sssdconfig.parse(f)
 2130 
 2131         self.assertEqual(len(data), 4)
 2132         self.assertEqual(data[-1], {'type': "section",
 2133                                     'name': "nss",
 2134                                     'value': [{'type': 'option',
 2135                                                'name': 'debug_level',
 2136                                                'value': '1'},
 2137                                               {'type': 'empty',
 2138                                                'name': 'empty'}]})
 2139 
 2140         with open(srcdir + "/testconfigs/sssd-valid.conf", "r") as f:
 2141             data = sssdconfig.parse(f)
 2142 
 2143         self.assertEqual(len(data), 10)
 2144         self.assertEqual(data[-1], {'name': "sudo",
 2145                                     'type': "section",
 2146                                     'value': [{'type': 'option',
 2147                                                'name': 'debug_level',
 2148                                                'value': '0xfC10'}]})
 2149 
 2150     def testEnabledOption(self):
 2151         """Test the new enabled option."""
 2152         # Positive Test
 2153         sssdconfig = SSSDConfig.SSSDConfig(srcdir + "/etc/sssd.api.conf",
 2154                                            srcdir + "/etc/sssd.api.d")
 2155         sssdconfig.import_config(srcdir + "/testconfigs/sssd-enabled-option.conf")
 2156 
 2157         # Verify that all sections were imported
 2158         control_list = [
 2159             'nss',
 2160             'sssd',
 2161             'pam',
 2162             'domain/enabled_1',
 2163             'domain/enabled_2',
 2164             'domain/enabled_3',
 2165             'domain/disabled_1',
 2166             'domain/disabled_2',
 2167             'domain/disabled_3',
 2168             ]
 2169 
 2170         for section in control_list:
 2171             self.assertTrue(sssdconfig.has_section(section),
 2172                             "Section [%s] missing" %
 2173                             section)
 2174         for section in sssdconfig.sections():
 2175             self.assertTrue(section['name'] in control_list)
 2176 
 2177         # Verify that all options were imported for [sssd] section
 2178         control_list = [
 2179             'services',
 2180             'reconnection_retries',
 2181             'domains',
 2182             'config_file_version',
 2183             'debug_timestamps']
 2184 
 2185         for option in control_list:
 2186             self.assertTrue(sssdconfig.has_option('sssd', option),
 2187                             "Option [%s] missing from [sssd]" %
 2188                             option)
 2189         for option in sssdconfig.options('sssd'):
 2190             if option['type'] in ('empty', 'comment'):
 2191                 continue
 2192             self.assertTrue(option['name'] in control_list,
 2193                             "Option [%s] unexpectedly found" %
 2194                             option)
 2195 
 2196         # Verify enabled domains
 2197         control_list = [
 2198             'enabled_1',
 2199             'enabled_2',
 2200             'enabled_3']
 2201 
 2202         if (sssdconfig.has_option('sssd', 'domains')):
 2203             sssd_domains = striplist(sssdconfig.get('sssd', 'domains').split(','))
 2204             domain_dict = dict.fromkeys(sssd_domains)
 2205             if '' in domain_dict:
 2206                 del domain_dict['']
 2207             sssd_domains = list(domain_dict)
 2208         else:
 2209             sssd_domains = []
 2210 
 2211         for domain in sssdconfig.list_active_domains():
 2212             self.assertTrue(domain in control_list,
 2213                             "Domain [domain/%s] should be disabled" % domain)
 2214         for domain in control_list:
 2215             self.assertTrue(domain in sssdconfig.list_active_domains(),
 2216                             "Domain [domain/%s] should be enabled" % domain)
 2217 
 2218         # Verify disabled domains
 2219         control_list = [
 2220             'disabled_1',
 2221             'disabled_2',
 2222             'disabled_3']
 2223 
 2224         for domain in sssdconfig.list_inactive_domains():
 2225             self.assertTrue(domain in control_list,
 2226                             "Domain [domain/%s] should be enabled" % domain)
 2227         for domain in control_list:
 2228             self.assertTrue(domain in sssdconfig.list_inactive_domains(),
 2229                             "Domain [domain/%s] should be disabled" % domain)
 2230 
 2231 
 2232 
 2233 if __name__ == "__main__":
 2234     error = 0
 2235 
 2236     suite = unittest.TestLoader().loadTestsFromTestCase(SSSDConfigTestSSSDService)
 2237     res = unittest.TextTestRunner().run(suite)
 2238     if not res.wasSuccessful():
 2239         error |= 0x1
 2240 
 2241     suite = unittest.TestLoader().loadTestsFromTestCase(SSSDConfigTestSSSDDomain)
 2242     res = unittest.TextTestRunner().run(suite)
 2243     if not res.wasSuccessful():
 2244         error |= 0x2
 2245 
 2246     suite = unittest.TestLoader().loadTestsFromTestCase(SSSDConfigTestSSSDConfig)
 2247     res = unittest.TextTestRunner().run(suite)
 2248     if not res.wasSuccessful():
 2249         error |= 0x4
 2250 
 2251     suite = unittest.TestLoader().loadTestsFromTestCase(SSSDConfigTestValid)
 2252     res = unittest.TextTestRunner().run(suite)
 2253     if not res.wasSuccessful():
 2254         error |= 0x8
 2255 
 2256     suite = unittest.TestLoader().loadTestsFromTestCase(SSSDConfigTestInvalid)
 2257     res = unittest.TextTestRunner().run(suite)
 2258     if not res.wasSuccessful():
 2259         error |= 0x10
 2260 
 2261     sys.exit(error)