/* Test whether a file has a nontrivial access control list.

   Copyright (C) 2002-2003, 2005-2009 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"


#if USE_ACL && HAVE_ACL_GET_FILE

# if HAVE_ACL_TYPE_EXTENDED /* MacOS X */

/* ACL is an ACL, from a file, stored as type ACL_TYPE_EXTENDED.
   Return 1 if the given ACL is non-trivial.
   Return 0 if it is trivial.  */
int
acl_extended_nontrivial (acl_t acl)
{
  /* acl is non-trivial if it is non-empty.  */
  return (acl_entries (acl) > 0);
}

# else /* Linux, FreeBSD, IRIX, Tru64 */

/* ACL is an ACL, from a file, stored as type ACL_TYPE_ACCESS.
   Return 1 if the given ACL is non-trivial.
   Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.
   Return -1 and set errno upon failure to determine it.  */
int
acl_access_nontrivial (acl_t acl)
{
  /* acl is non-trivial if it has some entries other than for "user::",
     "group::", and "other::".  Normally these three should be present
     at least, allowing us to write
	return (3 < acl_entries (acl));
     but the following code is more robust.  */
#  if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD */

  acl_entry_t ace;
  int got_one;

  for (got_one = acl_get_entry (acl, ACL_FIRST_ENTRY, &ace);
       got_one > 0;
       got_one = acl_get_entry (acl, ACL_NEXT_ENTRY, &ace))
    {
      acl_tag_t tag;
      if (acl_get_tag_type (ace, &tag) < 0)
	return -1;
      if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER))
	return 1;
    }
  return got_one;

#  else /* IRIX, Tru64 */
#   if HAVE_ACL_TO_SHORT_TEXT /* IRIX */
  /* Don't use acl_get_entry: it is undocumented.  */

  int count = acl->acl_cnt;
  int i;

  for (i = 0; i < count; i++)
    {
      acl_entry_t ace = &acl->acl_entry[i];
      acl_tag_t tag = ace->ae_tag;

      if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ
	    || tag == ACL_OTHER_OBJ))
	return 1;
    }
  return 0;

#   endif
#   if HAVE_ACL_FREE_TEXT /* Tru64 */
  /* Don't use acl_get_entry: it takes only one argument and does not work.  */

  int count = acl->acl_num;
  acl_entry_t ace;

  for (ace = acl->acl_first; count > 0; ace = ace->next, count--)
    {
      acl_tag_t tag;
      acl_perm_t perm;

      tag = ace->entry->acl_type;
      if (!(tag == ACL_USER_OBJ || tag == ACL_GROUP_OBJ || tag == ACL_OTHER))
	return 1;

      perm = ace->entry->acl_perm;
      /* On Tru64, perm can also contain non-standard bits such as
	 PERM_INSERT, PERM_DELETE, PERM_MODIFY, PERM_LOOKUP, ... */
      if ((perm & ~(ACL_READ | ACL_WRITE | ACL_EXECUTE)) != 0)
	return 1;
    }
  return 0;

#   endif
#  endif
}

# endif


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

# if !defined ACL_NO_TRIVIAL /* Solaris <= 10, Cygwin */

/* Test an ACL retrieved with GETACL.
   Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
   Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
int
acl_nontrivial (int count, aclent_t *entries)
{
  int i;

  for (i = 0; i < count; i++)
    {
      aclent_t *ace = &entries[i];

      /* Note: If ace->a_type = USER_OBJ, ace->a_id is the st_uid from stat().
	 If ace->a_type = GROUP_OBJ, ace->a_id is the st_gid from stat().
	 We don't need to check ace->a_id in these cases.  */
      if (!(ace->a_type == USER_OBJ
	    || ace->a_type == GROUP_OBJ
	    || ace->a_type == OTHER_OBJ
	    /* Note: Cygwin does not return a CLASS_OBJ ("mask:") entry
	       sometimes.  */
	    || ace->a_type == CLASS_OBJ))
	return 1;
    }
  return 0;
}

#  ifdef ACE_GETACL

