示例#1
0
    def db2ldif(self, instance, backend, online=True):
        '''
        Create a LDIF backup of the data in this instance.

        If executed online create a task and wait for it to complete.

        For SELinux reasons this writes out to the 389-ds backup location
        and we move it.
        '''
        logger.info('Backing up %s in %s to LDIF', backend, instance)

        cn = time.strftime('export_%Y_%m_%d_%H_%M_%S')
        dn = DN(('cn', cn), ('cn', 'export'), ('cn', 'tasks'),
                ('cn', 'config'))

        ldifname = '%s-%s.ldif' % (instance, backend)
        ldiffile = os.path.join(
            paths.SLAPD_INSTANCE_LDIF_DIR_TEMPLATE % instance, ldifname)

        if online:
            conn = self.get_connection()
            ent = conn.make_entry(
                dn, {
                    'objectClass': ['top', 'extensibleObject'],
                    'cn': [cn],
                    'nsInstance': [backend],
                    'nsFilename': [ldiffile],
                    'nsUseOneFile': ['true'],
                    'nsExportReplica': ['true'],
                })

            try:
                conn.add_entry(ent)
            except Exception as e:
                raise admintool.ScriptError('Unable to add LDIF task: %s' % e)

            logger.info("Waiting for LDIF to finish")
            wait_for_task(conn, dn)
        else:
            args = [
                paths.DB2LDIF, '-Z', instance, '-r', '-n', backend, '-a',
                ldiffile
            ]
            result = run(args, raiseonerr=False)
            if result.returncode != 0:
                logger.critical('db2ldif failed: %s', result.error_log)

        # Move the LDIF backup to our location
        shutil.move(ldiffile, os.path.join(self.dir, ldifname))
示例#2
0
    def validate_options(self):
        super(OTPTokenImport, self).validate_options()

        # Parse the file.
        if len(self.args) < 1:
            raise admintool.ScriptError("Import file required!")
        self.doc = PSKCDocument(self.args[0])

        # Get the output file.
        if len(self.args) < 2:
            raise admintool.ScriptError("Output file required!")
        self.output = self.args[1]
        if os.path.exists(self.output):
            raise admintool.ScriptError("Output file already exists!")

        # Verify a key is provided if one is needed.
        if self.doc.keyname is not None:
            if self.safe_options.keyfile is None:  # pylint: disable=no-member
                raise admintool.ScriptError("Encryption key required: %s!" % self.doc.keyname)

            # Load the keyfile.
            keyfile = self.safe_options.keyfile  # pylint: disable=no-member
            with open(keyfile) as f:
                self.doc.setKey(f.read())
示例#3
0
    def validate_options(self):
        options = self.options
        super(LDAPUpdater, self).validate_options(needs_root=True)

        self.files = self.args

        for filename in self.files:
            if not os.path.exists(filename):
                raise admintool.ScriptError("%s: file not found" % filename)

        try:
            installutils.check_server_configuration()
        except RuntimeError, e:
            print unicode(e)
            sys.exit(1)
示例#4
0
    def ask_for_options(self):
        options = self.options
        super(Restore, self).ask_for_options()

        # get the directory manager password
        self.dirman_password = options.password
        if not options.password:
            if not options.unattended:
                self.dirman_password = installutils.read_password(
                    "Directory Manager (existing master)",
                    confirm=False,
                    validate=False)
            if self.dirman_password is None:
                raise admintool.ScriptError(
                    "Directory Manager password required")
示例#5
0
    def run(self):
        super(LDAPUpdater_Upgrade, self).run()
        api.Backend.ldap2.connect()
        options = self.options

        realm = api.env.realm
        upgrade = IPAUpgrade(realm,
                             self.files,
                             schema_files=options.schema_files)

        try:
            upgrade.create_instance()
        except BadSyntax:
            raise admintool.ScriptError(
                'Bad syntax detected in upgrade file(s).', 1)
        except RuntimeError:
            raise admintool.ScriptError('IPA upgrade failed.', 1)
        else:
            if upgrade.modified:
                logger.info('Update complete')
            else:
                logger.info('Update complete, no data were modified')

        api.Backend.ldap2.disconnect()
