URL: https://github.com/SSSD/sssd/pull/397
Author: amitkumar50
 Title: #397: cleanup: Remove CONFDB_DOMAIN_LEGACY_PASS
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/397/head:pr397
git checkout pr397
From 5abac427b4b1d1e93af96ca854541ba4aeff892c Mon Sep 17 00:00:00 2001
From: amitkuma <amitk...@redhat.com>
Date: Tue, 3 Oct 2017 20:49:45 +0530
Subject: [PATCH 1/2] cleanup: Remove CONFDB_DOMAIN_LEGACY_PASS

Since CONFDB_DOMAIN_LEGACY_PASS is legacy parameter
that is rooted in pre-1.0 SSSD. We should just nuke
it as we remove other legacy code.

Resolves: https://pagure.io/SSSD/sssd/issue/3530
---
 src/confdb/confdb.c                          |   8 -
 src/confdb/confdb.h                          |   1 -
 src/config/SSSDConfig/__init__.py.in         |   1 -
 src/config/SSSDConfig/sssd_upgrade_config.py | 436 +++++++++++++++++++
 src/config/SSSDConfigTest.py                 |   2 -
 src/config/cfg_rules.ini                     |   1 -
 src/config/etc/sssd.api.conf                 |   1 -
 src/db/sysdb_ops.c                           |   2 +-
 8 files changed, 437 insertions(+), 15 deletions(-)
 create mode 100644 src/config/SSSDConfig/sssd_upgrade_config.py

diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
index a3eb9c66d9..7017f1bcbf 100644
--- a/src/confdb/confdb.c
+++ b/src/confdb/confdb.c
@@ -1111,14 +1111,6 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
         goto done;
     }
 
