Beispiel #1
0
    def __setup_sub_dict(self):
        if self.forwarders:
            fwds = "\n"
            for forwarder in self.forwarders:
                fwds += "\t\t%s;\n" % forwarder
            fwds += "\t"
        else:
            fwds = " "

        if self.ntp:
            optional_ntp =  "\n;ntp server\n"
            optional_ntp += "_ntp._udp\t\tIN SRV 0 100 123\t%s" % self.host_in_rr
        else:
            optional_ntp = ""

        boolean_var = {}
        for var in ('persistent_search', 'serial_autoincrement'):
            boolean_var[var] = "yes" if getattr(self, var, False) else "no"

        self.sub_dict = dict(FQDN=self.fqdn,
                             IP=self.ip_address,
                             DOMAIN=self.domain,
                             HOST=self.host,
                             REALM=self.realm,
                             SERVER_ID=realm_to_serverid(self.realm),
                             FORWARDERS=fwds,
                             SUFFIX=self.suffix,
                             OPTIONAL_NTP=optional_ntp,
                             ZONEMGR=self.zonemgr,
                             ZONE_REFRESH=self.zone_refresh,
                             PERSISTENT_SEARCH=boolean_var['persistent_search'],
                             SERIAL_AUTOINCREMENT=boolean_var['serial_autoincrement'],)
    def validate_options(self):
        options = self.options
        super(ReplicaPrepare, self).validate_options(needs_root=True)
        installutils.check_server_configuration()

        if not options.ip_address:
            if options.reverse_zone:
                self.option_parser.error("You cannot specify a --reverse-zone "
                    "option without the --ip-address option")
            if options.no_reverse:
                self.option_parser.error("You cannot specify a --no-reverse "
                    "option without the --ip-address option")
        elif options.reverse_zone and options.no_reverse:
            self.option_parser.error("You cannot specify a --reverse-zone "
                "option together with --no-reverse")

        #Automatically disable pkinit w/ dogtag until that is supported
        options.setup_pkinit = False

        # If any of the PKCS#12 options are selected, all are required.
        pkcs12_req = (options.dirsrv_pkcs12, options.http_pkcs12)
        pkcs12_opt = (options.pkinit_pkcs12,)
        if any(pkcs12_req + pkcs12_opt) and not all(pkcs12_req):
            self.option_parser.error(
                "--dirsrv_pkcs12 and --http_pkcs12 are required if any "
                "PKCS#12 options are used.")

        if len(self.args) < 1:
            self.option_parser.error(
                "must provide the fully-qualified name of the replica")
        elif len(self.args) > 1:
            self.option_parser.error(
                "must provide exactly one name for the replica")
        else:
            [self.replica_fqdn] = self.args

        api.bootstrap(in_server=True)
        api.finalize()

        if api.env.host == self.replica_fqdn:
            raise admintool.ScriptError("You can't create a replica on itself")

        if not api.env.enable_ra and not options.http_pkcs12:
            raise admintool.ScriptError(
                "Cannot issue certificates: a CA is not installed. Use the "
                "--http_pkcs12, --dirsrv_pkcs12 options to provide custom "
                "certificates.")

        config_dir = dsinstance.config_dirname(
            dsinstance.realm_to_serverid(api.env.realm))
        if not ipautil.dir_exists(config_dir):
            raise admintool.ScriptError(
                "could not find directory instance: %s" % config_dir)
Beispiel #3
0
    def execute(self, **options):
        ldap = self.obj.backend
        (cdn, ipa_config) = ldap.get_ipa_config()
        subject_base = ipa_config.get('ipacertificatesubjectbase', [None])[0]
        dirname = config_dirname(realm_to_serverid(api.env.realm))
        certdb = certs.CertDB(api.env.realm, nssdir=dirname, subject_base=subject_base)

        dercert = certdb.get_cert_from_db(certdb.cacert_name, pem=False)

        updates = {}
        dn = DN(('cn', 'CACert'), ('cn', 'ipa'), ('cn','etc'), api.env.basedn)

        cacrt_entry = ['objectclass:nsContainer',
                       'objectclass:pkiCA',
                       'cn:CAcert',
                       'cACertificate;binary:%s' % dercert,
                      ]
        updates[dn] = {'dn': dn, 'default': cacrt_entry}

        return (False, True, [updates])
