Exemplo n.º 1
0
/* Simple implementation of decryption: look for any crypto_LUKS
 * partitions and decrypt them, then rescan for VGs.  This only works
 * for Fedora whole-disk encryption.  WIP to make this work for other
 * encryption schemes.
 */
void
inspect_do_decrypt (void)
{
  CLEANUP_FREE_STRING_LIST char **partitions = guestfs_list_partitions (g);
  if (partitions == NULL)
    exit (EXIT_FAILURE);

  int need_rescan = 0;
  size_t i;
  for (i = 0; partitions[i] != NULL; ++i) {
    CLEANUP_FREE char *type = guestfs_vfs_type (g, partitions[i]);
    if (type && STREQ (type, "crypto_LUKS")) {
      char mapname[32];
      make_mapname (partitions[i], mapname, sizeof mapname);

      CLEANUP_FREE char *key = read_key (partitions[i]);
      /* XXX Should we call guestfs_luks_open_ro if readonly flag
       * is set?  This might break 'mount_ro'.
       */
      if (guestfs_luks_open (g, partitions[i], key, mapname) == -1)
        exit (EXIT_FAILURE);

      need_rescan = 1;
    }
  }

  if (need_rescan) {
    if (guestfs_vgscan (g) == -1)
      exit (EXIT_FAILURE);
    if (guestfs_vg_activate_all (g, 1) == -1)
      exit (EXIT_FAILURE);
  }
}
Exemplo n.º 2
0
static void
do_output_partitions (void)
{
  size_t i;

  CLEANUP_FREE_STRING_LIST char **parts = guestfs_list_partitions (g);
  if (parts == NULL)
    exit (EXIT_FAILURE);

  for (i = 0; parts[i] != NULL; ++i) {
    CLEANUP_FREE char *dev = NULL, *parent_name = NULL, *canonical_name = NULL;
    const char *parents[2];
    int64_t size = -1;
    int mbr_id = -1;

    dev = guestfs_canonical_device_name (g, parts[i]);
    if (!dev)
      exit (EXIT_FAILURE);

    if ((columns & COLUMN_SIZE)) {
      size = guestfs_blockdev_getsize64 (g, parts[i]);
      if (size == -1)
        exit (EXIT_FAILURE);
    }
    if ((columns & COLUMN_PARENTS)) {
      parent_name = guestfs_part_to_dev (g, parts[i]);
      if (parent_name == NULL)
        exit (EXIT_FAILURE);

      if ((columns & COLUMN_MBR))
        mbr_id = get_mbr_id (parts[i], parent_name);

      canonical_name = guestfs_canonical_device_name (g, parent_name);
      if (!canonical_name)
        exit (EXIT_FAILURE);

      parents[0] = canonical_name;
      parents[1] = NULL;
    }

    write_row (dev, "partition",
               NULL, NULL, mbr_id, size, (char **) parents, NULL);
  }
}
Exemplo n.º 3
0
/* Matches Windows registry HKLM\SYSYTEM\MountedDevices\DosDevices blob to
 * to libguestfs GPT partition device. For GPT disks, the blob is made of
 * "DMIO:ID:" prefix followed by the GPT partition GUID.
 */