示例#6
0
    def resubmit_request(self, ca='dogtag-ipa-ca-renew-agent', profile=''):
        timeout = api.env.startup_timeout + 60

        logger.debug("resubmitting certmonger request '%s'", self.request_id)
        certmonger.resubmit_request(self.request_id,
                                    ca=ca,
                                    profile=profile,
                                    is_ca=True)
        try:
            state = certmonger.wait_for_request(self.request_id, timeout)
        except RuntimeError:
            raise admintool.ScriptError(
                "Resubmitting certmonger request '%s' timed out, "
                "please check the request manually" % self.request_id)
        ca_error = certmonger.get_request_value(self.request_id, 'ca-error')
        if state != 'MONITORING' or ca_error:
            raise admintool.ScriptError(
                "Error resubmitting certmonger request '%s', "
                "please check the request manually" % self.request_id)

        logger.debug("modifying certmonger request '%s'", self.request_id)
        certmonger.modify(self.request_id,
                          ca='dogtag-ipa-ca-renew-agent',
                          profile='')
示例#7
0
def decrypt_file(tmpdir, filename):
    source = filename
    (dest, ext) = os.path.splitext(filename)

    if ext != '.gpg':
        raise admintool.ScriptError('Trying to decrypt a non-gpg file')

    dest = os.path.basename(dest)
    dest = os.path.join(tmpdir, dest)

    args = [
        paths.GPG2,
        '--batch',
        '--output',
        dest,
        '--decrypt',
        source,
    ]

    result = run(args, raiseonerr=False)
    if result.returncode != 0:
        raise admintool.ScriptError('gpg failed: %s' % result.error_log)

    return dest
示例#8
0
    def run(self):
        fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
        if (not fstore.has_files() and
            not os.path.exists(paths.IPA_DEFAULT_CONF)):
            raise admintool.ScriptError(
                "IPA client is not configured on this system.")

        api.bootstrap(context='cli_installer')
        api.finalize()

        server = urlparse.urlsplit(api.env.jsonrpc_uri).hostname
        ldap = ipaldap.IPAdmin(server)

        tmpdir = tempfile.mkdtemp(prefix="tmp-")
        ccache_name = os.path.join(tmpdir, 'ccache')
        try:
            principal = str('host/%s@%s' % (api.env.host, api.env.realm))
            ipautil.kinit_keytab(principal, paths.KRB5_KEYTAB, ccache_name)
            os.environ['KRB5CCNAME'] = ccache_name

            api.Backend.rpcclient.connect()
            try:
                result = api.Backend.rpcclient.forward(
                    'ca_is_enabled',
                    version=u'2.107',
                )
                ca_enabled = result['result']
            except (errors.CommandError, errors.NetworkError):
                result = api.Backend.rpcclient.forward(
                    'env',
                    server=True,
                    version=u'2.0',
                )
                ca_enabled = result['result']['enable_ra']
            api.Backend.rpcclient.disconnect()

            ldap.do_sasl_gssapi_bind()

            certs = certstore.get_ca_certs(ldap, api.env.basedn,
                                           api.env.realm, ca_enabled)
        finally:
            shutil.rmtree(tmpdir)

        server_fstore = sysrestore.FileStore(paths.SYSRESTORE)
        if server_fstore.has_files():
            self.update_server(certs)

        self.update_client(certs)
示例#9
0
    def ldap_connect(self):
        password = self.options.password
        if not password:
            try:
                api.Backend.ldap2.connect(ccache=os.environ.get('KRB5CCNAME'))
            except (gssapi.exceptions.GSSError, errors.ACIError):
                pass
            else:
                return

            password = installutils.read_password(
                "Directory Manager", confirm=False, validate=False)
            if password is None:
                raise admintool.ScriptError(
                    "Directory Manager password required")

        api.Backend.ldap2.connect(bind_pw=password)