/* Test an ACL retrieved with ACE_GETACL.
   Return 1 if the given ACL, consisting of COUNT entries, is non-trivial.
   Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
int
acl_ace_nontrivial (int count, ace_t *entries)
{
  int i;

  /* The flags in the ace_t structure changed in a binary incompatible way
     when ACL_NO_TRIVIAL etc. were introduced in <sys/acl.h> version 1.15.
     How to distinguish the two conventions at runtime?
     In the old convention, usually three ACEs have a_flags = ACE_OWNER /
     ACE_GROUP / ACE_OTHER, in the range 0x0100..0x0400.  In the new
     convention, these values are not used.  */
  int old_convention = 0;

  for (i = 0; i < count; i++)
    if (entries[i].a_flags & (ACE_OWNER | ACE_GROUP | ACE_OTHER))
      {
	old_convention = 1;
	break;
      }

  if (old_convention)
    /* Running on Solaris 10.  */
    for (i = 0; i < count; i++)
      {
	ace_t *ace = &entries[i];

	/* Note:
	   If ace->a_flags = ACE_OWNER, ace->a_who is the st_uid from stat().
	   If ace->a_flags = ACE_GROUP, ace->a_who is the st_gid from stat().
	   We don't need to check ace->a_who in these cases.  */
	if (!(ace->a_type == ALLOW
	      && (ace->a_flags == ACE_OWNER
		  || ace->a_flags == ACE_GROUP
		  || ace->a_flags == ACE_OTHER)))
	  return 1;
      }
  else
    /* Running on Solaris 10 (newer version) or Solaris 11.  */
    for (i = 0; i < count; i++)
      {
	ace_t *ace = &entries[i];

	if (!(ace->a_type == ACE_ACCESS_ALLOWED_ACE_TYPE
	      && (ace->a_flags == NEW_ACE_OWNER
		  || ace->a_flags
		     == (NEW_ACE_GROUP | NEW_ACE_IDENTIFIER_GROUP)
		  || ace->a_flags == ACE_EVERYONE)
	      && (ace->a_access_mask
		  & ~(NEW_ACE_READ_DATA | NEW_ACE_WRITE_DATA | NEW_ACE_EXECUTE))
		 == 0))
	  return 1;
      }

  return 0;
}

#  endif

# endif

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

/* Return 1 if the given ACL is non-trivial.
   Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
int
acl_nontrivial (int count, struct acl_entry *entries, struct stat *sb)
{
  int i;

  for (i = 0; i < count; i++)
    {
      struct acl_entry *ace = &entries[i];

      if (!((ace->uid == sb->st_uid && ace->gid == ACL_NSGROUP)
	    || (ace->uid == ACL_NSUSER && ace->gid == sb->st_gid)
	    || (ace->uid == ACL_NSUSER && ace->gid == ACL_NSGROUP)))
	return 1;
    }
  return 0;
}

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

/* TODO */

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

/* Return 1 if the given ACL is non-trivial.
   Return 0 if it is trivial, i.e. equivalent to a simple stat() mode.  */
int
acl_nontrivial (struct acl *a)
{
  /* The normal way to iterate through an ACL is like this:
       struct acl_entry *ace;
       for (ace = a->acl_ext; ace != acl_last (a); ace = acl_nxt (ace))
         {
           struct ace_id *aei;
           switch (ace->ace_type)
             {
             case ACC_PERMIT:
             case ACC_DENY:
             case ACC_SPECIFY:
               ...;
             }
           for (aei = ace->ace_id; aei != id_last (ace); aei = id_nxt (aei))
             ...
         }
   */
  return (acl_last (a) != a->acl_ext ? 1 : 0);
}

#endif


/* Return 1 if NAME has a nontrivial access control list, 0 if NAME
   only has no or a base access control list, and -1 (setting errno)
   on error.  SB must be set to the stat buffer of FILE.  */

