/* copy-acl.c - copy access control list from one file to another file

   Copyright (C) 2002-2003, 2005-2008 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.

   Written by Paul Eggert, Andreas Grünbacher, and Bruno Haible.  */

#include <config.h>

#include "acl.h"

#include "acl-internal.h"

#include "gettext.h"
#define _(msgid) gettext (msgid)


/* Copy access control lists from one file to another. If SOURCE_DESC is
   a valid file descriptor, use file descriptor operations, else use
   filename based operations on SRC_NAME. Likewise for DEST_DESC and
   DST_NAME.
   If access control lists are not available, fchmod the target file to
   MODE.  Also sets the non-permission bits of the destination file
   (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set.
   Return 0 if successful.
   Return -2 and set errno for an error relating to the source file.
   Return -1 and set errno for an error relating to the destination file.  */

static int
qcopy_acl (const char *src_name, int source_desc, const char *dst_name,
	   int dest_desc, mode_t mode)
{
#if USE_ACL && HAVE_ACL_GET_FILE
  /* POSIX 1003.1e (draft 17 -- abandoned) specific version.  */
  /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */
# if MODE_INSIDE_ACL
  /* Linux, FreeBSD, IRIX, Tru64 */

  acl_t acl;
  int ret;

  if (HAVE_ACL_GET_FD && source_desc != -1)
    acl = acl_get_fd (source_desc);
  else
    acl = acl_get_file (src_name, ACL_TYPE_ACCESS);
  if (acl == NULL)
    {
      if (ACL_NOT_WELL_SUPPORTED (errno))
	return qset_acl (dst_name, dest_desc, mode);
      else
	return -2;
    }

  if (HAVE_ACL_SET_FD && dest_desc != -1)
    ret = acl_set_fd (dest_desc, acl);
  else
    ret = acl_set_file (dst_name, ACL_TYPE_ACCESS, acl);
  if (ret != 0)
    {
      int saved_errno = errno;

      if (ACL_NOT_WELL_SUPPORTED (errno) && !acl_access_nontrivial (acl))
	{
	  acl_free (acl);
	  return chmod_or_fchmod (dst_name, dest_desc, mode);
	}
      else
	{
	  acl_free (acl);
	  chmod_or_fchmod (dst_name, dest_desc, mode);
	  errno = saved_errno;
	  return -1;
	}
    }
  else
    acl_free (acl);

  if (mode & (S_ISUID | S_ISGID | S_ISVTX))
    {
      /* We did not call chmod so far, and either the mode and the ACL are
	 separate or special bits are to be set which don't fit into ACLs.  */

      if (chmod_or_fchmod (dst_name, dest_desc, mode) != 0)
	return -1;
    }

  if (S_ISDIR (mode))
    {
      acl = acl_get_file (src_name, ACL_TYPE_DEFAULT);
      if (acl == NULL)
	return -2;

      if (acl_set_file (dst_name, ACL_TYPE_DEFAULT, acl))
	{
	  int saved_errno = errno;

	  acl_free (acl);
	  errno = saved_errno;
	  return -1;
	}
      else
	acl_free (acl);
    }
  return 0;

# else /* !MODE_INSIDE_ACL */
  /* MacOS X */

#  if !HAVE_ACL_TYPE_EXTENDED
#   error Must have ACL_TYPE_EXTENDED
#  endif

  /* On MacOS X,  acl_get_file (name, ACL_TYPE_ACCESS)
     and          acl_get_file (name, ACL_TYPE_DEFAULT)
     always return NULL / EINVAL.  You have to use
		  acl_get_file (name, ACL_TYPE_EXTENDED)
     or           acl_get_fd (open (name, ...))
     to retrieve an ACL.
     On the other hand,
		  acl_set_file (name, ACL_TYPE_ACCESS, acl)
     and          acl_set_file (name, ACL_TYPE_DEFAULT, acl)
     have the same effect as
		  acl_set_file (name, ACL_TYPE_EXTENDED, acl):
     Each of these calls sets the file's ACL.  */

  acl_t acl;
  int ret;

  if (HAVE_ACL_GET_FD && source_desc != -1)
    acl = acl_get_fd (source_desc);
  else
    acl = acl_get_file (src_name, ACL_TYPE_EXTENDED);
  if (acl == NULL)
    {
      if (ACL_NOT_WELL_SUPPORTED (errno))
	return qset_acl (dst_name, dest_desc, mode);
      else
	return -2;
    }

  if (HAVE_ACL_SET_FD && dest_desc != -1)
    ret = acl_set_fd (dest_desc, acl);
  else
    ret = acl_set_file (dst_name, ACL_TYPE_EXTENDED, acl);
  if (ret != 0)
    {
      int saved_errno = errno;

      if (ACL_NOT_WELL_SUPPORTED (errno) && !acl_extended_nontrivial (acl))
	{
	  acl_free (acl);
	  return chmod_or_fchmod (dst_name, dest_desc, mode);
	}
      else
	{
	  acl_free (acl);
	  chmod_or_fchmod (dst_name, dest_desc, mode);
	  errno = saved_errno;
	  return -1;
	}
    }
  else
    acl_free (acl);

  /* Since !MODE_INSIDE_ACL, we have to call chmod explicitly.  */
  return chmod_or_fchmod (dst_name, dest_desc, mode);

# endif

#elif USE_ACL && defined GETACL /* Solaris, Cygwin, not HP-UX */

# if defined ACL_NO_TRIVIAL
  /* Solaris 10 (newer version), which has additional API declared in
     <sys/acl.h> (acl_t) and implemented in libsec (acl_set, acl_trivial,
     acl_fromtext, ...).  */

  int ret;
  acl_t *aclp = NULL;
  ret = (source_desc < 0
	 ? acl_get (src_name, ACL_NO_TRIVIAL, &aclp)
	 : facl_get (source_desc, ACL_NO_TRIVIAL, &aclp));
  if (ret != 0 && errno != ENOSYS)
    return -2;

  ret = qset_acl (dst_name, dest_desc, mode);
  if (ret != 0)
    return -1;

  if (aclp)
    {
      ret = (dest_desc < 0
	     ? acl_set (dst_name, aclp)
	     : facl_set (dest_desc, aclp));
      if (ret != 0)
	{
	  int saved_errno = errno;

	  acl_free (aclp);
	  errno = saved_errno;
	  return -1;
	}
      acl_free (aclp);
    }

  return 0;

# else /* Solaris, Cygwin, general case */

  /* Solaris 2.5 through Solaris 10, Cygwin, and contemporaneous versions
     of Unixware.  The acl() call returns the access and default ACL both
     at once.  */
#  ifdef ACE_GETACL
  int ace_count;
  ace_t *ace_entries;
#  endif
  int count;
  aclent_t *entries;
  int did_chmod;
  int saved_errno;
  int ret;

#  ifdef ACE_GETACL
  /* Solaris also has a different variant of ACLs, used in ZFS and NFSv4
     file systems (whereas the other ones are used in UFS file systems).
     There is an API
       pathconf (name, _PC_ACL_ENABLED)
       fpathconf (desc, _PC_ACL_ENABLED)
     that allows to determine which of the two kinds of ACLs is supported
     for the given file.  But some file systems may implement this call
     incorrectly, so better not use it.
     When fetching the source ACL, we simply fetch both ACL types.
     When setting the destination ACL, we try either ACL types, assuming
     that the kernel will translate the ACL from one form to the other.
     (See in <http://docs.sun.com/app/docs/doc/819-2241/6n4huc7ia?l=en&a=view>
     the description of ENOTSUP.)  */
  for (;;)
    {
      ace_count = (source_desc != -1
		   ? facl (source_desc, ACE_GETACLCNT, 0, NULL)
		   : acl (src_name, ACE_GETACLCNT, 0, NULL));

      if (ace_count < 0)
	{
	  if (errno == ENOSYS || errno == EINVAL)
	    {
	      ace_count = 0;
	      ace_entries = NULL;
	      break;
	    }
	  else
	    return -2;
	}

      if (ace_count == 0)
	{
	  ace_entries = NULL;
	  break;
	}

      ace_entries = (ace_t *) malloc (ace_count * sizeof (ace_t));
      if (ace_entries == NULL)
	{
	  errno = ENOMEM;
	  return -2;
	}

      if ((source_desc != -1
	   ? facl (source_desc, ACE_GETACL, ace_count, ace_entries)
	   : acl (src_name, ACE_GETACL, ace_count, ace_entries))
	  == ace_count)
	break;
      /* Huh? The number of ACL entries changed since the last call.
	 Repeat.  */
    }
#  endif

  for (;;)
    {
      count = (source_desc != -1
	       ? facl (source_desc, GETACLCNT, 0, NULL)
	       : acl (src_name, GETACLCNT, 0, NULL));

      if (count < 0)
	{
	  if (errno == ENOSYS || errno == ENOTSUP)
	    {
	      count = 0;
	      entries = NULL;
	      break;
	    }
	  else
	    return -2;
	}

      if (count == 0)
	{
	  entries = NULL;
	  break;
	}

      entries = (aclent_t *) malloc (count * sizeof (aclent_t));
      if (entries == NULL)
	{
	  errno = ENOMEM;
	  return -2;
	}

      if ((source_desc != -1
	   ? facl (source_desc, GETACL, count, entries)
	   : acl (src_name, GETACL, count, entries))
	  == count)
	break;
      /* Huh? The number of ACL entries changed since the last call.
	 Repeat.  */
    }

  /* Is there an ACL of either kind?  */
#  ifdef ACE_GETACL
  if (ace_count == 0)
#  endif
    if (count == 0)
      return qset_acl (dst_name, dest_desc, mode);

  did_chmod = 0; /* set to 1 once the mode bits in 0777 have been set */
  saved_errno = 0; /* the first non-ignorable error code */

  if (!MODE_INSIDE_ACL)
    {
      /* On Cygwin, it is necessary to call chmod before acl, because
	 chmod can change the contents of the ACL (in ways that don't
	 change the allowed accesses, but still visible).  */
      if (chmod_or_fchmod (dst_name, dest_desc, mode) != 0)
	saved_errno = errno;
      did_chmod = 1;
    }

  /* If both ace_entries and entries are available, try SETACL before
     ACE_SETACL, because SETACL cannot fail with ENOTSUP whereas ACE_SETACL
     can.  */

  if (count > 0)
    {
      ret = (dest_desc != -1
	     ? facl (dest_desc, SETACL, count, entries)
	     : acl (dst_name, SETACL, count, entries));
      if (ret < 0 && saved_errno == 0)
	{
	  saved_errno = errno;
	  if (errno == ENOSYS && !acl_nontrivial (count, entries))
	    saved_errno = 0;
	}
      else
	did_chmod = 1;
    }
  free (entries);

#  ifdef ACE_GETACL
  if (ace_count > 0)
    {
      ret = (dest_desc != -1
	     ? facl (dest_desc, ACE_SETACL, ace_count, ace_entries)
	     : acl (dst_name, ACE_SETACL, ace_count, ace_entries));
      if (ret < 0 && saved_errno == 0)
	{
	  saved_errno = errno;
	  if ((errno == ENOSYS || errno == EINVAL || errno == ENOTSUP)
	      && !acl_ace_nontrivial (ace_count, ace_entries))
	    saved_errno = 0;
	}
    }
  free (ace_entries);
#  endif

  if (MODE_INSIDE_ACL
      && did_chmod <= ((mode & (S_ISUID | S_ISGID | S_ISVTX)) ? 1 : 0))
    {
      /* We did not call chmod so far, and either the mode and the ACL are
	 separate or special bits are to be set which don't fit into ACLs.  */

      if (chmod_or_fchmod (dst_name, dest_desc, mode) != 0)
	{
	  if (saved_errno == 0)
	    saved_errno = errno;
	}
    }

  if (saved_errno)
    {
      errno = saved_errno;
      return -1;
    }
  return 0;

# endif

#elif USE_ACL && HAVE_GETACL /* HP-UX */

  int count;
  struct acl_entry entries[NACLENTRIES];
  int ret;

  for (;;)
    {
      count = (source_desc != -1
	       ? fgetacl (source_desc, 0, NULL)
	       : getacl (src_name, 0, NULL));

      if (count < 0)
	{
	  if (errno == ENOSYS || errno == EOPNOTSUPP)
	    {
	      count = 0;
	      break;
	    }
	  else
	    return -2;
	}

      if (count == 0)
	break;

      if (count > NACLENTRIES)
	/* If NACLENTRIES cannot be trusted, use dynamic memory allocation.  */
	abort ();

      if ((source_desc != -1
	   ? fgetacl (source_desc, count, entries)
	   : getacl (src_name, count, entries))
	  == count)
	break;
      /* Huh? The number of ACL entries changed since the last call.
	 Repeat.  */
    }

  if (count == 0)
    return qset_acl (dst_name, dest_desc, mode);

  ret = (dest_desc != -1
	 ? fsetacl (dest_desc, count, entries)
	 : setacl (dst_name, count, entries));
  if (ret < 0)
    {
      int saved_errno = errno;

      if (errno == ENOSYS || errno == EOPNOTSUPP)
	{
	  struct stat source_statbuf;

	  if ((source_desc != -1
	       ? fstat (source_desc, &source_statbuf)
	       : stat (src_name, &source_statbuf)) == 0)
	    {
	      if (!acl_nontrivial (count, entries, &source_statbuf))
		return chmod_or_fchmod (dst_name, dest_desc, mode);
	    }
	  else
	    saved_errno = errno;
	}

      chmod_or_fchmod (dst_name, dest_desc, mode);
      errno = saved_errno;
      return -1;
    }

  if (mode & (S_ISUID | S_ISGID | S_ISVTX))
    {
      /* We did not call chmod so far, and either the mode and the ACL are
	 separate or special bits are to be set which don't fit into ACLs.  */

      return chmod_or_fchmod (dst_name, dest_desc, mode);
    }
  return 0;

#elif USE_ACL && HAVE_ACLX_GET && 0 /* AIX */

  /* TODO */

#elif USE_ACL && HAVE_STATACL /* older AIX */

  union { struct acl a; char room[4096]; } u;
  int ret;

  if ((source_desc != -1
       ? fstatacl (source_desc, STX_NORMAL, &u.a, sizeof (u))
       : statacl (src_name, STX_NORMAL, &u.a, sizeof (u)))
      < 0)
    return -2;

  ret = (dest_desc != -1
	 ? fchacl (dest_desc, &u.a, u.a.acl_len)
	 : chacl (dst_name, &u.a, u.a.acl_len));
  if (ret < 0)
    {
      int saved_errno = errno;

      chmod_or_fchmod (dst_name, dest_desc, mode);
      errno = saved_errno;
      return -1;
    }

  /* No need to call chmod_or_fchmod at this point, since the mode bits
     S_ISUID, S_ISGID, S_ISVTX are also stored in the ACL.  */

  return 0;

#else

  return qset_acl (dst_name, dest_desc, mode);

#endif
}


/* Copy access control lists from one file to another. If SOURCE_DESC is
   a valid file descriptor, use file descriptor operations, else use
   filename based operations on SRC_NAME. Likewise for DEST_DESC and
   DST_NAME.
   If access control lists are not available, fchmod the target file to
   MODE.  Also sets the non-permission bits of the destination file
   (S_ISUID, S_ISGID, S_ISVTX) to those from MODE if any are set.
   Return 0 if successful, otherwise output a diagnostic and return -1.  */

int
copy_acl (const char *src_name, int source_desc, const char *dst_name,
	  int dest_desc, mode_t mode)
{
  int ret = qcopy_acl (src_name, source_desc, dst_name, dest_desc, mode);
  switch (ret)
    {
    case -2:
      error (0, errno, "%s", quote (src_name));
      return -1;

    case -1:
      error (0, errno, _("preserving permissions for %s"), quote (dst_name));
      return -1;

    default:
      return 0;
    }
}