示例#10
0
    def get_connection(self):
        '''
        Create an ldapi connection and bind to it using autobind as root.
        '''
        if self._conn is not None:
            return self._conn

        self._conn = ipaldap.IPAdmin(host=api.env.host,
                                     ldapi=True,
                                     protocol='ldapi',
                                     realm=api.env.realm)

        try:
            pw_name = pwd.getpwuid(os.geteuid()).pw_name
            self._conn.do_external_bind(pw_name)
        except Exception, e:
            raise admintool.ScriptError('Unable to bind to LDAP server: %s' %
                                        e)
示例#11
0
    def ask_for_options(self):
        options = self.options
        super(Restore, self).ask_for_options()

        # no IPA config means we are reinstalling from nothing so
        # there is no need for the DM password
        if not os.path.exists(paths.IPA_DEFAULT_CONF):
            return
        # get the directory manager password
        self.dirman_password = options.password
        if not options.password:
            if not options.unattended:
                self.dirman_password = installutils.read_password(
                    "Directory Manager (existing master)",
                    confirm=False, validate=False)
            if self.dirman_password is None:
                raise admintool.ScriptError(
                    "Directory Manager password required")
示例#12
0
    def finalize_backup(self, data_only=False, encrypt=False, keyring=None):
        '''
        Create the final location of the backup files and move the files
        we've backed up there, optionally encrypting them.

        This is done in a couple of steps. We have a directory that
        contains the tarball of the files, a directory that contains
        the db2bak output and an LDIF.

        These, along with the header, are moved into a new subdirectory
        in /var/lib/ipa/backup.
        '''

        if data_only:
            backup_dir = os.path.join(paths.IPA_BACKUP_DIR, time.strftime('ipa-data-%Y-%m-%d-%H-%M-%S'))
            filename = os.path.join(backup_dir, "ipa-data.tar")
        else:
            backup_dir = os.path.join(paths.IPA_BACKUP_DIR, time.strftime('ipa-full-%Y-%m-%d-%H-%M-%S'))
            filename = os.path.join(backup_dir, "ipa-full.tar")

        os.mkdir(backup_dir)
        os.chmod(backup_dir, 0o700)

        os.chdir(self.dir)
        args = ['tar',
                '--xattrs',
                '--selinux',
                '-czf',
                filename,
                '.'
               ]
        result = run(args, raiseonerr=False)
        if result.returncode != 0:
            raise admintool.ScriptError(
                'tar returned non-zero code %s: %s' %
                (result.returncode, result.error_log))

        if encrypt:
            logger.info('Encrypting %s', filename)
            filename = encrypt_file(filename)

        shutil.move(self.header, backup_dir)

        logger.info('Backed up to %s', backup_dir)
示例#13
0
    def bak2db(self, instance, backend, online=True):
        '''
        Restore a BAK backup of the data and changelog in this instance.

        If backend is None then all backends are restored.

        If executed online create a task and wait for it to complete.

        instance here is a loaded term. It can mean either a separate
        389-ds install instance or a separate 389-ds backend. We only need
        to treat PKI-IPA and ipaca specially.
        '''
        if backend is not None:
            self.log.info('Restoring %s in %s' % (backend, instance))
        else:
            self.log.info('Restoring %s' % instance)

        cn = time.strftime('restore_%Y_%m_%d_%H_%M_%S')

        dn = DN(('cn', cn), ('cn', 'restore'), ('cn', 'tasks'),
                ('cn', 'config'))

        if online:
            conn = self.get_connection()
            ent = conn.make_entry(
                dn, {
                    'objectClass': ['top', 'extensibleObject'],
                    'cn': [cn],
                    'nsArchiveDir': [os.path.join(self.dir, instance)],
                    'nsDatabaseType': ['ldbm database'],
                })
            if backend is not None:
                ent['nsInstance'] = [backend]

            try:
                conn.add_entry(ent)
            except Exception, e:
                raise admintool.ScriptError(
                    'Unable to bind to LDAP server: %s' % e)

            self.log.info("Waiting for restore to finish")
            wait_for_task(conn, dn)