int
file_has_acl (char const *name, struct stat const *sb)
{
#if USE_ACL
  if (! S_ISLNK (sb->st_mode))
    {
# if HAVE_ACL_GET_FILE

      /* POSIX 1003.1e (draft 17 -- abandoned) specific version.  */
      /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */
      int ret;

      if (HAVE_ACL_EXTENDED_FILE) /* Linux */
	{
	  /* On Linux, acl_extended_file is an optimized function: It only
	     makes two calls to getxattr(), one for ACL_TYPE_ACCESS, one for
	     ACL_TYPE_DEFAULT.  */
	  ret = acl_extended_file (name);
	}
      else /* FreeBSD, MacOS X, IRIX, Tru64 */
	{
#  if HAVE_ACL_TYPE_EXTENDED /* MacOS X */
	  /* On MacOS X, acl_get_file (name, ACL_TYPE_ACCESS)
	     and acl_get_file (name, ACL_TYPE_DEFAULT)
	     always return NULL / EINVAL.  There is no point in making
	     these two useless calls.  The real ACL is retrieved through
	     acl_get_file (name, ACL_TYPE_EXTENDED).  */
	  acl_t acl = acl_get_file (name, ACL_TYPE_EXTENDED);
	  if (acl)
	    {
	      ret = acl_extended_nontrivial (acl);
	      acl_free (acl);
	    }
	  else
	    ret = -1;
#  else /* FreeBSD, IRIX, Tru64 */
	  acl_t acl = acl_get_file (name, ACL_TYPE_ACCESS);
	  if (acl)
	    {
	      int saved_errno;

	      ret = acl_access_nontrivial (acl);
	      saved_errno = errno;
	      acl_free (acl);
	      errno = saved_errno;
#   if HAVE_ACL_FREE_TEXT /* Tru64 */
	      /* On OSF/1, acl_get_file (name, ACL_TYPE_DEFAULT) always
		 returns NULL with errno not set.  There is no point in
		 making this call.  */
#   else /* FreeBSD, IRIX */
	      /* On Linux, FreeBSD, IRIX, acl_get_file (name, ACL_TYPE_ACCESS)
		 and acl_get_file (name, ACL_TYPE_DEFAULT) on a directory
		 either both succeed or both fail; it depends on the
		 filesystem.  Therefore there is no point in making the second
		 call if the first one already failed.  */
	      if (ret == 0 && S_ISDIR (sb->st_mode))
		{
		  acl = acl_get_file (name, ACL_TYPE_DEFAULT);
		  if (acl)
		    {
		      ret = (0 < acl_entries (acl));
		      acl_free (acl);
		    }
		  else
		    ret = -1;
		}
#   endif
	    }
	  else
	    ret = -1;
#  endif
	}
      if (ret < 0)
	return ACL_NOT_WELL_SUPPORTED (errno) ? 0 : -1;
      return ret;

# elif HAVE_ACL && defined GETACLCNT /* 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, ...).  */
      return acl_trivial (name);

#  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.  */
      int count;
      {
	aclent_t *entries;

	for (;;)
	  {
	    count = acl (name, GETACLCNT, 0, NULL);

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

	    if (count == 0)
	      break;

	    /* Don't use MIN_ACL_ENTRIES:  It's set to 4 on Cygwin, but Cygwin
	       returns only 3 entries for files with no ACL.  But this is safe:
	       If there are more than 4 entries, there cannot be only the
	       "user::", "group::", "other:", and "mask:" entries.  */
	    if (count > 4)
	      return 1;

	    entries = (aclent_t *) malloc (count * sizeof (aclent_t));
	    if (entries == NULL)
	      {
		errno = ENOMEM;
		return -1;
	      }
	    if (acl (name, GETACL, count, entries) == count)
	      {
		if (acl_nontrivial (count, entries))
		  {
		    free (entries);
		    return 1;
		  }
		free (entries);
		break;
	      }
	    /* Huh? The number of ACL entries changed since the last call.
	       Repeat.  */
	    free (entries);
	  }
      }

#   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).  */
      {
	ace_t *entries;

	for (;;)
	  {
	    count = acl (name, ACE_GETACLCNT, 0, NULL);

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

	    if (count == 0)
	      break;

	    /* If there are more than 3 entries, there cannot be only the
	       ACE_OWNER, ACE_GROUP, ACE_OTHER entries.  */
	    if (count > 3)
	      return 1;

	    entries = (ace_t *) malloc (count * sizeof (ace_t));
	    if (entries == NULL)
	      {
		errno = ENOMEM;
		return -1;
	      }
	    if (acl (name, ACE_GETACL, count, entries) == count)
	      {
		if (acl_ace_nontrivial (count, entries))
		  {
		    free (entries);
		    return 1;
		  }
		free (entries);
		break;
	      }
	    /* Huh? The number of ACL entries changed since the last call.
	       Repeat.  */
	    free (entries);
	  }
      }
#   endif

      return 0;
#  endif

# elif HAVE_GETACL /* HP-UX */

      int count;
      struct acl_entry entries[NACLENTRIES];

      for (;;)
	{
	  count = getacl (name, 0, NULL);

	  if (count < 0)
	    return (errno == ENOSYS || errno == EOPNOTSUPP ? 0 : -1);

	  if (count == 0)
	    return 0;

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

	  /* If there are more than 3 entries, there cannot be only the
	     (uid,%), (%,gid), (%,%) entries.  */
	  if (count > 3)
	    return 1;

	  if (getacl (name, count, entries) == count)
	    {
	      struct stat statbuf;

	      if (stat (name, &statbuf) < 0)
		return -1;

	      return acl_nontrivial (count, entries, &statbuf);
	    }
	  /* Huh? The number of ACL entries changed since the last call.
	     Repeat.  */
	}

# elif HAVE_ACLX_GET && 0 /* AIX */

      /* TODO: use aclx_get(), and then?  */

# elif HAVE_STATACL /* older AIX */

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

      if (statacl (name, STX_NORMAL, &u.a, sizeof (u)) < 0)
	return -1;

      return acl_nontrivial (&u.a);

# endif
    }
#endif

  return 0;
}