-    ret = get_entry_as_bool(res->msgs[0], &domain->legacy_passwords,
-                            CONFDB_DOMAIN_LEGACY_PASS, 0);
-    if(ret != EOK) {
-        DEBUG(SSSDBG_FATAL_FAILURE,
-              "Invalid value for %s\n", CONFDB_DOMAIN_LEGACY_PASS);
-        goto done;
-    }
-
     /* Get the global entry cache timeout setting */
     ret = get_entry_as_uint32(res->msgs[0], &entry_cache_timeout,
                               CONFDB_DOMAIN_ENTRY_CACHE_TIMEOUT, 5400);
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index 8af625f018..ec21680e66 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -321,7 +321,6 @@ struct sss_domain_info {
 
     bool cache_credentials;
     uint32_t cache_credentials_min_ff_length;
-    bool legacy_passwords;
     bool case_sensitive;
     bool case_preserve;
 
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 32b74e4c76..be2e29ce50 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -163,7 +163,6 @@ option_strings = {
     'max_id' : _('Maximum user ID'),
     'enumerate' : _('Enable enumerating all users/groups'),
     'cache_credentials' : _('Cache credentials for offline login'),
-    'store_legacy_passwords' : _('Store password hashes'),
     'use_fully_qualified_names' : _('Display users/groups in fully-qualified form'),
     'ignore_group_members' : _('Don\'t include group members in group lookups'),
     'entry_cache_timeout' : _('Entry cache timeout length (seconds)'),
diff --git a/src/config/SSSDConfig/sssd_upgrade_config.py b/src/config/SSSDConfig/sssd_upgrade_config.py
new file mode 100644
index 0000000000..6508536150
--- /dev/null
+++ b/src/config/SSSDConfig/sssd_upgrade_config.py
@@ -0,0 +1,436 @@
+#coding=utf-8
+
+#  SSSD
+#
+#  upgrade_config.py
+#
+#  Copyright (C) Jakub Hrozek <jhro...@redhat.com>        2009
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 3 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+from __future__ import print_function
+
+import os
+import sys
+import shutil
+import traceback
+from optparse import OptionParser
+
+from .ipachangeconf import openLocked
+from .ipachangeconf import SSSDChangeConf
+
+class SSSDConfigFile(SSSDChangeConf):
+    def __init__(self, filename):
+        SSSDChangeConf.__init__(self)
+        self.filename = filename
+
+        f = openLocked(self.filename, 0o600, False)
+        self.opts = self.parse(f)
+        f.close()
+
+    def _backup_file(self, file_name):
+        " Copy the file we operate on to a backup location "
+        shutil.copy(file_name, file_name + self.backup_suffix)
+        # make sure we don't leak data, force permissions on the backup
+        os.chmod(file_name + self.backup_suffix, 0o600)
+
+    def get_version(self):
+        ver = self.get_option_index('sssd', 'config_file_version')[1]
+        if not ver:
+            # config_file_version not found -> default to version 2
+            return 2
+        try:
+            return int(ver['value'])
+        except ValueError:
+            raise SyntaxError('config_file_version not an integer')
+
+    def rename_opts(self, parent_name, rename_kw, type='option'):
+        for new_name, old_name in rename_kw.items():
+            index, item = self.get_option_index(parent_name, old_name, type)
+            if item:
+                item['name'] = new_name
+
+    def _add_dns_domain_name(self, domain):
+        id_provider = self.findOpts(domain['value'], 'option', 'id_provider')[1]
+        dns_domain_name = { 'type' : 'option',
+                            'name' : 'dns_discovery_domain',
+                            'value' : domain['name'].lstrip('domain/') }
+        if id_provider['value'] == 'ldap':
+            server = self.findOpts(domain['value'], 'option', 'ldap_uri')[1]
+            if not server or "__srv__" in server['value']:
+                domain['value'].insert(0, dns_domain_name)
+                return
+        elif id_provider['value'] == 'ipa':
+            server = self.findOpts(domain['value'], 'option', 'ipa_server')[1]
+            if not server or "__srv__" in server['value']:
+                domain['value'].insert(0, dns_domain_name)
+                return
+
+        auth_provider = self.findOpts(domain['value'], 'option', 'auth_provider')[1]
+        if auth_provider and auth_provider['value'] == 'krb5':
+            server = self.findOpts(domain['value'], 'option', 'krb5_server')[1]
+            if not server or "__srv__" in server['value']:
+                domain['value'].insert(0, dns_domain_name)
+
+    def _do_v2_changes(self):
+        # remove Data Provider
+        srvlist = self.get_option_index('sssd', 'services')[1]
+        if srvlist:
+            services = [ srv.strip() for srv in srvlist['value'].split(',') ]
+            if 'dp' in services:
+                services.remove('dp')
+            srvlist['value'] = ", ".join([srv for srv in services])
+        self.delete_option('section', 'dp')
+
+        for domain in [ s for s in self.sections() if s['name'].startswith("domain/") ]:
+            # remove magic_private_groups from all domains
+            self.delete_option_subtree(domain['value'], 'option', 'magic_private_groups')
+            # check if we need to add dns_domain
+            self._add_dns_domain_name(domain)
+
+    def _update_option(self, to_section_name, from_section_name, opts):
+        to_section = [ s for s in self.sections() if s['name'].strip() == to_section_name ]
+        from_section = [ s for s in self.sections() if s['name'].strip() == from_section_name ]
+
+        if len(to_section) > 0 and len(from_section) > 0:
+            vals = to_section[0]['value']
+            for o in [one_opt for one_opt in from_section[0]['value'] if one_opt['name'] in opts]:
+                updated = False
+                for v in vals:
+                    if v['type'] == 'empty':
+                        continue
+                    # if already in list, just update
+                    if o['name'] == v['name']:
+                        o['value'] = v['value']
+                        updated = True
+                # not in list, add there
+                if not updated:
+                    vals.insert(0, { 'name' : o['name'], 'type' : o['type'], 'value' : o['value'] })
+
+    def _migrate_enumerate(self, domain):
+        " Enumerate was special as it turned into bool from (0,1,2,3) enum "
+        enum = self.findOpts(domain, 'option', 'enumerate')[1]
+        if enum:
+            if enum['value'].upper() not in ['TRUE', 'FALSE']:
+                try:
+                    enum['value'] = int(enum['value'])
+                except ValueError:
+                    raise ValueError('Cannot convert value %s in domain %s' % (enum['value'], domain['name']))
+
+                if enum['value'] == 0:
+                    enum['value'] = 'FALSE'
+                elif enum['value'] > 0:
+                    enum['value'] = 'TRUE'
+                else:
+                    raise ValueError('Cannot convert value %s in domain %s' % (enum['value'], domain['name']))
+
+    def _migrate_domain(self, domain):
+        # rename the section
+        domain['name'] = domain['name'].strip().replace('domains', 'domain')
+
+        # Generic options - new:old
+        generic_kw = { 'min_id' : 'minId',
+                       'max_id': 'maxId',
+                       'timeout': 'timeout',
+                       'magic_private_groups' : 'magicPrivateGroups',
+                       'cache_credentials' : 'cache-credentials',
+                       'id_provider' : 'provider',
+                       'auth_provider' : 'auth-module',
+                       'access_provider' : 'access-module',
+                       'chpass_provider' : 'chpass-module',
+                       'session_provider' : 'session-module',
+                       'use_fully_qualified_names' : 'useFullyQualifiedNames',
+                      }
+        # Proxy options
+        proxy_kw = { 'proxy_pam_target' : 'pam-target',
+                     'proxy_lib_name'   : 'libName',
+                   }
+        # LDAP options - new:old
+        ldap_kw = { 'ldap_uri' : 'ldapUri',
+                    'ldap_schema' : 'ldapSchema',
+                    'ldap_default_bind_dn' : 'defaultBindDn',
+                    'ldap_default_authtok_type' : 'defaultAuthtokType',
+                    'ldap_default_authtok' : 'defaultAuthtok',
+                    'ldap_user_search_base' : 'userSearchBase',
+                    'ldap_user_search_scope' : 'userSearchScope',
+                    'ldap_user_search_filter' : 'userSearchFilter',
+                    'ldap_user_object_class' : 'userObjectClass',
+                    'ldap_user_name' : 'userName',
+                    'ldap_user_pwd' : 'userPassword',
+                    'ldap_user_uid_number' : 'userUidNumber',
+                    'ldap_user_gid_number' : 'userGidNumber',
+                    'ldap_user_gecos' : 'userGecos',
+                    'ldap_user_home_directory' : 'userHomeDirectory',
+                    'ldap_user_shell' : 'userShell',
+                    'ldap_user_uuid' : 'userUUID',
+                    'ldap_user_principal' : 'userPrincipal',
+                    'ldap_force_upper_case_realm' : 'force_upper_case_realm',
+                    'ldap_user_fullname' : 'userFullname',
+                    'ldap_user_member_of' : 'userMemberOf',
+                    'ldap_user_modify_timestamp' : 'modifyTimestamp',
+                    'ldap_group_search_base' : 'groupSearchBase',
+                    'ldap_group_search_scope' : 'groupSearchScope',
+                    'ldap_group_search_filter' : 'groupSearchFilter',
+                    'ldap_group_object_class' : 'groupObjectClass',
+                    'ldap_group_name' : 'groupName',
+                    'ldap_group_pwd' : 'userPassword',
+                    'ldap_group_gid_number' : 'groupGidNumber',
+                    'ldap_group_member' : 'groupMember',
+                    'ldap_group_uuid' : 'groupUUID',
+                    'ldap_group_modify_timestamp' : 'modifyTimestamp',
+                    'ldap_network_timeout' : 'network_timeout',
+                    'ldap_offline_timeout' : 'offline_timeout',
+                    'ldap_enumeration_refresh_timeout' : 'enumeration_refresh_timeout',
+                    'ldap_stale_time' : 'stale_time',
+                    'ldap_opt_timeout' : 'opt_timeout',
+                    'ldap_tls_reqcert' : 'tls_reqcert',
+                    'ldap_netgroup_search_base' : 'netgroupSearchBase',
+                    'ldap_netgroup_object_class' : 'netgroupObjectClass',
+                    'ldap_netgroup_name' : 'netgroupName',
+                    'ldap_netgroup_member' : 'netgroupMember',
+                    'ldap_netgroup_triple' : 'netgroupTriple',
+                    'ldap_netgroup_modify_timestamp' : 'netgroupModifyTimestamp',
+                   }
+        krb5_kw = { 'krb5_server' : 'krb5KDCIP',
+                    'krb5_realm'  : 'krb5REALM',
+                    'krb5_try_simple_upn' : 'krb5try_simple_upn',
+                    'krb5_changepw_principal' : 'krb5changepw_principle',
+                    'krb5_ccachedir' : 'krb5ccache_dir',
+                    'krb5_auth_timeout' : 'krb5auth_timeout',
+                    'krb5_ccname_template' : 'krb5ccname_template',
+                  }
+        user_defaults_kw = { 'default_shell' : 'defaultShell',
+                             'base_directory' : 'baseDirectory',
+                           }
+
+        self._migrate_enumerate(domain['value'])
+        self.rename_opts(domain['name'], generic_kw)
+        self.rename_opts(domain['name'], proxy_kw)
+        self.rename_opts(domain['name'], ldap_kw)
+        self.rename_opts(domain['name'], krb5_kw)
+
+        # remove obsolete libPath option
+        self.delete_option_subtree(domain['value'], 'option', 'libPath')
+
+        # configuration files before 0.5.0 did not enforce provider= in local domains
+        # it did special-case by domain name (LOCAL)
+        prvindex, prv = self.findOpts(domain['value'], 'option', 'id_provider')
+        if not prv and domain['name'] == 'domain/LOCAL':
+            prv = { 'type'  : 'option',
+                    'name'  : 'id_provider',
+                    'value' : 'local',
+                  }
+            domain['value'].insert(0, prv)
+
+        # if domain was local, update with parameters from [user_defaults]
+        if prv['value'] == 'local':
+            self._update_option(domain['name'], 'user_defaults', user_defaults_kw.values())
+            self.delete_option('section', 'user_defaults')
+            self.rename_opts(domain['name'], user_defaults_kw)
+
+        # if domain had provider = files, unroll that into provider=proxy, proxy_lib_name=files
+        if prv['value'] == 'files':
+            prv['value'] = 'proxy'
+            libkw = { 'type'  : 'option',
+                      'name'  : 'proxy_lib_name',
+                      'value' : 'files',
+                    }
+            domain['value'].insert(prvindex+1, libkw)
+
+    def _migrate_domains(self):
+        for domain in [ s for s in self.sections() if s['name'].startswith("domains/") ]:
+            self._migrate_domain(domain)
+
+    def _update_if_exists(self, opt, to_name, from_section, from_name):
+        index, item = self.get_option_index(from_section, from_name)
+        if item:
+            item['name'] = to_name
+            opt.append(item)
+
+    def _migrate_services(self):
+        # [service] - options common to all services, no section as in v1
+        service_kw = { 'reconnection_retries' : 'reconnection_retries',
+                       'debug_level' : 'debug-level',
+                       'debug_timestamps' : 'debug-timestamps',
+                       'command' : 'command',
+                       'timeout' : 'timeout',
+                     }
+
+        # rename services sections
+        names_kw = { 'nss' : 'services/nss',
+                     'pam' : 'services/pam',
+                     'dp'  : 'services/dp',
+                   }
+        self.rename_opts(None, names_kw, 'section')
+
+        # [sssd] - monitor service
+        sssd_kw = [
+                    { 'type'  : 'option',
+                      'name'  : 'config_file_version',
+                      'value' : '2',
+                      'action': 'set',
+                    }
+                  ]
+        self._update_if_exists(sssd_kw, 'domains',
+                               'domains', 'domains')
+        self._update_if_exists(sssd_kw, 'services',
+                               'services', 'activeServices')
+        self._update_if_exists(sssd_kw, 'sbus_timeout',
+                               'services/monitor', 'sbusTimeout')
+        self._update_if_exists(sssd_kw, 're_expression',
+                              'names', 're-expression')
+        self._update_if_exists(sssd_kw, 're_expression',
+                              'names', 'full-name-format')
+        self.add_section('sssd', sssd_kw)
+        # update from general services section and monitor
+        self._update_option('sssd', 'services', service_kw.values())
+        self._update_option('sssd', 'services/monitor', service_kw.values())
+
+        # [nss] - Name service
+        nss_kw = { 'enum_cache_timeout' : 'EnumCacheTimeout',
+                   'entry_cache_timeout' : 'EntryCacheTimeout',
+                   'entry_cache_nowait_timeout' : 'EntryCacheNoWaitRefreshTimeout',
+                   'entry_negative_timeout ' : 'EntryNegativeTimeout',
+                   'filter_users' : 'filterUsers',
+                   'filter_groups' : 'filterGroups',
+                   'filter_users_in_groups' : 'filterUsersInGroups',
+                   }
+        nss_kw.update(service_kw)
+        self._update_option('nss', 'services', service_kw.values())
+        self.rename_opts('nss', nss_kw)
+
+        # [pam] - Authentication service
+        pam_kw = {}
+        pam_kw.update(service_kw)
+        self._update_option('pam', 'services', service_kw.values())
+        self.rename_opts('pam', pam_kw)
+
+        # remove obsolete sections
+        self.delete_option('section', 'services')
+        self.delete_option('section', 'names')
+        self.delete_option('section', 'domains')
+        self.delete_option('section', 'services/monitor')
+
+    def v2_changes(self, out_file_name, backup=True):
+        # read in the old file, make backup if needed
+        if backup:
+            self._backup_file(self.filename)
+
+        self._do_v2_changes()
+
+        # all done, write the file
+        of = open(out_file_name, "wb")
+        output = self.dump(self.opts)
+        of.write(output)
+        of.close()
+        # make sure it has the right permissions too
+        os.chmod(out_file_name, 0o600)
+
+    def upgrade_v2(self, out_file_name, backup=True):
+        # read in the old file, make backup if needed
+        if backup:
+            self._backup_file(self.filename)
+
+        # do the migration to v2 format
+        # do the upgrade
+        self._migrate_services()
+        self._migrate_domains()
+        # also include any changes in the v2 format
+        self._do_v2_changes()
+
+        # all done, write the file
+        of = open(out_file_name, "wb")
+        output = self.dump(self.opts)
+        of.write(output)
+        of.close()
+        # make sure it has the right permissions too
+        os.chmod(out_file_name, 0o600)
+
+def parse_options():
+    parser = OptionParser()
+    parser.add_option("-f", "--file",
+                      dest="filename", default="/etc/sssd/sssd.conf",
+                      help="Set input file to FILE", metavar="FILE")
+    parser.add_option("-o", "--outfile",
+                      dest="outfile", default=None,
+                      help="Set output file to OUTFILE", metavar="OUTFILE")
+    parser.add_option("", "--no-backup", action="store_false",
+                      dest="backup", default=True,
+                      help="""Do not provide backup file after conversion.
+The script copies the original file with the suffix .bak
+by default""")
+    parser.add_option("-v", "--verbose", action="store_true",
+                      dest="verbose", default=False,
+                      help="Be verbose")
+    (options, args) = parser.parse_args()
+    if len(args) > 0:
+        print >>sys.stderr, "Stray arguments: %s" % ' '.join([a for a in args])
+        return None
+
+    # do the conversion in place by default
+    if not options.outfile:
+        options.outfile = options.filename
+
+    return options
+
+def verbose(msg, verbose):
+    if verbose:
+        print(msg)
+
+def main():
+    options = parse_options()
+    if not options:
+        print >>sys.stderr, "Cannot parse options"
+        return 1
+
+    try:
+        config = SSSDConfigFile(options.filename)
+    except SyntaxError:
+        verbose(traceback.format_exc(), options.verbose)
+        print >>sys.stderr, "Cannot parse config file %s" % options.filename
+        return 1
+    except Exception as e:
+        print("ERROR: %s" % e)
+        verbose(traceback.format_exc(), options.verbose)
+        return 1
+
+    # make sure we keep strict settings when creating new files
+    os.umask(0o077)
+
+    version = config.get_version()
+    if version == 2:
+        verbose("Looks like v2, only checking changes", options.verbose)
+        try:
+            config.v2_changes(options.outfile, options.backup)
+        except Exception as e:
+            print("ERROR: %s" % e)
+            verbose(traceback.format_exc(), options.verbose)
+            return 1
+    elif version == 1:
+        verbose("Looks like v1, performing full upgrade", options.verbose)
+        try:
+            config.upgrade_v2(options.outfile, options.backup)
+        except Exception as e:
+            print("ERROR: %s" % e)
+            verbose(traceback.format_exc(), options.verbose)
+            return 1
+    else:
+        print("Can only upgrade from v1 to v2, file %s looks like version %d" % (options.filename, config.get_version()), file=sys.stderr)
+        return 1
+
+    return 0
+
+if __name__ == "__main__":
+    ret = main()
+    sys.exit(ret)
+
diff --git a/src/config/SSSDConfigTest.py b/src/config/SSSDConfigTest.py
index 87d1f6e641..7117d2972f 100755
--- a/src/config/SSSDConfigTest.py
+++ b/src/config/SSSDConfigTest.py
@@ -573,7 +573,6 @@ def testListOptions(self):
             'enumerate',
             'cache_credentials',
             'cache_credentials_minimal_first_factor_length',
-            'store_legacy_passwords',
             'use_fully_qualified_names',
             'ignore_group_members',
             'filter_users',
@@ -944,7 +943,6 @@ def testRemoveProvider(self):
             'enumerate',
             'cache_credentials',
             'cache_credentials_minimal_first_factor_length',
-            'store_legacy_passwords',
             'use_fully_qualified_names',
             'ignore_group_members',
             'filter_users',
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
index 5513227803..28102732bc 100644
--- a/src/config/cfg_rules.ini
+++ b/src/config/cfg_rules.ini
@@ -355,7 +355,6 @@ option = subdomain_enumerate
 option = offline_timeout
 option = cache_credentials
 option = cache_credentials_minimal_first_factor_length
-option = store_legacy_passwords
 option = use_fully_qualified_names
 option = ignore_group_members
 option = entry_cache_timeout
diff --git a/src/config/etc/sssd.api.conf b/src/config/etc/sssd.api.conf
index 2be2e3e685..c25592f174 100644
--- a/src/config/etc/sssd.api.conf
+++ b/src/config/etc/sssd.api.conf
@@ -159,7 +159,6 @@ subdomain_enumerate = str, None, false
 offline_timeout = int, None, false
 cache_credentials = bool, None, false
 cache_credentials_minimal_first_factor_length = int, None, false
-store_legacy_passwords = bool, None, false
 use_fully_qualified_names = bool, None, false
 ignore_group_members = bool, None, false
 entry_cache_timeout = int, None, false
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index 0210587776..4fa963f1d4 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -2710,7 +2710,7 @@ int sysdb_store_user(struct sss_domain_info *domain,
         }
     }
 
-    if (pwd && (domain->legacy_passwords || !*pwd)) {
+    if (pwd && !*pwd) {
         ret = sysdb_attrs_add_string(attrs, SYSDB_PWD, pwd);
         if (ret) goto done;
     }

From 10edc4b724b2c9b915232ff4b0b2c41fdf36bfee Mon Sep 17 00:00:00 2001
From: Amit Kumar <amitk...@redhat.com>
Date: Tue, 7 Aug 2018 13:48:03 +0530
Subject: [PATCH 2/2] cleanup: Remove CONFDB_DOMAIN_LEGACY_PASS

Since CONFDB_DOMAIN_LEGACY_PASS is legacy parameter
that is rooted in pre-1.0 SSSD. We should just nuke
it as we remove other legacy code.

Resolves: https://pagure.io/SSSD/sssd/issue/3530
---
 src/config/SSSDConfig/sssd_upgrade_config.py | 436 -------------------
 1 file changed, 436 deletions(-)
 delete mode 100644 src/config/SSSDConfig/sssd_upgrade_config.py

diff --git a/src/config/SSSDConfig/sssd_upgrade_config.py b/src/config/SSSDConfig/sssd_upgrade_config.py
deleted file mode 100644
index 6508536150..0000000000
--- a/src/config/SSSDConfig/sssd_upgrade_config.py
+++ /dev/null
@@ -1,436 +0,0 @@
-#coding=utf-8
-
-#  SSSD
-#
-#  upgrade_config.py
-#
-#  Copyright (C) Jakub Hrozek <jhro...@redhat.com>        2009
-#
-#  This program is free software; you can redistribute it and/or modify
-#  it under the terms of the GNU General Public License as published by
-#  the Free Software Foundation; either version 3 of the License, or
-#  (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#
-#  You should have received a copy of the GNU General Public License
-#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-from __future__ import print_function
-
-import os
-import sys
-import shutil
-import traceback
-from optparse import OptionParser
-
-from .ipachangeconf import openLocked
-from .ipachangeconf import SSSDChangeConf
-
-class SSSDConfigFile(SSSDChangeConf):
-    def __init__(self, filename):
-        SSSDChangeConf.__init__(self)
-        self.filename = filename
-
-        f = openLocked(self.filename, 0o600, False)
-        self.opts = self.parse(f)
-        f.close()
-
-    def _backup_file(self, file_name):
-        " Copy the file we operate on to a backup location "
-        shutil.copy(file_name, file_name + self.backup_suffix)
-        # make sure we don't leak data, force permissions on the backup
-        os.chmod(file_name + self.backup_suffix, 0o600)
-
-    def get_version(self):
-        ver = self.get_option_index('sssd', 'config_file_version')[1]
-        if not ver:
-            # config_file_version not found -> default to version 2
-            return 2
-        try:
-            return int(ver['value'])
-        except ValueError:
-            raise SyntaxError('config_file_version not an integer')
-
-    def rename_opts(self, parent_name, rename_kw, type='option'):
-        for new_name, old_name in rename_kw.items():
-            index, item = self.get_option_index(parent_name, old_name, type)
-            if item:
-                item['name'] = new_name
-
-    def _add_dns_domain_name(self, domain):
-        id_provider = self.findOpts(domain['value'], 'option', 'id_provider')[1]
-        dns_domain_name = { 'type' : 'option',
-                            'name' : 'dns_discovery_domain',
-                            'value' : domain['name'].lstrip('domain/') }
-        if id_provider['value'] == 'ldap':
-            server = self.findOpts(domain['value'], 'option', 'ldap_uri')[1]
-            if not server or "__srv__" in server['value']:
-                domain['value'].insert(0, dns_domain_name)
-                return
-        elif id_provider['value'] == 'ipa':
-            server = self.findOpts(domain['value'], 'option', 'ipa_server')[1]
-            if not server or "__srv__" in server['value']:
-                domain['value'].insert(0, dns_domain_name)
-                return
-
-        auth_provider = self.findOpts(domain['value'], 'option', 'auth_provider')[1]
-        if auth_provider and auth_provider['value'] == 'krb5':
-            server = self.findOpts(domain['value'], 'option', 'krb5_server')[1]
-            if not server or "__srv__" in server['value']:
-                domain['value'].insert(0, dns_domain_name)
-
-    def _do_v2_changes(self):
-        # remove Data Provider
-        srvlist = self.get_option_index('sssd', 'services')[1]
-        if srvlist:
-            services = [ srv.strip() for srv in srvlist['value'].split(',') ]
-            if 'dp' in services:
-                services.remove('dp')
-            srvlist['value'] = ", ".join([srv for srv in services])
-        self.delete_option('section', 'dp')
-
-        for domain in [ s for s in self.sections() if s['name'].startswith("domain/") ]:
-            # remove magic_private_groups from all domains
-            self.delete_option_subtree(domain['value'], 'option', 'magic_private_groups')
-            # check if we need to add dns_domain
-            self._add_dns_domain_name(domain)
-
-    def _update_option(self, to_section_name, from_section_name, opts):
-        to_section = [ s for s in self.sections() if s['name'].strip() == to_section_name ]
-        from_section = [ s for s in self.sections() if s['name'].strip() == from_section_name ]
-
-        if len(to_section) > 0 and len(from_section) > 0:
-            vals = to_section[0]['value']
-            for o in [one_opt for one_opt in from_section[0]['value'] if one_opt['name'] in opts]:
-                updated = False
-                for v in vals:
-                    if v['type'] == 'empty':
-                        continue
-                    # if already in list, just update
-                    if o['name'] == v['name']:
-                        o['value'] = v['value']
-                        updated = True
-                # not in list, add there
-                if not updated:
-                    vals.insert(0, { 'name' : o['name'], 'type' : o['type'], 'value' : o['value'] })
-
-    def _migrate_enumerate(self, domain):
-        " Enumerate was special as it turned into bool from (0,1,2,3) enum "
-        enum = self.findOpts(domain, 'option', 'enumerate')[1]
-        if enum:
-            if enum['value'].upper() not in ['TRUE', 'FALSE']:
-                try:
-                    enum['value'] = int(enum['value'])
-                except ValueError:
-                    raise ValueError('Cannot convert value %s in domain %s' % (enum['value'], domain['name']))
-
-                if enum['value'] == 0:
-                    enum['value'] = 'FALSE'
-                elif enum['value'] > 0:
-                    enum['value'] = 'TRUE'
-                else:
-                    raise ValueError('Cannot convert value %s in domain %s' % (enum['value'], domain['name']))
-
-    def _migrate_domain(self, domain):
-        # rename the section
-        domain['name'] = domain['name'].strip().replace('domains', 'domain')
-
-        # Generic options - new:old
-        generic_kw = { 'min_id' : 'minId',
-                       'max_id': 'maxId',
-                       'timeout': 'timeout',
-                       'magic_private_groups' : 'magicPrivateGroups',
-                       'cache_credentials' : 'cache-credentials',
-                       'id_provider' : 'provider',
-                       'auth_provider' : 'auth-module',
-                       'access_provider' : 'access-module',
-                       'chpass_provider' : 'chpass-module',
-                       'session_provider' : 'session-module',
-                       'use_fully_qualified_names' : 'useFullyQualifiedNames',
-                      }
-        # Proxy options
-        proxy_kw = { 'proxy_pam_target' : 'pam-target',
-                     'proxy_lib_name'   : 'libName',
-                   }
-        # LDAP options - new:old
-        ldap_kw = { 'ldap_uri' : 'ldapUri',
-                    'ldap_schema' : 'ldapSchema',
-                    'ldap_default_bind_dn' : 'defaultBindDn',
-                    'ldap_default_authtok_type' : 'defaultAuthtokType',
-                    'ldap_default_authtok' : 'defaultAuthtok',
-                    'ldap_user_search_base' : 'userSearchBase',
-                    'ldap_user_search_scope' : 'userSearchScope',
-                    'ldap_user_search_filter' : 'userSearchFilter',
-                    'ldap_user_object_class' : 'userObjectClass',
-                    'ldap_user_name' : 'userName',
-                    'ldap_user_pwd' : 'userPassword',
-                    'ldap_user_uid_number' : 'userUidNumber',
-                    'ldap_user_gid_number' : 'userGidNumber',
-                    'ldap_user_gecos' : 'userGecos',
-                    'ldap_user_home_directory' : 'userHomeDirectory',
-                    'ldap_user_shell' : 'userShell',
-                    'ldap_user_uuid' : 'userUUID',
-                    'ldap_user_principal' : 'userPrincipal',
-                    'ldap_force_upper_case_realm' : 'force_upper_case_realm',
-                    'ldap_user_fullname' : 'userFullname',
-                    'ldap_user_member_of' : 'userMemberOf',
-                    'ldap_user_modify_timestamp' : 'modifyTimestamp',
-                    'ldap_group_search_base' : 'groupSearchBase',
-                    'ldap_group_search_scope' : 'groupSearchScope',
-                    'ldap_group_search_filter' : 'groupSearchFilter',
-                    'ldap_group_object_class' : 'groupObjectClass',
-                    'ldap_group_name' : 'groupName',
-                    'ldap_group_pwd' : 'userPassword',
-                    'ldap_group_gid_number' : 'groupGidNumber',
-                    'ldap_group_member' : 'groupMember',
-                    'ldap_group_uuid' : 'groupUUID',
-                    'ldap_group_modify_timestamp' : 'modifyTimestamp',
-                    'ldap_network_timeout' : 'network_timeout',
-                    'ldap_offline_timeout' : 'offline_timeout',
-                    'ldap_enumeration_refresh_timeout' : 'enumeration_refresh_timeout',
-                    'ldap_stale_time' : 'stale_time',
-                    'ldap_opt_timeout' : 'opt_timeout',
-                    'ldap_tls_reqcert' : 'tls_reqcert',
-                    'ldap_netgroup_search_base' : 'netgroupSearchBase',
-                    'ldap_netgroup_object_class' : 'netgroupObjectClass',
-                    'ldap_netgroup_name' : 'netgroupName',
-                    'ldap_netgroup_member' : 'netgroupMember',
-                    'ldap_netgroup_triple' : 'netgroupTriple',
-                    'ldap_netgroup_modify_timestamp' : 'netgroupModifyTimestamp',
-                   }
-        krb5_kw = { 'krb5_server' : 'krb5KDCIP',
-                    'krb5_realm'  : 'krb5REALM',
-                    'krb5_try_simple_upn' : 'krb5try_simple_upn',
-                    'krb5_changepw_principal' : 'krb5changepw_principle',
-                    'krb5_ccachedir' : 'krb5ccache_dir',
-                    'krb5_auth_timeout' : 'krb5auth_timeout',
-                    'krb5_ccname_template' : 'krb5ccname_template',
-                  }
-        user_defaults_kw = { 'default_shell' : 'defaultShell',
-                             'base_directory' : 'baseDirectory',
-                           }
-
-        self._migrate_enumerate(domain['value'])
-        self.rename_opts(domain['name'], generic_kw)
-        self.rename_opts(domain['name'], proxy_kw)
-        self.rename_opts(domain['name'], ldap_kw)
-        self.rename_opts(domain['name'], krb5_kw)
-
-        # remove obsolete libPath option
-        self.delete_option_subtree(domain['value'], 'option', 'libPath')
-
-        # configuration files before 0.5.0 did not enforce provider= in local domains
-        # it did special-case by domain name (LOCAL)
-        prvindex, prv = self.findOpts(domain['value'], 'option', 'id_provider')
-        if not prv and domain['name'] == 'domain/LOCAL':
-            prv = { 'type'  : 'option',
-                    'name'  : 'id_provider',
-                    'value' : 'local',
-                  }
-            domain['value'].insert(0, prv)
-
-        # if domain was local, update with parameters from [user_defaults]
-        if prv['value'] == 'local':
-            self._update_option(domain['name'], 'user_defaults', user_defaults_kw.values())
-            self.delete_option('section', 'user_defaults')
-            self.rename_opts(domain['name'], user_defaults_kw)
-
-        # if domain had provider = files, unroll that into provider=proxy, proxy_lib_name=files
-        if prv['value'] == 'files':
-            prv['value'] = 'proxy'
-            libkw = { 'type'  : 'option',
-                      'name'  : 'proxy_lib_name',
-                      'value' : 'files',
-                    }
-            domain['value'].insert(prvindex+1, libkw)
-
-    def _migrate_domains(self):
-        for domain in [ s for s in self.sections() if s['name'].startswith("domains/") ]:
-            self._migrate_domain(domain)
-
-    def _update_if_exists(self, opt, to_name, from_section, from_name):
-        index, item = self.get_option_index(from_section, from_name)
-        if item:
-            item['name'] = to_name
-            opt.append(item)
-
-    def _migrate_services(self):
-        # [service] - options common to all services, no section as in v1
-        service_kw = { 'reconnection_retries' : 'reconnection_retries',
-                       'debug_level' : 'debug-level',
-                       'debug_timestamps' : 'debug-timestamps',
-                       'command' : 'command',
-                       'timeout' : 'timeout',
-                     }
-
-        # rename services sections
-        names_kw = { 'nss' : 'services/nss',
-                     'pam' : 'services/pam',
-                     'dp'  : 'services/dp',
-                   }
-        self.rename_opts(None, names_kw, 'section')
-
-        # [sssd] - monitor service
-        sssd_kw = [
-                    { 'type'  : 'option',
-                      'name'  : 'config_file_version',
-                      'value' : '2',
-                      'action': 'set',
-                    }
-                  ]
-        self._update_if_exists(sssd_kw, 'domains',
-                               'domains', 'domains')
-        self._update_if_exists(sssd_kw, 'services',
-                               'services', 'activeServices')
-        self._update_if_exists(sssd_kw, 'sbus_timeout',
-                               'services/monitor', 'sbusTimeout')
-        self._update_if_exists(sssd_kw, 're_expression',
-                              'names', 're-expression')
-        self._update_if_exists(sssd_kw, 're_expression',
-                              'names', 'full-name-format')
-        self.add_section('sssd', sssd_kw)
-        # update from general services section and monitor
-        self._update_option('sssd', 'services', service_kw.values())
-        self._update_option('sssd', 'services/monitor', service_kw.values())
-
-        # [nss] - Name service
-        nss_kw = { 'enum_cache_timeout' : 'EnumCacheTimeout',
-                   'entry_cache_timeout' : 'EntryCacheTimeout',
-                   'entry_cache_nowait_timeout' : 'EntryCacheNoWaitRefreshTimeout',
-                   'entry_negative_timeout ' : 'EntryNegativeTimeout',
-                   'filter_users' : 'filterUsers',
-                   'filter_groups' : 'filterGroups',
-                   'filter_users_in_groups' : 'filterUsersInGroups',
-                   }
-        nss_kw.update(service_kw)
-        self._update_option('nss', 'services', service_kw.values())
-        self.rename_opts('nss', nss_kw)
-
-        # [pam] - Authentication service
-        pam_kw = {}
-        pam_kw.update(service_kw)
-        self._update_option('pam', 'services', service_kw.values())
-        self.rename_opts('pam', pam_kw)
-
-        # remove obsolete sections
-        self.delete_option('section', 'services')
-        self.delete_option('section', 'names')
-        self.delete_option('section', 'domains')
-        self.delete_option('section', 'services/monitor')
-
-    def v2_changes(self, out_file_name, backup=True):
-        # read in the old file, make backup if needed
-        if backup:
-            self._backup_file(self.filename)
-
-        self._do_v2_changes()
-
-        # all done, write the file
-        of = open(out_file_name, "wb")
-        output = self.dump(self.opts)
-        of.write(output)
-        of.close()
-        # make sure it has the right permissions too
-        os.chmod(out_file_name, 0o600)
-
-    def upgrade_v2(self, out_file_name, backup=True):
-        # read in the old file, make backup if needed
-        if backup:
-            self._backup_file(self.filename)
-
-        # do the migration to v2 format
-        # do the upgrade
-        self._migrate_services()
-        self._migrate_domains()
-        # also include any changes in the v2 format
-        self._do_v2_changes()
-
-        # all done, write the file
-        of = open(out_file_name, "wb")
-        output = self.dump(self.opts)
-        of.write(output)
-        of.close()
-        # make sure it has the right permissions too
-        os.chmod(out_file_name, 0o600)
-
-def parse_options():
-    parser = OptionParser()
-    parser.add_option("-f", "--file",
-                      dest="filename", default="/etc/sssd/sssd.conf",
-                      help="Set input file to FILE", metavar="FILE")
-    parser.add_option("-o", "--outfile",
-                      dest="outfile", default=None,
-                      help="Set output file to OUTFILE", metavar="OUTFILE")
-    parser.add_option("", "--no-backup", action="store_false",
-                      dest="backup", default=True,
-                      help="""Do not provide backup file after conversion.
-The script copies the original file with the suffix .bak
-by default""")
-    parser.add_option("-v", "--verbose", action="store_true",
-                      dest="verbose", default=False,
-                      help="Be verbose")
-    (options, args) = parser.parse_args()
-    if len(args) > 0:
-        print >>sys.stderr, "Stray arguments: %s" % ' '.join([a for a in args])
-        return None
-
-    # do the conversion in place by default
-    if not options.outfile:
-        options.outfile = options.filename
-
-    return options
-
-def verbose(msg, verbose):
-    if verbose:
-        print(msg)
-
-def main():
-    options = parse_options()
-    if not options:
-        print >>sys.stderr, "Cannot parse options"
-        return 1
-
-    try:
-        config = SSSDConfigFile(options.filename)
-    except SyntaxError:
-        verbose(traceback.format_exc(), options.verbose)
-        print >>sys.stderr, "Cannot parse config file %s" % options.filename
-        return 1
-    except Exception as e:
-        print("ERROR: %s" % e)
-        verbose(traceback.format_exc(), options.verbose)
-        return 1
-
-    # make sure we keep strict settings when creating new files
-    os.umask(0o077)
-
-    version = config.get_version()
-    if version == 2:
-        verbose("Looks like v2, only checking changes", options.verbose)
-        try:
-            config.v2_changes(options.outfile, options.backup)
-        except Exception as e:
-            print("ERROR: %s" % e)
-            verbose(traceback.format_exc(), options.verbose)
-            return 1
-    elif version == 1:
-        verbose("Looks like v1, performing full upgrade", options.verbose)
-        try:
-            config.upgrade_v2(options.outfile, options.backup)
-        except Exception as e:
-            print("ERROR: %s" % e)
-            verbose(traceback.format_exc(), options.verbose)
-            return 1
-    else:
-        print("Can only upgrade from v1 to v2, file %s looks like version %d" % (options.filename, config.get_version()), file=sys.stderr)
-        return 1
-
-    return 0
-
-if __name__ == "__main__":
-    ret = main()
-    sys.exit(ret)
-
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: https://getfedora.org/code-of-conduct.html
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/sssd-devel@lists.fedorahosted.org/message/TRAJGBYDH7D5J6FHZ5A4P7ADKJXKQUPK/

Reply via email to