示例#14
0
    def _run(self):
        super(KRAInstaller, self).run()
        print dedent(self.INSTALLER_START_MESSAGE)

        subject = dsinstance.DsInstance().find_subject_base()
        if not self.installing_replica:
            kra = krainstance.KRAInstance(
                api.env.realm, dogtag_constants=dogtag.install_constants)

            kra.configure_instance(api.env.host,
                                   api.env.domain,
                                   self.options.password,
                                   self.options.password,
                                   subject_base=subject)
        else:
            replica_config = create_replica_config(self.options.password,
                                                   self.replica_file,
                                                   self.options)

            if not read_replica_info_kra_enabled(replica_config.dir):
                raise admintool.ScriptError(
                    "Either KRA is not installed on the master system or "
                    "your replica file is out of date")

            kra = krainstance.install_replica_kra(replica_config)
            service.print_msg("Restarting the directory server")

            ds = dsinstance.DsInstance()
            ds.restart()

        kra.enable_client_auth_to_db(kra.dogtag_constants.KRA_CS_CFG_PATH)

        # Restart apache for new proxy config file
        services.knownservices.httpd.restart(capture_output=True)

        # Update config file
        parser = RawConfigParser()
        parser.read(paths.IPA_DEFAULT_CONF)
        parser.set('global', 'enable_kra', 'True')

        with open(paths.IPA_DEFAULT_CONF, 'w') as f:
            parser.write(f)
示例#15
0
def encrypt_file(filename, remove_original=True):
    source = filename
    dest = filename + '.gpg'

    args = [
        paths.GPG2,
        '--batch',
        '--default-recipient-self',
        '--output', dest,
        '--encrypt', source,
    ]

    result = run(args, raiseonerr=False)
    if result.returncode != 0:
        raise admintool.ScriptError('gpg failed: %s' % result.error_log)

    if remove_original:
        os.unlink(source)

    return dest
示例#16
0
    def extract_backup(self, keyring=None):
        '''
        Extract the contents of the tarball backup into a temporary location,
        decrypting if necessary.
        '''

        encrypt = False
        filename = None
        if self.backup_type == 'FULL':
            filename = os.path.join(self.backup_dir, 'ipa-full.tar')
        else:
            filename = os.path.join(self.backup_dir, 'ipa-data.tar')
        if not os.path.exists(filename):
            if not os.path.exists(filename + '.gpg'):
                raise admintool.ScriptError('Unable to find backup file in %s' % self.backup_dir)
            else:
                filename = filename + '.gpg'
                encrypt = True

        if encrypt:
            logger.info('Decrypting %s', filename)
            filename = decrypt_file(self.dir, filename, keyring)

        os.chdir(self.dir)

        args = ['tar',
                '--xattrs',
                '--selinux',
                '-xzf',
                filename,
                '.'
               ]
        run(args)

        pent = pwd.getpwnam(constants.DS_USER)
        os.chown(self.top_dir, pent.pw_uid, pent.pw_gid)
        recursive_chown(self.dir, pent.pw_uid, pent.pw_gid)

        if encrypt:
            # We can remove the decoded tarball
            os.unlink(filename)