static char *
map_registry_disk_blob_gpt (guestfs_h *g, const void *blob)
{
  CLEANUP_FREE_STRING_LIST char **parts = NULL;
  CLEANUP_FREE char *blob_guid = extract_guid_from_registry_blob (g, blob);
  size_t i;

  parts = guestfs_list_partitions (g);
  if (parts == NULL)
    return NULL;

  for (i = 0; parts[i] != NULL; ++i) {
    CLEANUP_FREE char *fs_guid = NULL;
    int partnum;
    CLEANUP_FREE char *device = NULL;
    CLEANUP_FREE char *type = NULL;

    partnum = guestfs_part_to_partnum (g, parts[i]);
    if (partnum == -1)
      continue;

    device = guestfs_part_to_dev (g, parts[i]);
    if (device == NULL)
      continue;

    type = guestfs_part_get_parttype (g, device);
    if (type == NULL)
      continue;

    if (STRCASENEQ (type, "gpt"))
      continue;

    /* get the GPT parition GUID from the partition block device */
    fs_guid = guestfs_part_get_gpt_guid (g, device, partnum);
    if (fs_guid == NULL)
      continue;

    /* if both GUIDs match, we have found the mapping for our device */
    if (STRCASEEQ (fs_guid, blob_guid))
      return safe_strdup (g, parts[i]);
  }

  return NULL;
}
Exemplo n.º 4
0
char *
complete_dest_paths_generator (const char *text, int state)
{
#ifdef HAVE_LIBREADLINE

  static size_t len, index;
  static struct word *words = NULL;
  static size_t nr_words = 0;
  guestfs_error_handler_cb old_error_cb;
  void *old_error_cb_data;

  /* Temporarily replace the error handler so that messages don't
   * get printed to stderr while we are issuing commands.
   */
#define SAVE_ERROR_CB							\
  old_error_cb = guestfs_get_error_handler (g, &old_error_cb_data);	\
  guestfs_set_error_handler (g, NULL, NULL);

  /* Restore error handler. */
#define RESTORE_ERROR_CB						\
  guestfs_set_error_handler (g, old_error_cb, old_error_cb_data);

  if (!state) {
    char **strs;

    len = strlen (text);
    index = 0;

    if (words) free_words (words, nr_words);

    words = NULL;
    nr_words = 0;

    SAVE_ERROR_CB

/* Silently do nothing if an allocation fails */
#define APPEND_STRS_AND_FREE						\
  do {									\
    if (strs) {								\
      size_t i;								\
      size_t n = count_strings (strs);					\
                                                                        \
      if ( n > 0 && ! xalloc_oversized (nr_words + n, sizeof (struct word))) { \
        struct word *w;							\
        w = realloc (words, sizeof (struct word) * (nr_words + n));	\
                                                                        \
        if (w == NULL) {						\
          free_words (words, nr_words);					\
          words = NULL;							\
          nr_words = 0;							\
        } else {							\
          words = w;							\
          for (i = 0; i < n; ++i) {					\
            words[nr_words].name = strs[i];				\
            words[nr_words].is_dir = 0;					\
            nr_words++;							\
          }								\
        }								\
      }									\
      free (strs);							\
    }									\
  } while (0)

    /* Is it a device? */
    if (len < 5 || STREQLEN (text, "/dev/", 5)) {
      /* Get a list of everything that can possibly begin with /dev/ */
      strs = guestfs_list_devices (g);
      APPEND_STRS_AND_FREE;

      strs = guestfs_list_partitions (g);
      APPEND_STRS_AND_FREE;

      strs = guestfs_lvs (g);
      APPEND_STRS_AND_FREE;

      strs = guestfs_list_dm_devices (g);
      APPEND_STRS_AND_FREE;

      strs = guestfs_list_md_devices (g);
      APPEND_STRS_AND_FREE;
    }

    if (len < 1 || text[0] == '/') {
      /* If we've got a partial path already, we need to list everything
       * in that directory, otherwise list everything in /
       */
      char *p, *dir;
      struct guestfs_dirent_list *dirents;

      p = strrchr (text, '/');
      dir = p && p > text ? strndup (text, p - text) : strdup ("/");
      if (dir) {
        dirents = guestfs_readdir (g, dir);

        /* Prepend directory to names before adding them to the list
         * of words.
         */
        if (dirents) {
          size_t i;

          for (i = 0; i < dirents->len; ++i) {
            int err;

            if (STRNEQ (dirents->val[i].name, ".") &&
                STRNEQ (dirents->val[i].name, "..")) {
              if (STREQ (dir, "/"))
                err = asprintf (&p, "/%s", dirents->val[i].name);
              else
                err = asprintf (&p, "%s/%s", dir, dirents->val[i].name);
              if (err >= 0) {
                if (!xalloc_oversized (nr_words+1, sizeof (struct word))) {
                  struct word *w;

                  w = realloc (words, sizeof (struct word) * (nr_words+1));
                  if (w == NULL) {
                    free_words (words, nr_words);
                    words = NULL;
                    nr_words = 0;
                  }
                  else {
                    words = w;
                    words[nr_words].name = p;
                    words[nr_words].is_dir = dirents->val[i].ftyp == 'd';
                    nr_words++;
                  }
                }
              }
            }
          }

          guestfs_free_dirent_list (dirents);
        }
      }
    }

    /* else ...  In theory we could complete other things here such as VG
     * names.  At the moment we don't do that.
     */

    RESTORE_ERROR_CB
  }
Exemplo n.º 5
0
char *
complete_dest_paths_generator (const char *text, int state)
{
#ifdef HAVE_LIBREADLINE

  static size_t len, index;
  static struct word *words = NULL;
  static size_t nr_words = 0;

  if (!state) {
    char **strs;

    len = strlen (text);
    index = 0;

    if (words) free_words (words, nr_words);

    words = NULL;
    nr_words = 0;

    guestfs_push_error_handler (g, NULL, NULL);

/* Silently do nothing if an allocation fails */
#define APPEND_STRS_AND_FREE						\
  do {									\
    if (strs) {								\
      size_t i;								\
      size_t n = count_strings (strs);					\
                                                                        \
      if ( n > 0 && ! xalloc_oversized (nr_words + n, sizeof (struct word))) { \
        struct word *w;							\
        w = realloc (words, sizeof (struct word) * (nr_words + n));	\
                                                                        \
        if (w == NULL) {						\
          free_words (words, nr_words);					\
          words = NULL;							\
          nr_words = 0;							\
        } else {							\
          words = w;							\
          for (i = 0; i < n; ++i) {					\
            words[nr_words].name = strs[i];				\
            words[nr_words].is_dir = 0;					\
            nr_words++;							\
          }								\
        }								\
      }									\
      free (strs);							\
    }									\
  } while (0)

    /* Is it a device? */
    if (len < 5 || STREQLEN (text, "/dev/", 5)) {
      /* Get a list of everything that can possibly begin with /dev/ */
      strs = guestfs_list_devices (g);
      APPEND_STRS_AND_FREE;

      strs = guestfs_list_partitions (g);
      APPEND_STRS_AND_FREE;

      strs = guestfs_lvs (g);
      APPEND_STRS_AND_FREE;

      strs = guestfs_list_dm_devices (g);
      APPEND_STRS_AND_FREE;

      strs = guestfs_list_md_devices (g);
      APPEND_STRS_AND_FREE;
    }

    if (len < 1 || text[0] == '/') {
      /* If we've got a partial path already, we need to list everything
       * in that directory, otherwise list everything in /
       */
      char *p, *dir;
      struct guestfs_dirent_list *dirents;

      p = strrchr (text, '/');
      dir = p && p > text ? strndup (text, p - text) : strdup ("/");
      if (dir) {
        dirents = guestfs_readdir (g, dir);

        /* Prepend directory to names before adding them to the list
         * of words.
         */
        if (dirents) {
          size_t i;

          for (i = 0; i < dirents->len; ++i) {
            int err;

            if (STRNEQ (dirents->val[i].name, ".") &&
                STRNEQ (dirents->val[i].name, "..")) {
              if (STREQ (dir, "/"))
                err = asprintf (&p, "/%s", dirents->val[i].name);
              else
                err = asprintf (&p, "%s/%s", dir, dirents->val[i].name);
              if (err >= 0) {
                if (!xalloc_oversized (nr_words+1, sizeof (struct word))) {
                  struct word *w;

                  w = realloc (words, sizeof (struct word) * (nr_words+1));
                  if (w == NULL) {
                    free_words (words, nr_words);
                    words = NULL;
                    nr_words = 0;
                  }
                  else {
                    words = w;
                    words[nr_words].name = p;
                    words[nr_words].is_dir = dirents->val[i].ftyp == 'd';
                    nr_words++;
                  }
                }
              }
            }
          }

          guestfs_free_dirent_list (dirents);
        }
      }
    }

    /* else ...  In theory we could complete other things here such as VG
     * names.  At the moment we don't do that.
     */

    guestfs_pop_error_handler (g);
  }

  /* This inhibits ordinary (local filename) completion. */
  rl_attempted_completion_over = 1;

  /* Sort the words so the list is stable over multiple calls. */
  if (words)
    qsort (words, nr_words, sizeof (struct word), compare_words);

  /* Complete the string. */
  while (index < nr_words) {
    struct word *word;

    word = &words[index];
    index++;

    /* Whether we should match case insensitively here or not is
     * determined by the value of the completion-ignore-case readline
     * variable.  Default to case insensitive.  (See: RHBZ#582993).
     */
    char *cic_var = rl_variable_value ("completion-ignore-case");
    int cic = 1;
    if (cic_var && STREQ (cic_var, "off"))
      cic = 0;

    int matches =
      cic ? STRCASEEQLEN (word->name, text, len)
          : STREQLEN (word->name, text, len);

    if (matches) {
      if (word->is_dir)
        rl_completion_append_character = '/';

      return strdup (word->name);
    }
  }

#endif /* HAVE_LIBREADLINE */

  return NULL;
}