Beispiel #4
0
    def __init__(self, realm_name, files=[], live_run=True):
        """
        realm_name: kerberos realm name, used to determine DS instance dir
        files: list of update files to process. If none use UPDATEDIR
        live_run: boolean that defines if we are in test or live mode.
        """

        ext = ''
        rand = random.Random()
        for i in range(8):
            h = "%02x" % rand.randint(0,255)
            ext += h
        service.Service.__init__(self, "dirsrv")
        serverid = dsinstance.realm_to_serverid(realm_name)
        self.filename = '%s%s/%s' % (DSBASE, serverid, DSE)
        self.savefilename = '%s%s/%s.ipa.%s' % (DSBASE, serverid, DSE, ext)
        self.live_run = live_run
        self.files = files
        self.modified = False
        self.badsyntax = False
        self.upgradefailed = False
        self.serverid = serverid
Beispiel #5
0
    def __init__(self, realm_name, files=[], live_run=True):
        """
        realm_name: kerberos realm name, used to determine DS instance dir
        files: list of update files to process. If none use UPDATEDIR
        live_run: boolean that defines if we are in test or live mode.
        """

        ext = ''
        rand = random.Random()
        for i in range(8):
            h = "%02x" % rand.randint(0, 255)
            ext += h
        service.Service.__init__(self, "dirsrv")
        serverid = dsinstance.realm_to_serverid(realm_name)
        self.filename = '%s%s/%s' % (DSBASE, serverid, DSE)
        self.savefilename = '%s%s/%s.ipa.%s' % (DSBASE, serverid, DSE, ext)
        self.live_run = live_run
        self.files = files
        self.modified = False
        self.badsyntax = False
        self.upgradefailed = False
        self.serverid = serverid
Beispiel #6
0
    def __setup_default_attributes(self):
        """
        This method setups default attributes that are either constants, or
        based on api.env attributes, such as realm, hostname or domain name.
        """

        # Constants
        self.smb_conf = "/etc/samba/smb.conf"
        self.samba_keytab = "/etc/samba/samba.keytab"
        self.selinux_booleans = ["samba_portmapper"]
        self.cifs_hosts = []

        # Values obtained from API.env
        self.fqdn = self.fqdn or api.env.host
        self.realm = self.realm or api.env.realm
        self.domain_name = self.domain_name or api.env.domain

        self.cifs_principal = "cifs/" + self.fqdn + "@" + self.realm
        self.suffix = ipautil.realm_to_suffix(self.realm)
        self.ldapi_socket = "%%2fvar%%2frun%%2fslapd-%s.socket" % \
                            realm_to_serverid(self.realm)

        # DN definitions
        self.trust_dn = DN(api.env.container_trusts, self.suffix)

        self.smb_dn = DN(('cn', 'adtrust agents'),
                         ('cn', 'sysaccounts'),
                         ('cn', 'etc'),
                         self.suffix)

        self.smb_dom_dn = DN(('cn', self.domain_name),
                             api.env.container_cifsdomains,
                             self.suffix)

        self.cifs_agent = DN(('krbprincipalname', self.cifs_principal.lower()),
                             api.env.container_service,
                             self.suffix)
    def install_dirsrv_cert(self):
        serverid = dsinstance.realm_to_serverid(api.env.realm)
        dirname = dsinstance.config_dirname(serverid)

        conn = ldap2(shared_instance=False, base_dn='')
        conn.connect(bind_dn=DN(('cn', 'directory manager')),
                     bind_pw=self.options.dirman_password)

        entry = conn.get_entry(DN(('cn', 'RSA'), ('cn', 'encryption'),
                                  ('cn', 'config')),
                               ['nssslpersonalityssl'])
        old_cert = entry.single_value['nssslpersonalityssl']

        server_cert = self.import_cert(dirname, self.options.pin,
                                       old_cert, 'ldap/%s' % api.env.host,
                                       'restart_dirsrv %s' % serverid)

        entry['nssslpersonalityssl'] = [server_cert]
        try:
            conn.update_entry(entry)
        except errors.EmptyModlist:
            pass

        conn.disconnect()