示例#17
0
    def run(self):
        super(EPN, self).run()

        if not is_ipa_client_configured():
            logger.error("IPA client is not configured on this system.")
            raise admintool.ScriptError()

        # tasks required privileges
        self._get_krb5_ticket()
        self._read_configuration()
        self._validate_configuration()
        self._parse_configuration()
        self._get_connection()
        self._read_ipa_configuration()
        self._create_ssl_context()

        drop_privileges()
        if self.options.mailtest:
            self._gentestdata()
        else:
            if self.options.to_nbdays:
                self._build_cli_date_ranges()
            for date_range in self._date_ranges:
                self._fetch_data_from_ldap(date_range)
                self._parse_ldap_data()
        if self.options.dry_run:
            self._pretty_print_data()
        else:
            self._mailer = MailUserAgent(
                security_protocol=api.env.smtp_security,
                smtp_hostname=api.env.smtp_server,
                smtp_port=api.env.smtp_port,
                smtp_timeout=api.env.smtp_timeout,
                smtp_username=api.env.smtp_user,
                smtp_password=api.env.smtp_password,
                ssl_context=self._ssl_context,
                x_mailer=self.command_name,
                msg_subtype=api.env.msg_subtype,
                msg_charset=api.env.msg_charset,
            )
            self._send_emails()
示例#18
0
    def import_cert(self, dirname, pkcs12_passwd, old_cert, principal, command):
        pkcs12_file, pin, ca_cert = installutils.load_pkcs12(
            cert_files=self.args,
            key_password=pkcs12_passwd,
            key_nickname=self.options.cert_name,
            ca_cert_files=[paths.IPA_CA_CRT],
            host_name=api.env.host)

        dirname = os.path.normpath(dirname)
        cdb = certs.CertDB(api.env.realm, nssdir=dirname)

        # Check that the ca_cert is known and trusted
        self.check_chain(pkcs12_file.name, pin, cdb)

        try:
            ca_enabled = api.Command.ca_is_enabled()['result']
            if ca_enabled:
                cdb.untrack_server_cert(old_cert)

            cdb.delete_cert(old_cert)
            prevs = cdb.find_server_certs()
            cdb.import_pkcs12(pkcs12_file.name, pin)
            news = cdb.find_server_certs()
            server_certs = [item for item in news if item not in prevs]
            server_cert = server_certs[0][0]

            if ca_enabled:
                # Start tracking only if the cert was issued by IPA CA
                # Retrieve IPA CA
                ipa_ca_cert = cdb.get_cert_from_db(
                    get_ca_nickname(api.env.realm))
                # And compare with the CA which signed this certificate
                if ca_cert == ipa_ca_cert:
                    cdb.track_server_cert(server_cert,
                                          principal,
                                          cdb.passwd_fname,
                                          command)
        except RuntimeError as e:
            raise admintool.ScriptError(str(e))

        return server_cert
示例#19
0
    def file_backup(self, options):
        def verify_directories(dirs):
            return [s for s in dirs if os.path.exists(s)]

        self.log.info("Backing up files")
        args = [
            'tar', '--exclude=/var/lib/ipa/backup', '--xattrs', '--selinux',
            '-czf',
            os.path.join(self.dir, 'files.tar')
        ]

        args.extend(verify_directories(self.dirs))
        args.extend(verify_directories(self.files))

        if options.logs:
            args.extend(verify_directories(self.logs))

        (stdout, stderr, rc) = run(args, raiseonerr=False)
        if rc != 0:
            raise admintool.ScriptError('tar returned non-zero %d: %s' %
                                        (rc, stdout))
示例#20
0
    def init_api(self, **overrides):
        overrides.setdefault('confdir', paths.ETC_IPA)
        api.bootstrap(in_server=True, context='restore', **overrides)
        api.finalize()

        self.instances = [ipaldap.realm_to_serverid(api.env.realm)]
        self.backends = ['userRoot', 'ipaca']

        # no IPA config means we are reinstalling from nothing so
        # there is nothing to test the DM password against.
        if os.path.exists(paths.IPA_DEFAULT_CONF):
            instance_name = ipapython.ipaldap.realm_to_serverid(api.env.realm)
            if not services.knownservices.dirsrv.is_running(instance_name):
                raise admintool.ScriptError(
                    "directory server instance is not running")
            try:
                ReplicationManager(api.env.realm, api.env.host,
                                   self.dirman_password)
            except errors.ACIError:
                logger.error("Incorrect Directory Manager password provided")
                raise
