Esempio n. 1
0
    def test_backup_offline(self):
        """
        Backup service offline, delete files, restore and check.
        """
        ntacls.backup_offline(self.service_root, self.tarfile_path,
                              self.samdb_conn, self.smb_conf_path)
        self._check_tarfile()

        self.smb_helper.delete_tree()
        ntacls.backup_restore(self.tarfile_path, self.service_root,
                              self.samdb_conn, self.smb_conf_path)
        self._check_tree()

        # compare ntacls after restored
        self.assertDictEqual(self.original_ntacls,
                             self.smb_helper.get_ntacls())
Esempio n. 2
0
    def test_backup_offline(self):
        """
        Backup service offline, delete files, restore and check.
        """
        ntacls.backup_offline(
            self.service_root, self.tarfile_path,
            self.samdb_conn, self.smb_conf_path)
        self._check_tarfile()

        self.smb_helper.delete_tree()
        ntacls.backup_restore(
            self.tarfile_path, self.service_root,
            self.samdb_conn, self.smb_conf_path)
        self._check_tree()

        # compare ntacls after restored
        self.assertDictEqual(
            self.original_ntacls, self.smb_helper.get_ntacls())
Esempio n. 3
0
    def run(self, sambaopts=None, targetdir=None):

        logger = logging.getLogger()
        logger.setLevel(logging.DEBUG)
        logger.addHandler(logging.StreamHandler(sys.stdout))

        # Get the absolute paths of all the directories we're going to backup
        lp = sambaopts.get_loadparm()

        paths = samba.provision.provision_paths_from_lp(lp, lp.get('realm'))
        if not (paths.samdb and os.path.exists(paths.samdb)):
            raise CommandError('No sam.db found.  This backup ' +
                               'tool is only for AD DCs')

        check_targetdir(logger, targetdir)

        samdb = SamDB(url=paths.samdb, session_info=system_session(), lp=lp)
        sid = get_sid_for_restore(samdb)

        backup_dirs = [
            paths.private_dir, paths.state_dir,
            os.path.dirname(paths.smbconf)
        ]  # etc dir
        logger.info('running backup on dirs: {}'.format(backup_dirs))

        # Recursively get all file paths in the backup directories
        all_files = []
        for backup_dir in backup_dirs:
            for (working_dir, _, filenames) in os.walk(backup_dir):
                if working_dir.startswith(paths.sysvol):
                    continue

                for filename in filenames:
                    if filename in all_files:
                        continue

                    # Assume existing backup files are from a previous backup.
                    # Delete and ignore.
                    if filename.endswith(self.backup_ext):
                        os.remove(os.path.join(working_dir, filename))
                        continue
                    all_files.append(os.path.join(working_dir, filename))

        # Backup secrets, sam.ldb and their downstream files
        self.backup_secrets(paths.private_dir, lp, logger)
        self.backup_smb_dbs(paths.private_dir, samdb, lp, logger)

        # Open the new backed up samdb, flag it as backed up, and write
        # the next SID so the restore tool can add objects.
        # WARNING: Don't change this code unless you know what you're doing.
        #          Writing to a .bak file only works because the DN being
        #          written to happens to be top level.
        samdb = SamDB(url=paths.samdb + self.backup_ext,
                      session_info=system_session(),
                      lp=lp)
        time_str = get_timestamp()
        add_backup_marker(samdb, "backupDate", time_str)
        add_backup_marker(samdb, "sidForRestore", sid)

        # Now handle all the LDB and TDB files that are not linked to
        # anything else.  Use transactions for LDBs.
        for path in all_files:
            if not os.path.exists(path + self.backup_ext):
                if path.endswith('.ldb'):
                    logger.info('Starting transaction on solo db: ' + path)
                    ldb_obj = Ldb(path, lp=lp)
                    ldb_obj.transaction_start()
                    logger.info('   running tdbbackup on the same file')
                    self.offline_tdb_copy(path)
                    ldb_obj.transaction_cancel()
                elif path.endswith('.tdb'):
                    logger.info('running tdbbackup on lone tdb file ' + path)
                    self.offline_tdb_copy(path)

        # Now make the backup tar file and add all
        # backed up files and any other files to it.
        temp_tar_dir = tempfile.mkdtemp(dir=targetdir,
                                        prefix='INCOMPLETEsambabackupfile')
        temp_tar_name = os.path.join(temp_tar_dir, "samba-backup.tar.bz2")
        tar = tarfile.open(temp_tar_name, 'w:bz2')

        logger.info('running offline ntacl backup of sysvol')
        sysvol_tar_fn = 'sysvol.tar.gz'
        sysvol_tar = os.path.join(temp_tar_dir, sysvol_tar_fn)
        backup_offline(paths.sysvol, sysvol_tar, samdb, paths.smbconf)
        tar.add(sysvol_tar, sysvol_tar_fn)
        os.remove(sysvol_tar)

        create_log_file(temp_tar_dir, lp, "offline", "localhost", True)
        backup_fn = os.path.join(temp_tar_dir, "backup.txt")
        tar.add(backup_fn, os.path.basename(backup_fn))
        os.remove(backup_fn)

        logger.info('building backup tar')
        for path in all_files:
            arc_path = self.get_arc_path(path, paths)

            if os.path.exists(path + self.backup_ext):
                logger.info('   adding backup ' + arc_path + self.backup_ext +
                            ' to tar and deleting file')
                tar.add(path + self.backup_ext, arcname=arc_path)
                os.remove(path + self.backup_ext)
            elif path.endswith('.ldb') or path.endswith('.tdb'):
                logger.info('   skipping ' + arc_path)
            else:
                logger.info('   adding misc file ' + arc_path)
                tar.add(path, arcname=arc_path)

        tar.close()
        os.rename(
            temp_tar_name,
            os.path.join(targetdir,
                         'samba-backup-{}.tar.bz2'.format(time_str)))
        os.rmdir(temp_tar_dir)
        logger.info('Backup succeeded.')