Beispiel #1
0
static char *
specific_dirname (const char *dir)
{
  char dirbuf[1024];

  if (0 == strcmp (".", dir))
    {
      /* OK, what's '.'? */
      if (NULL != getcwd (dirbuf, sizeof (dirbuf)))
	{
	  return strdup (dirbuf);
	}
      else
	{
	  return strdup (dir);
	}
    }
  else
    {
      char *result = canonicalize_filename_mode (dir, CAN_EXISTING);
      if (NULL == result)
	return strdup (dir);
      else
	return result;
    }
}
Beispiel #2
0
/*
  This function takes a path and a mode, it calls computecon to get the
  label of the path object if the current process created it, then it calls
  matchpathcon to get the default type for the object.  It substitutes the
  default type into label.  It tells the SELinux Kernel to label all new file
  system objects created by the current process with this label.

  Returns -1 on failure.  errno will be set appropriately.
*/
int
defaultcon (char const *path, mode_t mode)
{
  int rc = -1;
  char *scon = NULL;
  char *tcon = NULL;
  context_t scontext = 0, tcontext = 0;
  const char *contype;
  char *constr;
  char *newpath = NULL;

  if (! IS_ABSOLUTE_FILE_NAME (path))
    {
      /* Generate absolute path as required by subsequent matchpathcon(),
         with libselinux < 2.1.5 2011-0826.  */
      newpath = canonicalize_filename_mode (path, CAN_MISSING);
      if (! newpath)
        error (EXIT_FAILURE, errno, _("error canonicalizing %s"),
               quote (path));
      path = newpath;
    }

  if (matchpathcon (path, mode, &scon) < 0)
    {
      /* "No such file or directory" is a confusing error,
         when processing files, when in fact it was the
         associated default context that was not found.
         Therefore map the error to something more appropriate
         to the context in which we're using matchpathcon().  */
      if (errno == ENOENT)
        errno = ENODATA;
      goto quit;
    }
  if (computecon (path, mode, &tcon) < 0)
    goto quit;
  if (!(scontext = context_new (scon)))
    goto quit;
  if (!(tcontext = context_new (tcon)))
    goto quit;

  if (!(contype = context_type_get (scontext)))
    goto quit;
  if (context_type_set (tcontext, contype))
    goto quit;
  if (!(constr = context_str (tcontext)))
    goto quit;

  rc = setfscreatecon (constr);

quit:
  context_free (scontext);
  context_free (tcontext);
  freecon (scon);
  freecon (tcon);
  free (newpath);
  return rc;
}
Beispiel #3
0
/*
  This function takes three parameters:

  PATH of an existing file system object.

  A RECURSE boolean which if the file system object is a directory, will
  call restorecon_private on every file system object in the directory.

  A LOCAL boolean that indicates whether the function should set object labels
  to the default for the local process, or use system wide settings.

  Returns false on failure.  errno will be set appropriately.
*/
bool
restorecon (char const *path, bool recurse, bool local)
{
  char *newpath = NULL;
  FTS *fts;
  bool ok = true;

  if (! IS_ABSOLUTE_FILE_NAME (path) && ! local)
    {
      /* Generate absolute path as required by subsequent matchpathcon(),
         with libselinux < 2.1.5 2011-0826.  Also generating the absolute
         path before the fts walk, will generate absolute paths in the
         fts entries, which may be quicker to process in any case.  */
      newpath = canonicalize_filename_mode (path, CAN_MISSING);
      if (! newpath)
        error (EXIT_FAILURE, errno, _("error canonicalizing %s"),
               quote (path));
    }

  const char *ftspath[2] = { newpath ? newpath : path, NULL };

  if (! recurse)
    {
      ok = restorecon_private (*ftspath, local) != -1;
      free (newpath);
      return ok;
    }

  fts = xfts_open ((char *const *) ftspath, FTS_PHYSICAL, NULL);
  while (1)
    {
      FTSENT *ent;

      ent = fts_read (fts);
      if (ent == NULL)
        {
          if (errno != 0)
            {
              error (0, errno, _("fts_read failed"));
              ok = false;
            }
          break;
        }

      ok &= restorecon_private (fts->fts_path, local) != -1;
    }

  if (fts_close (fts) != 0)
    {
      error (0, errno, _("fts_close failed"));
      ok = false;
    }

  free (newpath);
  return ok;
}
int
main ()
{
  /* Check that the symbolic link to a file can be resolved.  */
  {
    char *result1 = canonicalize_file_name ("t-can.tmp/huk");
    char *result2 = canonicalize_file_name ("t-can.tmp/tra");
    char *result3 = canonicalize_filename_mode ("t-can.tmp/huk", CAN_EXISTING);
    ASSERT (result1 != NULL);
    ASSERT (result2 != NULL);
    ASSERT (result3 != NULL);
    ASSERT (strcmp (result1, result2) == 0);
    ASSERT (strcmp (result2, result3) == 0);
    ASSERT (strcmp (result1 + strlen (result1) - 14, "/t-can.tmp/tra") == 0);
    free (result1);
    free (result2);
    free (result3);
  }

  /* Check that the symbolic link to a directory can be resolved.  */
  {
    char *result1 = canonicalize_file_name ("t-can.tmp/plo");
    char *result2 = canonicalize_file_name ("t-can.tmp/bef");
    char *result3 = canonicalize_file_name ("t-can.tmp/lum");
    char *result4 = canonicalize_filename_mode ("t-can.tmp/plo", CAN_EXISTING);
    ASSERT (result1 != NULL);
    ASSERT (result2 != NULL);
    ASSERT (result3 != NULL);
    ASSERT (result4 != NULL);
    ASSERT (strcmp (result1, result2) == 0);
    ASSERT (strcmp (result2, result3) == 0);
    ASSERT (strcmp (result3, result4) == 0);
    ASSERT (strcmp (result1 + strlen (result1) - 14, "/t-can.tmp/lum") == 0);
    free (result1);
    free (result2);
    free (result3);
    free (result4);
  }

  /* Check that a symbolic link to a nonexistent file yields NULL.  */
  {
    char *result1 = canonicalize_file_name ("t-can.tmp/ouk");
    char *result2 = canonicalize_filename_mode ("t-can.tmp/ouk", CAN_EXISTING);
    ASSERT (result1 == NULL);
    ASSERT (result2 == NULL);
  }

  /* Check that a loop of symbolic links is detected.  */
  {
    char *result1 = canonicalize_file_name ("ise");
    char *result2 = canonicalize_filename_mode ("ise", CAN_EXISTING);
    ASSERT (result1 == NULL);
    ASSERT (result2 == NULL);
  }

  /* Check that alternate modes can resolve missing basenames.  */
  {
    char *result1 = canonicalize_filename_mode ("t-can.tmp/zzz", CAN_ALL_BUT_LAST);
    char *result2 = canonicalize_filename_mode ("t-can.tmp/zzz", CAN_MISSING);
    ASSERT (result1 != NULL);
    ASSERT (result2 != NULL);
    ASSERT (strcmp (result1, result2) == 0);
    ASSERT (strcmp (result1 + strlen (result1) - 14, "/t-can.tmp/zzz") == 0);
    free (result1);
    free (result2);
  }

  /* Check that alternate modes can resolve broken symlink basenames.  */
  {
    char *result1 = canonicalize_filename_mode ("t-can.tmp/ouk", CAN_ALL_BUT_LAST);
    char *result2 = canonicalize_filename_mode ("t-can.tmp/ouk", CAN_MISSING);
    ASSERT (result1 != NULL);
    ASSERT (result2 != NULL);
    ASSERT (strcmp (result1, result2) == 0);
    ASSERT (strcmp (result1 + strlen (result1) - 14, "/t-can.tmp/wum") == 0);
    free (result1);
    free (result2);
  }

  /* Check that alternate modes can handle missing dirnames.  */
  {
    char *result1 = canonicalize_filename_mode ("t-can.zzz/zzz", CAN_ALL_BUT_LAST);
    char *result2 = canonicalize_filename_mode ("t-can.zzz/zzz", CAN_MISSING);
    ASSERT (result1 == NULL);
    ASSERT (result2 != NULL);
    ASSERT (strcmp (result2 + strlen (result2) - 14, "/t-can.zzz/zzz") == 0);
    free (result2);
  }

  /* Ensure that the following is resolved properly.
     Before 2007-09-27, it would mistakenly report a loop.  */
  {
    char *result1 = canonicalize_filename_mode ("t-can.tmp", CAN_EXISTING);
    char *result2 = canonicalize_filename_mode ("t-can.tmp/p/1", CAN_EXISTING);
    ASSERT (result1 != NULL);
    ASSERT (result2 != NULL);
    ASSERT (strcmp (result2 + strlen (result1), "/d/2") == 0);
    free (result1);
    free (result2);
  }

  return 0;
}
Beispiel #5
0
char *
canonicalize_file_name (const char *name)
{
  return canonicalize_filename_mode (name, CAN_EXISTING);
}
Beispiel #6
0
char *
canonicalize_file_name (const char *name)
{
# if HAVE_RESOLVEPATH

  char *resolved, *extra_buf = NULL;
  size_t resolved_size;
  ssize_t resolved_len;

  if (name == NULL)
    {
      __set_errno (EINVAL);
      return NULL;
    }

  if (name[0] == '\0')
    {
      __set_errno (ENOENT);
      return NULL;
    }

  /* All known hosts with resolvepath (e.g. Solaris 7) don't turn
     relative names into absolute ones, so prepend the working
     directory if the file name is not absolute.  */
  if (name[0] != '/')
    {
      char *wd;

      if (!(wd = xgetcwd ()))
	return NULL;

      extra_buf = file_name_concat (wd, name, NULL);
      name = extra_buf;
      free (wd);
    }

  resolved_size = strlen (name);
  while (1)
    {
      resolved_size = 2 * resolved_size + 1;
      resolved = xmalloc (resolved_size);
      resolved_len = resolvepath (name, resolved, resolved_size);
      if (resolved_len < 0)
	{
	  free (resolved);
	  free (extra_buf);
	  return NULL;
	}
      if (resolved_len < resolved_size)
	break;
      free (resolved);
    }

  free (extra_buf);

  /* NUL-terminate the resulting name.  */
  resolved[resolved_len] = '\0';

  return resolved;

# else

  return canonicalize_filename_mode (name, CAN_EXISTING);

# endif /* !HAVE_RESOLVEPATH */
}