示例#21
0
    def export_certdb(self, fname, passwd_fname):
        """Export a cert database

        :param fname: The file to export to (relative to the info directory)
        :param passwd_fname: File that holds the cert DB password
        """
        hostname = self.replica_fqdn
        subject_base = self.subject_base
        ca_subject = ca.lookup_ca_subject(api, subject_base)
        nickname = "Server-Cert"

        try:
            db = certs.CertDB(api.env.realm,
                              nssdir=self.dir,
                              host_name=api.env.host,
                              subject_base=subject_base,
                              ca_subject=ca_subject)
            db.create_passwd_file()
            db.create_from_cacert()
            db.create_server_cert(nickname, hostname)

            pkcs12_fname = os.path.join(self.dir, fname + ".p12")

            try:
                db.export_pkcs12(pkcs12_fname, passwd_fname, nickname)
            except ipautil.CalledProcessError as e:
                logger.info("error exporting Server certificate: %s", e)
                installutils.remove_file(pkcs12_fname)
                installutils.remove_file(passwd_fname)

            self.remove_info_file("cert8.db")
            self.remove_info_file("key3.db")
            self.remove_info_file("secmod.db")
            self.remove_info_file("noise.txt")

            orig_filename = passwd_fname + ".orig"
            if ipautil.file_exists(orig_filename):
                installutils.remove_file(orig_filename)
        except errors.CertificateOperationError as e:
            raise admintool.ScriptError(str(e))
示例#22
0
    def db2bak(self, instance, online=True):
        '''
        Create a BAK backup of the data and changelog in this instance.

        If executed online create a task and wait for it to complete.
        '''
        logger.info('Backing up %s', instance)
        cn = time.strftime('backup_%Y_%m_%d_%H_%M_%S')
        dn = DN(('cn', cn), ('cn', 'backup'), ('cn', 'tasks'),
                ('cn', 'config'))

        bakdir = os.path.join(paths.SLAPD_INSTANCE_BACKUP_DIR_TEMPLATE %
                              (instance, instance))

        if online:
            conn = self.get_connection()
            ent = conn.make_entry(
                dn, {
                    'objectClass': ['top', 'extensibleObject'],
                    'cn': [cn],
                    'nsInstance': ['userRoot'],
                    'nsArchiveDir': [bakdir],
                    'nsDatabaseType': ['ldbm database'],
                })

            try:
                conn.add_entry(ent)
            except Exception as e:
                raise admintool.ScriptError(
                    'Unable to to add backup task: %s' % e)

            logger.info("Waiting for BAK to finish")
            wait_for_task(conn, dn)
        else:
            args = [paths.DB2BAK, bakdir, '-Z', instance]
            result = run(args, raiseonerr=False)
            if result.returncode != 0:
                logger.critical('db2bak failed: %s', result.error_log)

        shutil.move(bakdir, self.dir)
