Esempio n. 1
0
/* Install ".<filename>.hmac" file for FIPS self-checks */
static int hmac_install(const char *src, const char *dst, const char *hmacpath)
{
        _cleanup_free_ char *srcpath = strdup(src);
        _cleanup_free_ char *dstpath = strdup(dst);
        _cleanup_free_ char *srchmacname = NULL;
        _cleanup_free_ char *dsthmacname = NULL;
        int ret;

        if (!(srcpath && dstpath))
                return -ENOMEM;

        size_t dlen = dir_len(src);

        if (endswith(src, ".hmac"))
                return 0;

        if (!hmacpath) {
                hmac_install(src, dst, "/lib/fipscheck");
                hmac_install(src, dst, "/lib64/fipscheck");
                hmac_install(src, dst, "/lib/hmaccalc");
                hmac_install(src, dst, "/lib64/hmaccalc");
        }

        srcpath[dlen] = '\0';
        dstpath[dir_len(dst)] = '\0';
        if (hmacpath) {
                ret = asprintf(&srchmacname, "%s/%s.hmac", hmacpath, &src[dlen + 1]);
                if (ret < 0) {
                        log_error("Out of memory!");
                        exit(EXIT_FAILURE);
                }

                ret = asprintf(&dsthmacname, "%s/%s.hmac", hmacpath, &src[dlen + 1]);
                if (ret < 0) {
                        log_error("Out of memory!");
                        exit(EXIT_FAILURE);
                }
        } else {
                ret = asprintf(&srchmacname, "%s/.%s.hmac", srcpath, &src[dlen + 1]);
                if (ret < 0) {
                        log_error("Out of memory!");
                        exit(EXIT_FAILURE);
                }

                ret = asprintf(&dsthmacname, "%s/.%s.hmac", dstpath, &src[dlen + 1]);
                if (ret < 0) {
                        log_error("Out of memory!");
                        exit(EXIT_FAILURE);
                }
        }
        log_debug("hmac cp '%s' '%s')", srchmacname, dsthmacname);
        dracut_install(srchmacname, dsthmacname, false, false, true);
        return 0;
}
Esempio n. 2
0
char *
dir_name (char const *file)
{
  size_t length = dir_len (file);
  bool append_dot = (length == FILE_SYSTEM_PREFIX_LEN (file));
  char *dir = xmalloc (length + append_dot + 1);
  memcpy (dir, file, length);
  if (append_dot)
    dir[length++] = '.';
  dir[length] = 0;
  return dir;
}
Esempio n. 3
0
File: dirname.c Progetto: 4solo/cs35
char *
dir_name (char const *file)
{
  size_t length = dir_len (file);
  bool append_dot = (length == 0
		     || (FILE_SYSTEM_DRIVE_PREFIX_CAN_BE_RELATIVE
			 && length == FILE_SYSTEM_PREFIX_LEN (file)
			 && file[2] != '\0' && ! ISSLASH (file[2])));
  char *dir = xmalloc (length + append_dot + 1);
  memcpy (dir, file, length);
  if (append_dot)
    dir[length++] = '.';
  dir[length] = '\0';
  return dir;
}
Esempio n. 4
0
/**
 * Return an absolute path corresponding to PATH, which is absolute or relative
 * to the directory containing BASE_FILE, or NULL on error
 */
