You are here

function backup_migrate_requirements in Backup and Migrate 7.3

Same name and namespace in other branches
  1. 8.2 backup_migrate.install \backup_migrate_requirements()
  2. 8.3 backup_migrate.install \backup_migrate_requirements()
  3. 5.2 backup_migrate.install \backup_migrate_requirements()
  4. 6.3 backup_migrate.install \backup_migrate_requirements()
  5. 6.2 backup_migrate.install \backup_migrate_requirements()
  6. 7.2 backup_migrate.install \backup_migrate_requirements()

Implements hook_requirements().

File

./backup_migrate.install, line 11
Install hooks for Backup and Migrate.

Code

function backup_migrate_requirements($phase) {
  $requirements = array();

  // Ensure translations don't break during installation.
  $t = get_t();
  if ($phase == 'runtime') {

    // Get a list of all destinations, make sure none of them are publicly
    // accessible.
    // @todo Expand the API to add methods to specifically check this.
    require_once dirname(__FILE__) . '/includes/destinations.inc';
    foreach (backup_migrate_get_destinations() as $dest_name => $destination) {
      if (method_exists($destination, 'get_display_location')) {
        $dest_path = $destination
          ->get_display_location();
        if (!empty($dest_path) && file_valid_uri($dest_path)) {
          $scheme = file_uri_scheme($dest_path);

          // Support public and private storage and raw server paths.
          if ($scheme === 'private' || $scheme === 'public' || substr($dest_path, 0, 1) == '/') {

            // Check if the path exists.
            $path_exists = file_prepare_directory($dest_path, FILE_CREATE_DIRECTORY);
            if ($path_exists) {
              $real_path = drupal_realpath($dest_path);

              // See if the private path is somewhere inside the main Drupal
              // directory structure.
              if (strpos($real_path, DRUPAL_ROOT) === 0) {

                // Extract the relative path from the Drupal root path, and
                // then add the base URL, theoretically creating a fully
                // qualified URL to the storage directory.
                $url = substr($real_path, strlen(DRUPAL_ROOT) + 1);
                $url = url($url, array(
                  'absolute' => TRUE,
                ));
                $result = drupal_http_request($url);

                // If the HTTP request comes back as a status 200 that means
                // there is a directory listing of some sort; directory paths
                // should return a 503 error.
                if (!empty($result->code) && $result->code == 200) {

                  // Get the human readable information for this destination.
                  $dest_spec = $destination
                    ->get_list_row();

                  // Display a warning message.
                  $requirements['bmdest_' . $dest_name] = array(
                    'severity' => REQUIREMENT_ERROR,
                    'title' => 'Backup Migrate',
                    'value' => $t('Backup destination "%dest" is publicly accessible!', array(
                      '%dest' => $dest_spec['name'],
                    )),
                    'description' => $t('The backup destination, "%dest", stores its files in the "%path" directory. This directory is publicly available from the web server and urgently needs to be secured! Please see the Drupal manual on <a href="@manual">configuring the private directory path</a> on how to fix this problem.', array(
                      '%dest' => $dest_spec['name'],
                      '%path' => $real_path,
                      '@manual' => 'https://www.drupal.org/docs/7/core/modules/file/overview',
                    )),
                  );
                }
                else {
                  $files = scandir($real_path);
                  if (!empty($files)) {
                    foreach ($files as $file) {

                      // Skip the base field pointers.
                      if ($file == '.' || $file == '..') {
                        continue;
                      }
                      $result = drupal_http_request($url . '/' . $file);

                      // If the HTTP request comes back as a status 200 that
                      // means the file is accessible.
                      if (!empty($result->code) && $result->code == 200) {

                        // Get the human readable information for this
                        // destination.
                        $dest_spec = $destination
                          ->get_list_row();

                        // Display a warning message.
                        $requirements['bmdest_' . $dest_name] = array(
                          'severity' => REQUIREMENT_ERROR,
                          'title' => 'Backup Migrate',
                          'value' => $t('Files in "%dest" are publicly accessible!', array(
                            '%dest' => $dest_spec['name'],
                          )),
                          'description' => $t('The backup destination, "%dest", stores its files in the "%path" directory. These file(s) are publicly available from the web server and urgently need to be secured! Please see the Drupal manual on <a href="@manual">configuring the private directory path</a> on how to fix this problem.', array(
                            '%dest' => $dest_spec['name'],
                            '%path' => $real_path,
                            '@manual' => 'https://www.drupal.org/docs/7/core/modules/file/overview',
                          )),
                        );
                      }

                      // Only need to check one file.
                      break;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }

    // Leave a note if there were no problems.
    // @todo No point in displaying this until the API has been expanded.
    // @code
    // if (empty($requirements)) {
    //   $requirements['bmdest_' . $dest_name] = array(
    //     'severity' => REQUIREMENT_INFO,
    //     'title' => 'Backup Migrate',
    //     'value' => $t('Backup destinations are safe'),
    //     'description' => $t('The backup destinations were all checked and none of them were exposing files to the public. This is a good thing.'),
    //   );
    // }
    // @endcode
    if (variable_get('backup_migrate_disable_cron', FALSE)) {
      $requirements['bm_disable_cron'] = array(
        'severity' => REQUIREMENT_INFO,
        'title' => 'Backup Migrate',
        'value' => $t('Cron tasks are disabled'),
        'description' => $t('The cron tasks have been disabled, so scheduled backups will not run. See the Backup & Migrate module\'s README.txt file for further details.'),
      );
    }
  }
  return $requirements;
}