示例#23
0
    def db2ldif(self, instance, backend, online=True):
        '''
        Create a LDIF backup of the data in this instance.

        If executed online create a task and wait for it to complete.

        For SELinux reasons this writes out to the 389-ds backup location
        and we move it.
        '''
        self.log.info('Backing up %s in %s to LDIF' % (backend, instance))

        now = time.localtime()
        cn = time.strftime('export_%Y_%m_%d_%H_%M_%S')
        dn = DN(('cn', cn), ('cn', 'export'), ('cn', 'tasks'),
                ('cn', 'config'))

        ldifname = '%s-%s.ldif' % (instance, backend)
        ldiffile = os.path.join(
            paths.SLAPD_INSTANCE_LDIF_DIR_TEMPLATE % instance, ldifname)

        if online:
            conn = self.get_connection()
            ent = conn.make_entry(
                dn, {
                    'objectClass': ['top', 'extensibleObject'],
                    'cn': [cn],
                    'nsInstance': [backend],
                    'nsFilename': [ldiffile],
                    'nsUseOneFile': ['true'],
                    'nsExportReplica': ['true'],
                })

            try:
                conn.add_entry(ent)
            except Exception, e:
                raise admintool.ScriptError('Unable to add LDIF task: %s' % e)

            self.log.info("Waiting for LDIF to finish")
            wait_for_task(conn, dn)
    def replace_key_cert_files(self,
                               cert,
                               key,
                               cert_fname,
                               key_fname,
                               ca_cert,
                               passwd_fname=None,
                               profile=None,
                               cmgr_post_command=None):
        try:
            ca_enabled = api.Command.ca_is_enabled()['result']
            if ca_enabled:
                certmonger.stop_tracking(certfile=cert_fname)

            pkey_passwd = None
            if passwd_fname is not None:
                with open(passwd_fname, 'rb') as f:
                    pkey_passwd = f.read()

            x509.write_certificate(cert, cert_fname)
            x509.write_pem_private_key(key, key_fname, pkey_passwd)

            if ca_enabled:
                # Start tracking only if the cert was issued by IPA CA
                # Retrieve IPA CA
                cdb = certs.CertDB(api.env.realm, nssdir=paths.IPA_NSSDB_DIR)
                ipa_ca_cert = cdb.get_cert_from_db(
                    get_ca_nickname(api.env.realm))
                # And compare with the CA which signed this certificate
                if ca_cert == ipa_ca_cert:
                    req_id = certmonger.start_tracking(
                        (cert_fname, key_fname),
                        pinfile=passwd_fname,
                        storage='FILE',
                        post_command=cmgr_post_command)
                    return req_id
        except RuntimeError as e:
            raise admintool.ScriptError(str(e))
        return None
示例#25
0
    def delete_winsync_agreement(self):
        """
        Deletes the winsync agreement between the current master and the
        given AD server.
        """

        try:
            self.manager.delete_agreement(self.options.server)
            self.manager.delete_referral(self.options.server)

            dn = DN(('cn', self.options.server),
                    ('cn', 'replicas'), ('cn', 'ipa'), ('cn', 'etc'),
                    realm_to_suffix(api.env.realm))
            entries = self.manager.conn.get_entries(dn,
                                                    self.ldap.SCOPE_SUBTREE)
            if entries:
                entries.sort(key=len, reverse=True)
                for entry in entries:
                    self.ldap.delete_entry(entry)

        except Exception as e:
            raise admintool.ScriptError(
                "Deletion of the winsync agreement failed: %s" % str(e))
示例#26
0
    def ldap_connect(self):
        conn = ldap2()

        password = self.options.password
        if not password:
            try:
                ccache = krbV.default_context().default_ccache()
                conn.connect(ccache=ccache)
            except (krbV.Krb5Error, errors.ACIError):
                pass
            else:
                return conn

            password = installutils.read_password("Directory Manager",
                                                  confirm=False,
                                                  validate=False)
            if password is None:
                raise admintool.ScriptError(
                    "Directory Manager password required")

        conn.connect(bind_dn=DN(('cn', 'Directory Manager')), bind_pw=password)

        return conn
示例#27
0
    def validate_options(self):
        options = self.options
        super(Backup, self).validate_options(needs_root=True)
        installutils.check_server_configuration()

        if options.gpg_keyring is not None:
            if not os.path.exists(options.gpg_keyring + '.pub'):
                raise admintool.ScriptError('No such key %s' %
                                            options.gpg_keyring)
            options.gpg = True

        if options.online and not options.data_only:
            self.option_parser.error("You cannot specify --online "
                                     "without --data")

        if options.gpg:
            tmpfd = write_tmp_file('encryptme')
            newfile = encrypt_file(tmpfd.name, options.gpg_keyring, False)
            os.unlink(newfile)

        if options.data_only and options.logs:
            self.option_parser.error("You cannot specify --data "
                                     "with --logs")