static char *
absolutePathFromBaseFile(const char *base_file, const char *path)
{
    char *res;
    size_t d_len = dir_len (base_file);

    /* If path is already absolute, or if dirname(base_file) is ".",
       just return a copy of path.  */
    if (*path == '/' || d_len == 0)
        return strdup(path);

    /* Ensure that the following cast-to-int is valid.  */
    if (d_len > INT_MAX)
        return NULL;

    virAsprintf(&res, "%.*s/%s", (int) d_len, base_file, path);
    return res;
}
static int
parent_dir_changed(struct archive_string *dir, struct archive_entry *entry)
{
	const char *path;
	size_t l;

	l = dir_len(entry);
	path = tk_archive_entry_pathname(entry);
	if (tk_archive_strlen(dir) > 0) {
		if (l == 0) {
			tk_archive_string_empty(dir);
			return (1);
		}
		if (strncmp(dir->s, path, l) == 0)
			return (0); /* The parent directory is the same. */
	} else if (l == 0)
		return (0);	    /* The parent directory is the same. */
	tk_archive_strncpy(dir, path, l);
	return (1);
}
Esempio n. 6
0
static char *convert_abs_rel(const char *from, const char *target)
{
        /* we use the 4*MAXPATHLEN, which should not overrun */
        char relative_from[MAXPATHLEN * 4];
        _cleanup_free_ char *realtarget = NULL;
        _cleanup_free_ char *target_dir_p = NULL, *realpath_p = NULL;
        const char *realfrom = from;
        size_t level = 0, fromlevel = 0, targetlevel = 0;
        int l;
        size_t i, rl, dirlen;
        int ret;

        target_dir_p = strdup(target);
        if (!target_dir_p)
                return strdup(from);

        dirlen = dir_len(target_dir_p);
        target_dir_p[dirlen] = '\0';
        realpath_p = realpath(target_dir_p, NULL);

        if (realpath_p == NULL) {
                log_warning("convert_abs_rel(): target '%s' directory has no realpath.", target);
                return strdup(from);
        }

        /* dir_len() skips double /'s e.g. //lib64, so we can't skip just one
         * character - need to skip all leading /'s */
        rl = strlen(target);
        for (i = dirlen + 1; i < rl; ++i)
                if (target_dir_p[i] != '/')
                        break;
        ret = asprintf(&realtarget, "%s/%s", realpath_p, &target_dir_p[i]);
        if (ret < 0) {
                log_error("Out of memory!");
                exit(EXIT_FAILURE);
        }

        /* now calculate the relative path from <from> to <target> and
           store it in <relative_from>
         */
        relative_from[0] = 0;
        rl = 0;

        /* count the pathname elements of realtarget */
        for (targetlevel = 0, i = 0; realtarget[i]; i++)
                if (realtarget[i] == '/')
                        targetlevel++;

        /* count the pathname elements of realfrom */
        for (fromlevel = 0, i = 0; realfrom[i]; i++)
                if (realfrom[i] == '/')
                        fromlevel++;

        /* count the pathname elements, which are common for both paths */
        for (level = 0, i = 0; realtarget[i] && (realtarget[i] == realfrom[i]); i++)
                if (realtarget[i] == '/')
                        level++;

        /* add "../" to the relative_from path, until the common pathname is
           reached */
        for (i = level; i < targetlevel; i++) {
                if (i != level)
                        relative_from[rl++] = '/';
                relative_from[rl++] = '.';
                relative_from[rl++] = '.';
        }

        /* set l to the next uncommon pathname element in realfrom */
        for (l = 1, i = 1; i < level; i++)
                for (l++; realfrom[l] && realfrom[l] != '/'; l++) ;
        /* skip next '/' */
        l++;

        /* append the uncommon rest of realfrom to the relative_from path */
        for (i = level; i <= fromlevel; i++) {
                if (rl)
                        relative_from[rl++] = '/';
                while (realfrom[l] && realfrom[l] != '/')
                        relative_from[rl++] = realfrom[l++];
                l++;
        }

        relative_from[rl] = 0;
        return strdup(relative_from);
}
Esempio n. 7
0
static int dracut_install(const char *src, const char *dst, bool isdir, bool resolvedeps, bool hashdst)
{
        struct stat sb, db;
        _cleanup_free_ char *fulldstpath = NULL;
        _cleanup_free_ char *fulldstdir = NULL;
        int ret;
        bool src_exists = true;
        char *i = NULL;
        char *existing;

        log_debug("dracut_install('%s', '%s')", src, dst);

        existing = hashmap_get(items_failed, src);
        if (existing) {
                if (strcmp(existing, src) == 0) {
                        log_debug("hash hit items_failed for '%s'", src);
                        return 1;
                }
        }

        if (hashdst) {
                existing = hashmap_get(items, dst);
                if (existing) {
                        if (strcmp(existing, dst) == 0) {
                                log_debug("hash hit items for '%s'", dst);
                                return 0;
                        }
                }
        }

        if (lstat(src, &sb) < 0) {
                src_exists = false;
                if (!isdir) {
                        i = strdup(src);
                        hashmap_put(items_failed, i, i);
                        /* src does not exist */
                        return 1;
                }
        }

        i = strdup(dst);
        if (!i)
                return -ENOMEM;

        hashmap_put(items, i, i);

        ret = asprintf(&fulldstpath, "%s%s", destrootdir, dst);
        if (ret < 0) {
                log_error("Out of memory!");
                exit(EXIT_FAILURE);
        }

        ret = stat(fulldstpath, &sb);

        if (ret != 0 && (errno != ENOENT)) {
                log_error("ERROR: stat '%s': %m", fulldstpath);
                return 1;
        }

        if (ret == 0) {
                if (resolvedeps && S_ISREG(sb.st_mode) && (sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
                        log_debug("'%s' already exists, but checking for any deps", fulldstpath);
                        ret = resolve_deps(src);
                } else
                        log_debug("'%s' already exists", fulldstpath);

                /* dst does already exist */
                return ret;
        }

        /* check destination directory */
        fulldstdir = strdup(fulldstpath);
        fulldstdir[dir_len(fulldstdir)] = '\0';

        ret = stat(fulldstdir, &db);

        if (ret < 0) {
                _cleanup_free_ char *dname = NULL;

                if (errno != ENOENT) {
                        log_error("ERROR: stat '%s': %m", fulldstdir);
                        return 1;
                }
                /* create destination directory */
                log_debug("dest dir '%s' does not exist", fulldstdir);
                dname = strdup(dst);
                if (!dname)
                        return 1;

                dname[dir_len(dname)] = '\0';
                ret = dracut_install(dname, dname, true, false, true);

                if (ret != 0) {
                        log_error("ERROR: failed to create directory '%s'", fulldstdir);
                        return 1;
                }
        }

        if (isdir && !src_exists) {
                log_info("mkdir '%s'", fulldstpath);
                ret = mkdir(fulldstpath, 0755);
                return ret;
        }

        /* ready to install src */

        if (S_ISDIR(sb.st_mode)) {
                log_info("mkdir '%s'", fulldstpath);
                ret = mkdir(fulldstpath, sb.st_mode | S_IWUSR);
                return ret;
        }

        if (S_ISLNK(sb.st_mode)) {
                _cleanup_free_ char *abspath = NULL;

                abspath = realpath(src, NULL);

                if (abspath == NULL)
                        return 1;

                if (dracut_install(abspath, abspath, false, resolvedeps, hashdst)) {
                        log_debug("'%s' install error", abspath);
                        return 1;
                }

                if (lstat(abspath, &sb) != 0) {
                        log_debug("lstat '%s': %m", abspath);
                        return 1;
                }

                if (lstat(fulldstpath, &sb) != 0) {
                        _cleanup_free_ char *absdestpath = NULL;

                        ret = asprintf(&absdestpath, "%s%s", destrootdir, abspath);
                        if (ret < 0) {
                                log_error("Out of memory!");
                                exit(EXIT_FAILURE);
                        }

                        ln_r(absdestpath, fulldstpath);
                }

                if (arg_hmac) {
                        /* copy .hmac files also */
                        hmac_install(src, dst, NULL);
                }

                return 0;
        }

        if (sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
                if (resolvedeps)
                        ret += resolve_deps(src);
                if (arg_hmac) {
                        /* copy .hmac files also */
                        hmac_install(src, dst, NULL);
                }
        }

        log_debug("dracut_install ret = %d", ret);
        log_info("cp '%s' '%s'", src, fulldstpath);

        if (arg_hostonly)
                mark_hostonly(dst);

        ret += cp(src, fulldstpath);
        if (ret == 0 && logfile_f)
                dracut_log_cp(src);

        log_debug("dracut_install ret = %d", ret);

        return ret;
}
Esempio n. 8
0
int
main (void)
{
  struct test *t;
  bool ok = true;

  for (t = tests; t->name; t++)
    {
      char *dir = dir_name (t->name);
      int dirlen = dir_len (t->name);
      char *last = last_component (t->name);
      char *base = base_name (t->name);
      int baselen = base_len (base);
      char *stripped = strdup (t->name);
      bool modified = strip_trailing_slashes (stripped);
      bool absolute = IS_ABSOLUTE_FILE_NAME (t->name);
      if (! (strcmp (dir, t->dir) == 0
             && (dirlen == strlen (dir)
                 || (dirlen + 1 == strlen (dir) && dir[dirlen] == '.'))))
        {
          ok = false;
          printf ("dir_name '%s': got '%s' len %d,"
                  " expected '%s' len %ld\n",
                  t->name, dir, dirlen,
                  t->dir, (unsigned long) strlen (t->dir));
        }
      if (strcmp (last, t->last))
        {
          ok = false;
          printf ("last_component '%s': got '%s', expected '%s'\n",
                  t->name, last, t->last);
        }
      if (! (strcmp (base, t->base) == 0
             && (baselen == strlen (base)
                 || (baselen + 1 == strlen (base)
                     && ISSLASH (base[baselen])))))
        {
          ok = false;
          printf ("base_name '%s': got '%s' len %d,"
                  " expected '%s' len %ld\n",
                  t->name, base, baselen,
                  t->base, (unsigned long) strlen (t->base));
        }
      if (strcmp (stripped, t->stripped) || modified != t->modified)
        {
          ok = false;
          printf ("strip_trailing_slashes '%s': got %s %s, expected %s %s\n",
                  t->name, stripped, modified ? "changed" : "unchanged",
                  t->stripped, t->modified ? "changed" : "unchanged");
        }
      if (t->absolute != absolute)
        {
          ok = false;
          printf ("'%s': got %s, expected %s\n", t->name,
                  absolute ? "absolute" : "relative",
                  t->absolute ? "absolute" : "relative");
        }
      free (dir);
      free (base);
      free (stripped);
    }
  return ok ? 0 : 1;
}