Beispiel #8
0
    def run(self):
        options = self.options
        super(Restore, self).run()

        api.bootstrap(in_server=False, context='restore')
        api.finalize()

        self.log.info("Preparing restore from %s on %s",
            self.backup_dir, api.env.host)

        if not options.instance:
            instances = []
            for instance in [realm_to_serverid(api.env.realm), 'PKI-IPA']:
                if os.path.exists('/var/lib/dirsrv/slapd-%s' % instance):
                    instances.append(instance)
        else:
            instances = [options.instance]
        if options.data_only and not instances:
            raise admintool.ScriptError('No instances to restore to')

        create_ds_group()
        create_ds_user()
        pent = pwd.getpwnam(DS_USER)

        # Temporary directory for decrypting files before restoring
        self.top_dir = tempfile.mkdtemp("ipa")
        os.chown(self.top_dir, pent.pw_uid, pent.pw_gid)
        os.chmod(self.top_dir, 0750)
        self.dir = os.path.join(self.top_dir, "ipa")
        os.mkdir(self.dir, 0750)

        os.chown(self.dir, pent.pw_uid, pent.pw_gid)

        self.header = os.path.join(self.backup_dir, 'header')

        cwd = os.getcwd()
        try:
            dirsrv = ipaservices.knownservices.dirsrv

            self.read_header()
            # These two checks would normally be in the validate method but
            # we need to know the type of backup we're dealing with.
            if (self.backup_type != 'FULL' and not options.data_only and
                not instances):
                raise admintool.ScriptError('Cannot restore a data backup into an empty system')
            if (self.backup_type == 'FULL' and not options.data_only and
                (options.instance or options.backend)):
                raise admintool.ScriptError('Restore must be in data-only mode when restoring a specific instance or backend.')
            if self.backup_host != api.env.host:
                self.log.warning('Host name %s does not match backup name %s' %
                    (api.env.host, self.backup_host))
                if (not options.unattended and
                    not user_input("Continue to restore?", False)):
                    raise admintool.ScriptError("Aborted")
            if self.backup_ipa_version != str(version.VERSION):
                self.log.warning(
                    "Restoring data from a different release of IPA.\n"
                    "Data is version %s.\n"
                    "Server is running %s." %
                    (self.backup_ipa_version, str(version.VERSION)))
                if (not options.unattended and
                    not user_input("Continue to restore?", False)):
                    raise admintool.ScriptError("Aborted")

            # Big fat warning
            if  (not options.unattended and
                not user_input("Restoring data will overwrite existing live data. Continue to restore?", False)):
                raise admintool.ScriptError("Aborted")

            self.log.info(
                "Each master will individually need to be re-initialized or")
            self.log.info(
                "re-created from this one. The replication agreements on")
            self.log.info(
                "masters running IPA 3.1 or earlier will need to be manually")
            self.log.info(
                "re-enabled. See the man page for details.")

            self.log.info("Disabling all replication.")
            self.disable_agreements()

            self.extract_backup(options.gpg_keyring)
            if options.data_only:
                if not options.online:
                    self.log.info('Stopping Directory Server')
                    dirsrv.stop(capture_output=False)
                else:
                    self.log.info('Starting Directory Server')
                    dirsrv.start(capture_output=False)
            else:
                self.log.info('Stopping IPA services')
                (stdout, stderr, rc) = run(['ipactl', 'stop'], raiseonerr=False)
                if rc not in [0, 6]:
                    self.log.warn('Stopping IPA failed: %s' % stderr)


            # We do either a full file restore or we restore data.
            if self.backup_type == 'FULL' and not options.data_only:
                if options.online:
                    raise admintool.ScriptError('File restoration cannot be done online.')
                self.file_restore(options.no_logs)
                if 'CA' in self.backup_services:
                    self.__create_dogtag_log_dirs()

            # Always restore the data from ldif
            # If we are restoring PKI-IPA then we need to restore the
            # userRoot backend in it and the main IPA instance. If we
            # have a unified instance we need to restore both userRoot and
            # ipaca.
            for instance in instances:
                if os.path.exists('/var/lib/dirsrv/slapd-%s' % instance):
                    if options.backend is None:
                        self.ldif2db(instance, 'userRoot', online=options.online)
                        if os.path.exists('/var/lib/dirsrv/slapd-%s/db/ipaca' % instance):
                            self.ldif2db(instance, 'ipaca', online=options.online)
                    else:
                        self.ldif2db(instance, options.backend, online=options.online)
                else:
                    raise admintool.ScriptError('389-ds instance %s does not exist' % instance)

            if options.data_only:
                if not options.online:
                    self.log.info('Starting Directory Server')
                    dirsrv.start(capture_output=False)
            else:
                # explicitly enable then disable the pki tomcatd service to
                # re-register its instance. FIXME, this is really wierd.
                ipaservices.knownservices.pki_tomcatd.enable()
                ipaservices.knownservices.pki_tomcatd.disable()

                self.log.info('Starting IPA services')
                run(['ipactl', 'start'])
                self.log.info('Restarting SSSD')
                sssd = ipaservices.service('sssd')
                sssd.restart()
        finally:
            try:
                os.chdir(cwd)
            except Exception, e:
                self.log.error('Cannot change directory to %s: %s' % (cwd, e))
            shutil.rmtree(self.top_dir)