示例#28
0
    def import_cert(self, dirname, pkcs12_passwd, old_cert, principal,
                    command):
        pkcs12_file, pin, ca_cert = installutils.load_pkcs12(
            cert_files=self.args,
            key_password=pkcs12_passwd,
            key_nickname=self.options.cert_name,
            ca_cert_files=[CACERT],
            host_name=api.env.host)

        cdb = certs.CertDB(api.env.realm, nssdir=dirname)
        try:
            ca_enabled = api.Command.ca_is_enabled()['result']
            if ca_enabled:
                cdb.untrack_server_cert(old_cert)

            cdb.delete_cert(old_cert)
            cdb.import_pkcs12(pkcs12_file.name, pin)
            server_cert = cdb.find_server_certs()[0][0]

            if ca_enabled:
                cdb.track_server_cert(server_cert, principal, cdb.passwd_fname,
                                      command)
        except RuntimeError, e:
            raise admintool.ScriptError(str(e))
示例#29
0
def encrypt_file(filename, keyring, remove_original=True):
    source = filename
    dest = filename + '.gpg'

    args = [paths.GPG, '--batch', '--default-recipient-self', '-o', dest]

    if keyring is not None:
        args.append('--no-default-keyring')
        args.append('--keyring')
        args.append(keyring + '.pub')
        args.append('--secret-keyring')
        args.append(keyring + '.sec')

    args.append('-e')
    args.append(source)

    result = run(args, raiseonerr=False)
    if result.returncode != 0:
        raise admintool.ScriptError('gpg failed: %s' % result.error_log)

    if remove_original:
        os.unlink(source)

    return dest
示例#30
0
    def disable_agreements(self):
        '''
        Find all replication agreements on all masters and disable them.

        Warn very loudly about any agreements/masters we cannot contact.
        '''
        try:
            conn = self.get_connection()
        except Exception as e:
            logger.error('Unable to get connection, skipping disabling '
                         'agreements: %s', e)
            return
        masters = []
        dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
        try:
            entries = conn.get_entries(dn, conn.SCOPE_ONELEVEL)
        except Exception as e:
            raise admintool.ScriptError(
                "Failed to read master data: %s" % e)
        else:
            masters = [ent.single_value['cn'] for ent in entries]

        for master in masters:
            if master == api.env.host:
                continue

            try:
                repl = ReplicationManager(api.env.realm, master,
                                          self.dirman_password)
            except Exception as e:
                logger.critical("Unable to disable agreement on %s: %s",
                                master, e)
                continue

            master_dn = DN(('cn', master), ('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
            try:
                services = repl.conn.get_entries(master_dn,
                                                 repl.conn.SCOPE_ONELEVEL)
            except errors.NotFound:
                continue

            services_cns = [s.single_value['cn'] for s in services]

            host_entries = repl.find_ipa_replication_agreements()
            hosts = [rep.single_value.get('nsds5replicahost')
                     for rep in host_entries]

            for host in hosts:
                logger.info('Disabling replication agreement on %s to %s',
                            master, host)
                repl.disable_agreement(host)

            if 'CA' in services_cns:
                try:
                    repl = get_cs_replication_manager(api.env.realm, master,
                                                      self.dirman_password)
                except Exception as e:
                    logger.critical("Unable to disable agreement on %s: %s",
                                    master, e)
                    continue

                host_entries = repl.find_ipa_replication_agreements()
                hosts = [rep.single_value.get('nsds5replicahost')
                         for rep in host_entries]
                for host in hosts:
                    logger.info('Disabling CA replication agreement on %s to '
                                '%s', master, host)
                    repl.hostnames = [master, host]
                    repl.disable_agreement(host)