Example #1
0
File: acl.c Project: vanElden/burp
static int get_acl_string(struct asfd *asfd, acl_t acl, char **acltext,
	size_t *alen, const char *path, char type, struct cntr *cntr)
{
	int ret=0;
	char pre[10]="";
	char *tmp=NULL;
	ssize_t tlen=0;
	char *ourtext=NULL;
	ssize_t maxlen=0xFFFFFFFF/2;

	if(!(tmp=acl_to_text(acl, NULL)))
	{
		logw(asfd, cntr, "could not get ACL text of '%s'\n", path);
		goto end; // carry on
	}

	tlen=strlen(tmp);

	if(tlen>maxlen)
	{
		logw(asfd, cntr, "ACL of '%s' too long: %d\n", path, tlen);
		goto end; // carry on
	}

	snprintf(pre, sizeof(pre), "%c%08X", type, (unsigned int)tlen);
	if(!(ourtext=prepend(pre, tmp))
	  || !(*acltext=prepend_len(*acltext,
		*alen, ourtext, tlen+9, "", 0, alen)))
			ret=-1;
end:
	free_w(&tmp);
	free_w(&ourtext);
	return ret;
}
Example #2
0
/* "system.posix_acl_default" */
static void
xattrs__acls_get_d (int parentfd, char const *file_name,
                    struct tar_stat_info *st,
                    char **ret_ptr, size_t * ret_len)
{
  char *val = NULL;
  ssize_t len;
  acl_t acl;

  if (!(acl = acl_get_file_at (parentfd, file_name, ACL_TYPE_DEFAULT)))
    {
      if (errno != ENOTSUP)
        call_arg_warn ("acl_get_file_at", file_name);
      return;
    }

  val = acl_to_text (acl, &len);
  acl_free (acl);

  if (!val)
    {
      call_arg_warn ("acl_to_text", file_name);
      return;
    }

  *ret_ptr = xstrdup (val);
  *ret_len = len;

  acl_free (val);
}
Example #3
0
int
acl_entries (acl_t acl)
{
  char *t;
  int entries = 0;
  char *text = acl_to_text (acl, NULL);
  if (! text)
    return -1;
  for (t = text; *t; t++)
    entries += (*t == '\n');
  acl_free_text (text);
  return entries;
}
Example #4
0
QString KrVfsHandler::getACL(const QString & path, int type)
{
    Q_UNUSED(path);
    Q_UNUSED(type);
#ifdef HAVE_POSIX_ACL
    acl_t acl = 0;
    // do we have an acl for the file, and/or a default acl for the dir, if it is one?
    if ((acl = acl_get_file(path.toLocal8Bit(), type)) != 0) {
        bool aclExtended = false;

#ifdef HAVE_NON_POSIX_ACL_EXTENSIONS
        aclExtended = acl_equiv_mode(acl, 0);
#else
        acl_entry_t entry;
        int ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
        while (ret == 1) {
            acl_tag_t currentTag;
            acl_get_tag_type(entry, &currentTag);
            if (currentTag != ACL_USER_OBJ &&
                    currentTag != ACL_GROUP_OBJ &&
                    currentTag != ACL_OTHER) {
                aclExtended = true;
                break;
            }
            ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
        }
#endif

        if (!aclExtended) {
            acl_free(acl);
            acl = 0;
        }
    }

    if (acl == 0)
        return QString();

    char *aclString = acl_to_text(acl, 0);
    QString ret = QString::fromLatin1(aclString);
    acl_free((void*)aclString);
    acl_free(acl);

    return ret;
#else
    return QString();
#endif
}
Example #5
0
int do_getfacl(const char *path, const char *filter)
{
	char *textacl;
	acl_t acl;
	ssize_t size;
	const char *p;
	const char *loc;
	char c;
	int def;
	int k;

	errno = 0;
	def = !strcmp(filter,"default");
	if (def || !strcmp(filter,"access")) {
		acl = acl_get_file(path,(def ? ACL_TYPE_DEFAULT : ACL_TYPE_ACCESS));
		if (acl) {
				/*
				 * When there is no extended ACL, we get
				 * ENODATA (not mentioned in the man.)
				 * In such situation return basic ACL
				 * (or void for default ACL) with no error
				 */
			if (errno == ENODATA)
				errno = 0;
			textacl = acl_to_text(acl,&size);
				/* getting all the access or default rights */
			k = 0;
			p = textacl;
			while (p && *p) {
				loc = p;
				if (loc && strchr("ugom",*loc)) {
					c = *loc;
					loc = strchr(loc,':');
					if (loc) {
						if (k) {
							putchar(',');
							k++;
							}
						putchar(c);
						k++;
						while (*loc
						   && (*loc != '\n')
						   && (*loc != '\t')) {
							c = *loc++;
							putchar(c);
							k++;
						}
					}
				}
				while (*p && (*p != '\n')) p++;
				if (*p) p++;
			}
			if (textacl)
				acl_free(textacl);
			if (k)
				putchar('\n');
			else
				printf("void\n");
			acl_free(acl);
			/* for some reason the functions above may set errno */
			errno = 0;
		}
	} else
		errno = EBADRQC; /* "bad request" */
	return (-errno);
}
Example #6
0
int
main (int argc, char *argv[])
{
  const char *file1;
  const char *file2;

  set_program_name (argv[0]);

  ASSERT (argc == 3);

  file1 = argv[1];
  file2 = argv[2];

  /* Compare the contents of the two files.  */
  {
    size_t size1;
    char *contents1;
    size_t size2;
    char *contents2;

    contents1 = read_file (file1, &size1);
    if (contents1 == NULL)
      {
        fprintf (stderr, "error reading file %s: errno = %d\n", file1, errno);
        fflush (stderr);
        abort ();
      }
    contents2 = read_file (file2, &size2);
    if (contents2 == NULL)
      {
        fprintf (stderr, "error reading file %s: errno = %d\n", file2, errno);
        fflush (stderr);
        abort ();
      }

    if (size2 != size1)
      {
        fprintf (stderr, "files %s and %s have different sizes\n",
                 file1, file2);
        fflush (stderr);
        abort ();
      }
    if (memcmp (contents1, contents2, size1) != 0)
      {
        fprintf (stderr, "files %s and %s have different contents\n",
                 file1, file2);
        fflush (stderr);
        abort ();
      }
  }

  /* Compare the access permissions of the two files, including ACLs.  */
  {
    struct stat statbuf1;
    struct stat statbuf2;

    if (stat (file1, &statbuf1) < 0)
      {
        fprintf (stderr, "error accessing file %s: errno = %d\n", file1, errno);
        fflush (stderr);
        abort ();
      }
    if (stat (file2, &statbuf2) < 0)
      {
        fprintf (stderr, "error accessing file %s: errno = %d\n", file2, errno);
        fflush (stderr);
        abort ();
      }
    if (statbuf1.st_mode != statbuf2.st_mode)
      {
        fprintf (stderr, "files %s and %s have different access modes: %03o and %03o\n",
                 file1, file2,
                (unsigned int) statbuf1.st_mode, (unsigned int) statbuf2.st_mode);
        return 1;
      }
  }
  {
#if HAVE_ACL_GET_FILE /* Linux, FreeBSD, MacOS X, IRIX, Tru64 */
    static const int types[] =
      {
        ACL_TYPE_ACCESS
# if HAVE_ACL_TYPE_EXTENDED /* MacOS X */
        , ACL_TYPE_EXTENDED
# endif
      };
    int t;

    for (t = 0; t < sizeof (types) / sizeof (types[0]); t++)
      {
        int type = types[t];
        acl_t acl1;
        char *text1;
        int errno1;
        acl_t acl2;
        char *text2;
        int errno2;

        acl1 = acl_get_file (file1, type);
        if (acl1 == (acl_t)NULL)
          {
            text1 = NULL;
            errno1 = errno;
          }
        else
          {
            text1 = acl_to_text (acl1, NULL);
            if (text1 == NULL)
              errno1 = errno;
            else
              errno1 = 0;
          }
        acl2 = acl_get_file (file2, type);
        if (acl2 == (acl_t)NULL)
          {
            text2 = NULL;
            errno2 = errno;
          }
        else
          {
            text2 = acl_to_text (acl2, NULL);
            if (text2 == NULL)
              errno2 = errno;
            else
              errno2 = 0;
          }

        if (acl1 != (acl_t)NULL)
          {
            if (acl2 != (acl_t)NULL)
              {
                if (text1 != NULL)
                  {
                    if (text2 != NULL)
                      {
                        if (strcmp (text1, text2) != 0)
                          {
                            fprintf (stderr, "files %s and %s have different ACLs:\n%s\n%s\n",
                                     file1, file2, text1, text2);
                            return 1;
                          }
                      }
                    else
                      {
                        fprintf (stderr, "file %s has a valid ACL, but file %s has an invalid ACL\n",
                                 file1, file2);
                        return 1;
                      }
                  }
                else
                  {
                    if (text2 != NULL)
                      {
                        fprintf (stderr, "file %s has an invalid ACL, but file %s has a valid ACL\n",
                                 file1, file2);
                        return 1;
                      }
                    else
                      {
                        if (errno1 != errno2)
                          {
                            fprintf (stderr, "files %s and %s have differently invalid ACLs, errno = %d vs. %d\n",
                                     file1, file2, errno1, errno2);
                            return 1;
                          }
                      }
                  }
              }
            else
              {
                fprintf (stderr, "file %s has an ACL, but file %s has no ACL\n",
                         file1, file2);
                return 1;
              }
          }
        else
          {
            if (acl2 != (acl_t)NULL)
              {
                fprintf (stderr, "file %s has no ACL, but file %s has an ACL\n",
                         file1, file2);
                return 1;
              }
          }
      }
#elif HAVE_FACL && defined GETACL /* Solaris, Cygwin, not HP-UX */
  int count1;
  int count2;

  count1 = acl (file1, GETACLCNT, 0, NULL);
  if (count1 < 0 && errno == ENOSYS) /* Can happen on Solaris 10 with ZFS */
    count1 = 0;
  count2 = acl (file2, GETACLCNT, 0, NULL);
  if (count2 < 0 && errno == ENOSYS) /* Can happen on Solaris 10 with ZFS */
    count2 = 0;

  if (count1 < 0)
    {
      fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
      fflush (stderr);
      abort ();
    }
  if (count2 < 0)
    {
      fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
      fflush (stderr);
      abort ();
    }
  if (count1 != count2)
    {
      fprintf (stderr, "files %s and %s have different number of ACLs: %d and %d\n",
               file1, file2, count1, count2);
      return 1;
    }
  else
    {
      aclent_t *entries1 = XNMALLOC (count1, aclent_t);
      aclent_t *entries2 = XNMALLOC (count2, aclent_t);
      int i;

      if (count1 > 0 && acl (file1, GETACL, count1, entries1) < count1)
        {
          fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
          fflush (stderr);
          abort ();
        }
      if (count2 > 0 && acl (file2, GETACL, count2, entries2) < count1)
        {
          fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
          fflush (stderr);
          abort ();
        }
      for (i = 0; i < count1; i++)
        {
          if (entries1[i].a_type != entries2[i].a_type)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different types %d and %d\n",
                       file1, file2, i, entries1[i].a_type, entries2[i].a_type);
              return 1;
            }
          if (entries1[i].a_id != entries2[i].a_id)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different ids %d and %d\n",
                       file1, file2, i, (int)entries1[i].a_id, (int)entries2[i].a_id);
              return 1;
            }
          if (entries1[i].a_perm != entries2[i].a_perm)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different permissions %03o and %03o\n",
                       file1, file2, i, (unsigned int) entries1[i].a_perm, (unsigned int) entries2[i].a_perm);
              return 1;
            }
        }
    }
# ifdef ACE_GETACL
  count1 = acl (file1, ACE_GETACLCNT, 0, NULL);
  if (count1 < 0 && errno == EINVAL)
    count1 = 0;
  count2 = acl (file2, ACE_GETACLCNT, 0, NULL);
  if (count2 < 0 && errno == EINVAL)
    count2 = 0;
  if (count1 < 0)
    {
      fprintf (stderr, "error accessing the ACE-ACLs of file %s\n", file1);
      fflush (stderr);
      abort ();
    }
  if (count2 < 0)
    {
      fprintf (stderr, "error accessing the ACE-ACLs of file %s\n", file2);
      fflush (stderr);
      abort ();
    }
  if (count1 != count2)
    {
      fprintf (stderr, "files %s and %s have different number of ACE-ACLs: %d and %d\n",
               file1, file2, count1, count2);
      return 1;
    }
  else if (count1 > 0)
    {
      ace_t *entries1 = XNMALLOC (count1, ace_t);
      ace_t *entries2 = XNMALLOC (count2, ace_t);
      int i;

      if (acl (file1, ACE_GETACL, count1, entries1) < count1)
        {
          fprintf (stderr, "error retrieving the ACE-ACLs of file %s\n", file1);
          fflush (stderr);
          abort ();
        }
      if (acl (file2, ACE_GETACL, count2, entries2) < count1)
        {
          fprintf (stderr, "error retrieving the ACE-ACLs of file %s\n", file2);
          fflush (stderr);
          abort ();
        }
      for (i = 0; i < count1; i++)
        {
          if (entries1[i].a_type != entries2[i].a_type)
            {
              fprintf (stderr, "files %s and %s: different ACE-ACL entry #%d: different types %d and %d\n",
                       file1, file2, i, entries1[i].a_type, entries2[i].a_type);
              return 1;
            }
          if (entries1[i].a_who != entries2[i].a_who)
            {
              fprintf (stderr, "files %s and %s: different ACE-ACL entry #%d: different ids %d and %d\n",
                       file1, file2, i, (int)entries1[i].a_who, (int)entries2[i].a_who);
              return 1;
            }
          if (entries1[i].a_access_mask != entries2[i].a_access_mask)
            {
              fprintf (stderr, "files %s and %s: different ACE-ACL entry #%d: different access masks %03o and %03o\n",
                       file1, file2, i, (unsigned int) entries1[i].a_access_mask, (unsigned int) entries2[i].a_access_mask);
              return 1;
            }
          if (entries1[i].a_flags != entries2[i].a_flags)
            {
              fprintf (stderr, "files %s and %s: different ACE-ACL entry #%d: different flags 0x%x and 0x%x\n",
                       file1, file2, i, (unsigned int) entries1[i].a_flags, (unsigned int) entries2[i].a_flags);
              return 1;
            }
        }
    }
# endif
#elif HAVE_GETACL /* HP-UX */
  int count1;
  int count2;

  count1 = getacl (file1, 0, NULL);
  if (count1 < 0
      && (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP))
    count1 = 0;
  count2 = getacl (file2, 0, NULL);
  if (count2 < 0
      && (errno == ENOSYS || errno == EOPNOTSUPP || errno == ENOTSUP))
    count2 = 0;

  if (count1 < 0)
    {
      fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
      fflush (stderr);
      abort ();
    }
  if (count2 < 0)
    {
      fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
      fflush (stderr);
      abort ();
    }
  if (count1 != count2)
    {
      fprintf (stderr, "files %s and %s have different number of ACLs: %d and %d\n",
               file1, file2, count1, count2);
      return 1;
    }
  else if (count1 > 0)
    {
      struct acl_entry *entries1 = XNMALLOC (count1, struct acl_entry);
      struct acl_entry *entries2 = XNMALLOC (count2, struct acl_entry);
      int i;

      if (getacl (file1, count1, entries1) < count1)
        {
          fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
          fflush (stderr);
          abort ();
        }
      if (getacl (file2, count2, entries2) < count1)
        {
          fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
          fflush (stderr);
          abort ();
        }
      for (i = 0; i < count1; i++)
        {
          if (entries1[i].uid != entries2[i].uid)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different uids %d and %d\n",
                       file1, file2, i, (int)entries1[i].uid, (int)entries2[i].uid);
              return 1;
            }
          if (entries1[i].gid != entries2[i].gid)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different gids %d and %d\n",
                       file1, file2, i, (int)entries1[i].gid, (int)entries2[i].gid);
              return 1;
            }
          if (entries1[i].mode != entries2[i].mode)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different permissions %03o and %03o\n",
                       file1, file2, i, (unsigned int) entries1[i].mode, (unsigned int) entries2[i].mode);
              return 1;
            }
        }
    }

# if HAVE_ACLV_H /* HP-UX >= 11.11 */
  {
    struct acl dummy_entries[NACLVENTRIES];

    count1 = acl ((char *) file1, ACL_CNT, NACLVENTRIES, dummy_entries);
    if (count1 < 0
        && (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL))
      count1 = 0;
    count2 = acl ((char *) file2, ACL_CNT, NACLVENTRIES, dummy_entries);
    if (count2 < 0
        && (errno == ENOSYS || errno == EOPNOTSUPP || errno == EINVAL))
      count2 = 0;
  }

  if (count1 < 0)
    {
      fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
      fflush (stderr);
      abort ();
    }
  if (count2 < 0)
    {
      fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
      fflush (stderr);
      abort ();
    }
  if (count1 != count2)
    {
      fprintf (stderr, "files %s and %s have different number of ACLs: %d and %d\n",
               file1, file2, count1, count2);
      return 1;
    }
  else if (count1 > 0)
    {
      struct acl *entries1 = XNMALLOC (count1, struct acl);
      struct acl *entries2 = XNMALLOC (count2, struct acl);
      int i;

      if (acl ((char *) file1, ACL_GET, count1, entries1) < count1)
        {
          fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
          fflush (stderr);
          abort ();
        }
      if (acl ((char *) file2, ACL_GET, count2, entries2) < count1)
        {
          fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
          fflush (stderr);
          abort ();
        }
      for (i = 0; i < count1; i++)
        {
          if (entries1[i].a_type != entries2[i].a_type)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different types %d and %d\n",
                       file1, file2, i, entries1[i].a_type, entries2[i].a_type);
              return 1;
            }
          if (entries1[i].a_id != entries2[i].a_id)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different ids %d and %d\n",
                       file1, file2, i, (int)entries1[i].a_id, (int)entries2[i].a_id);
              return 1;
            }
          if (entries1[i].a_perm != entries2[i].a_perm)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different permissions %03o and %03o\n",
                       file1, file2, i, (unsigned int) entries1[i].a_perm, (unsigned int) entries2[i].a_perm);
              return 1;
            }
        }
    }
# endif
#elif HAVE_ACLX_GET /* AIX */
  acl_type_t type1;
  char acl1[1000];
  size_t aclsize1 = sizeof (acl1);
  mode_t mode1;
  char text1[1000];
  size_t textsize1 = sizeof (text1);
  acl_type_t type2;
  char acl2[1000];
  size_t aclsize2 = sizeof (acl2);
  mode_t mode2;
  char text2[1000];
  size_t textsize2 = sizeof (text2);

  /* The docs say that type1 being 0 is equivalent to ACL_ANY, but it is not
     true, in AIX 5.3.  */
  type1.u64 = ACL_ANY;
  if (aclx_get (file1, 0, &type1, acl1, &aclsize1, &mode1) < 0)
    {
      if (errno == ENOSYS)
        text1[0] = '\0';
      else
        {
          fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
          fflush (stderr);
          abort ();
        }
    }
  else
    if (aclx_printStr (text1, &textsize1, acl1, aclsize1, type1, file1, 0) < 0)
      {
        fprintf (stderr, "cannot convert the ACLs of file %s to text\n", file1);
        fflush (stderr);
        abort ();
      }

  /* The docs say that type2 being 0 is equivalent to ACL_ANY, but it is not
     true, in AIX 5.3.  */
  type2.u64 = ACL_ANY;
  if (aclx_get (file2, 0, &type2, acl2, &aclsize2, &mode2) < 0)
    {
      if (errno == ENOSYS)
        text2[0] = '\0';
      else
        {
          fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
          fflush (stderr);
          abort ();
        }
    }
  else
    if (aclx_printStr (text2, &textsize2, acl2, aclsize2, type2, file2, 0) < 0)
      {
        fprintf (stderr, "cannot convert the ACLs of file %s to text\n", file2);
        fflush (stderr);
        abort ();
      }

  if (strcmp (text1, text2) != 0)
    {
      fprintf (stderr, "files %s and %s have different ACLs:\n%s\n%s\n",
               file1, file2, text1, text2);
      return 1;
    }
#elif HAVE_STATACL /* older AIX */
  union { struct acl a; char room[4096]; } acl1;
  union { struct acl a; char room[4096]; } acl2;
  unsigned int i;

  if (statacl (file1, STX_NORMAL, &acl1.a, sizeof (acl1)) < 0)
    {
      fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
      fflush (stderr);
      abort ();
    }
  if (statacl (file2, STX_NORMAL, &acl2.a, sizeof (acl2)) < 0)
    {
      fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
      fflush (stderr);
      abort ();
    }

  if (acl1.a.acl_len != acl2.a.acl_len)
    {
      fprintf (stderr, "files %s and %s have different ACL lengths: %u and %u\n",
               file1, file2, acl1.a.acl_len, acl2.a.acl_len);
      return 1;
    }
  if (acl1.a.acl_mode != acl2.a.acl_mode)
    {
      fprintf (stderr, "files %s and %s have different ACL modes: %03o and %03o\n",
               file1, file2, acl1.a.acl_mode, acl2.a.acl_mode);
      return 1;
    }
  if (acl1.a.u_access != acl2.a.u_access
      || acl1.a.g_access != acl2.a.g_access
      || acl1.a.o_access != acl2.a.o_access)
    {
      fprintf (stderr, "files %s and %s have different ACL access masks: %03o %03o %03o and %03o %03o %03o\n",
               file1, file2,
               acl1.a.u_access, acl1.a.g_access, acl1.a.o_access,
               acl2.a.u_access, acl2.a.g_access, acl2.a.o_access);
      return 1;
    }
  if (memcmp (acl1.a.acl_ext, acl2.a.acl_ext, acl1.a.acl_len) != 0)
    {
      fprintf (stderr, "files %s and %s have different ACL entries\n",
               file1, file2);
      return 1;
    }
#elif HAVE_ACLSORT /* NonStop Kernel */
  int count1;
  int count2;

  count1 = acl ((char *) file1, ACL_CNT, NACLENTRIES, NULL);
  count2 = acl ((char *) file2, ACL_CNT, NACLENTRIES, NULL);

  if (count1 < 0)
    {
      fprintf (stderr, "error accessing the ACLs of file %s\n", file1);
      fflush (stderr);
      abort ();
    }
  if (count2 < 0)
    {
      fprintf (stderr, "error accessing the ACLs of file %s\n", file2);
      fflush (stderr);
      abort ();
    }
  if (count1 != count2)
    {
      fprintf (stderr, "files %s and %s have different number of ACLs: %d and %d\n",
               file1, file2, count1, count2);
      return 1;
    }
  else if (count1 > 0)
    {
      struct acl *entries1 = XNMALLOC (count1, struct acl);
      struct acl *entries2 = XNMALLOC (count2, struct acl);
      int i;

      if (acl ((char *) file1, ACL_GET, count1, entries1) < count1)
        {
          fprintf (stderr, "error retrieving the ACLs of file %s\n", file1);
          fflush (stderr);
          abort ();
        }
      if (acl ((char *) file2, ACL_GET, count2, entries2) < count1)
        {
          fprintf (stderr, "error retrieving the ACLs of file %s\n", file2);
          fflush (stderr);
          abort ();
        }
      for (i = 0; i < count1; i++)
        {
          if (entries1[i].a_type != entries2[i].a_type)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different types %d and %d\n",
                       file1, file2, i, entries1[i].a_type, entries2[i].a_type);
              return 1;
            }
          if (entries1[i].a_id != entries2[i].a_id)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different ids %d and %d\n",
                       file1, file2, i, (int)entries1[i].a_id, (int)entries2[i].a_id);
              return 1;
            }
          if (entries1[i].a_perm != entries2[i].a_perm)
            {
              fprintf (stderr, "files %s and %s: different ACL entry #%d: different permissions %03o and %03o\n",
                       file1, file2, i, (unsigned int) entries1[i].a_perm, (unsigned int) entries2[i].a_perm);
              return 1;
            }
        }
    }
#endif
  }

  return 0;
}
Example #7
0
/* Obtain the ACL of the given file in long text form.
   @param path          Path to the file
   @param text          Will hold the result. This is a managed object which
                        finally has to be freed by a call to this function
                        with bit15 of flag.
   @param flag          Bitfield for control purposes
                        (bit0=  obtain default ACL rather than access ACL)
                        bit4=  set *text = NULL and return 2
                               if the ACL matches st_mode permissions.
                        bit5=  in case of symbolic link: inquire link target
                        bit15= free text and return 1
   @return              > 0 ok
                          0 ACL support not enabled at compile time
                            or filesystem does not support ACL
                         -1 failure of system ACL service (see errno)
                         -2 attempt to inquire ACL of a symbolic
                            link without bit4 or bit5
*/
int aaip_get_acl_text(char *path, char **text, int flag)
{
#ifdef Libisofs_with_aaip_acL
 acl_t acl= NULL;
#endif
 struct stat stbuf;
 int ret;

 if(flag & (1 << 15)) {
   if(*text != NULL)
#ifdef Libisofs_with_aaip_acL
     acl_free(*text);
#else
     free(*text);
#endif
   *text= NULL;
   return(1);
 }

 *text= NULL;
 if(flag & 32)
   ret= stat(path, &stbuf);
 else
   ret= lstat(path, &stbuf);
 if(ret == -1)
   return(-1);
 if((stbuf.st_mode & S_IFMT) == S_IFLNK) {
   if(flag & 16)
     return(2);
   return(-2);
 }

 /* Note: no ACL_TYPE_DEFAULT in FreeBSD  */
 if(flag & 1)
   return(0);

#ifdef Libisofs_with_aaip_acL

 acl= acl_get_file(path, ACL_TYPE_ACCESS);

 if(acl == NULL) {
   if(errno == EOPNOTSUPP) {
     /* filesystem does not support ACL */
     if(flag & 16)
       return(2);

     /* >>> ??? fake ACL from POSIX permissions ? */;

     return(0);
   }
   return(-1);
 }
 *text= acl_to_text(acl, NULL);
 acl_free(acl);

#else /* Libisofs_with_aaip_acL */

 /* ??? >>> Fake ACL */;

 return(0);

#endif /* ! Libisofs_with_aaip_acL */

 if(*text == NULL)
   return(-1);
 if(flag & 16) {
   ret = aaip_cleanout_st_mode(*text, &(stbuf.st_mode), 2);
   if(!(ret & (7 | 64)))
     (*text)[0]= 0;
   if((*text)[0] == 0 || strcmp(*text, "\n") == 0) {
#ifdef Libisofs_with_aaip_acL
     acl_free(*text);
#else
     free(*text);
#endif
     *text= NULL;
     return(2);
   }
 }
 return(1);
}
Example #8
0
File: cert.c Project: jelmer/cups
void
cupsdAddCert(int        pid,		/* I - Process ID */
             const char *username,	/* I - Username */
             int        type)		/* I - AuthType for username */
{
  int		i;			/* Looping var */
  cupsd_cert_t	*cert;			/* Current certificate */
  int		fd;			/* Certificate file */
  char		filename[1024];		/* Certificate filename */
  static const char hex[] = "0123456789ABCDEF";
					/* Hex constants... */


  cupsdLogMessage(CUPSD_LOG_DEBUG2,
                  "cupsdAddCert: Adding certificate for PID %d", pid);

 /*
  * Allocate memory for the certificate...
  */

  if ((cert = calloc(sizeof(cupsd_cert_t), 1)) == NULL)
    return;

 /*
  * Fill in the certificate information...
  */

  cert->pid  = pid;
  cert->type = type;
  strlcpy(cert->username, username, sizeof(cert->username));

  for (i = 0; i < 32; i ++)
    cert->certificate[i] = hex[CUPS_RAND() & 15];

 /*
  * Save the certificate to a file readable only by the User and Group
  * (or root and SystemGroup for PID == 0)...
  */

  snprintf(filename, sizeof(filename), "%s/certs/%d", StateDir, pid);
  unlink(filename);

  if ((fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0)
  {
    cupsdLogMessage(CUPSD_LOG_ERROR,
                    "Unable to create certificate file %s - %s",
                    filename, strerror(errno));
    free(cert);
    return;
  }

  if (pid == 0)
  {
#ifdef HAVE_ACL_INIT
    acl_t		acl;		/* ACL information */
    acl_entry_t		entry;		/* ACL entry */
    acl_permset_t	permset;	/* Permissions */
#  ifdef HAVE_MBR_UID_TO_UUID
    uuid_t		group;		/* Group ID */
#  endif /* HAVE_MBR_UID_TO_UUID */
    static int		acls_not_supported = 0;
					/* Only warn once */
#endif /* HAVE_ACL_INIT */


   /*
    * Root certificate...
    */

    fchmod(fd, 0440);
    fchown(fd, RunUser, SystemGroupIDs[0]);

    cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddCert: NumSystemGroups=%d",
                    NumSystemGroups);

#ifdef HAVE_ACL_INIT
    if (NumSystemGroups > 1)
    {
     /*
      * Set POSIX ACLs for the root certificate so that all system
      * groups can access it...
      */

      int	j;			/* Looping var */

#  ifdef HAVE_MBR_UID_TO_UUID
     /*
      * On MacOS X, ACLs use UUIDs instead of GIDs...
      */

      acl = acl_init(NumSystemGroups - 1);

      for (i = 1; i < NumSystemGroups; i ++)
      {
       /*
        * Add each group ID to the ACL...
	*/

        for (j = 0; j < i; j ++)
	  if (SystemGroupIDs[j] == SystemGroupIDs[i])
            break;

        if (j < i)
          continue;			/* Skip duplicate groups */

        acl_create_entry(&acl, &entry);
	acl_get_permset(entry, &permset);
	acl_add_perm(permset, ACL_READ_DATA);
	acl_set_tag_type(entry, ACL_EXTENDED_ALLOW);
	mbr_gid_to_uuid((gid_t)SystemGroupIDs[i], group);
	acl_set_qualifier(entry, &group);
	acl_set_permset(entry, permset);
      }

#  else
     /*
      * POSIX ACLs need permissions for owner, group, other, and mask
      * in addition to the rest of the system groups...
      */

      acl = acl_init(NumSystemGroups + 3);

      /* Owner */
      acl_create_entry(&acl, &entry);
      acl_get_permset(entry, &permset);
      acl_add_perm(permset, ACL_READ);
      acl_set_tag_type(entry, ACL_USER_OBJ);
      acl_set_permset(entry, permset);

      /* Group */
      acl_create_entry(&acl, &entry);
      acl_get_permset(entry, &permset);
      acl_add_perm(permset, ACL_READ);
      acl_set_tag_type(entry, ACL_GROUP_OBJ);
      acl_set_permset(entry, permset);

      /* Others */
      acl_create_entry(&acl, &entry);
      acl_get_permset(entry, &permset);
      acl_add_perm(permset, 0);
      acl_set_tag_type(entry, ACL_OTHER);
      acl_set_permset(entry, permset);

      /* Mask */
      acl_create_entry(&acl, &entry);
      acl_get_permset(entry, &permset);
      acl_add_perm(permset, ACL_READ);
      acl_set_tag_type(entry, ACL_MASK);
      acl_set_permset(entry, permset);

      for (i = 1; i < NumSystemGroups; i ++)
      {
       /*
        * Add each group ID to the ACL...
	*/

        for (j = 0; j < i; j ++)
	  if (SystemGroupIDs[j] == SystemGroupIDs[i])
            break;

        if (j < i)
          continue;			/* Skip duplicate groups */

        acl_create_entry(&acl, &entry);
	acl_get_permset(entry, &permset);
	acl_add_perm(permset, ACL_READ);
	acl_set_tag_type(entry, ACL_GROUP);
	acl_set_qualifier(entry, SystemGroupIDs + i);
	acl_set_permset(entry, permset);
      }

      if (acl_valid(acl))
      {
        char *text, *textptr;		/* Temporary string */

        cupsdLogMessage(CUPSD_LOG_ERROR, "ACL did not validate: %s",
	                strerror(errno));
        text = acl_to_text(acl, NULL);
	for (textptr = strchr(text, '\n');
	     textptr;
	     textptr = strchr(textptr + 1, '\n'))
	  *textptr = ',';

	cupsdLogMessage(CUPSD_LOG_ERROR, "ACL: %s", text);
	acl_free(text);
      }
#  endif /* HAVE_MBR_UID_TO_UUID */

      if (acl_set_fd(fd, acl))
      {
	if (errno != EOPNOTSUPP || !acls_not_supported)
	  cupsdLogMessage(CUPSD_LOG_ERROR,
			  "Unable to set ACLs on root certificate \"%s\" - %s",
			  filename, strerror(errno));

	if (errno == EOPNOTSUPP)
	  acls_not_supported = 1;
      }

      acl_free(acl);
    }
#endif /* HAVE_ACL_INIT */

    RootCertTime = time(NULL);
  }
  else
  {
   /*
    * CGI certificate...
    */

    fchmod(fd, 0400);
    fchown(fd, User, Group);
  }

  DEBUG_printf(("ADD pid=%d, username=%s, cert=%s\n", pid, username,
                cert->certificate));

  write(fd, cert->certificate, strlen(cert->certificate));
  close(fd);

 /*
  * Insert the certificate at the front of the list...
  */

  cert->next = Certs;
  Certs      = cert;
}
Example #9
0
int
modify_file_acl(unsigned int optflags, const char *path, acl_t modifier, int position, int inheritance_level, int follow) {
	
	acl_t oacl = NULL;
	unsigned aindex  = 0, flag_new_acl = 0;
	acl_entry_t newent = NULL;
	acl_entry_t entry = NULL;
	unsigned retval = 0;

	extern int chmod_fflag;

/* XXX acl_get_file() returns a zero entry ACL if an ACL was previously
 * associated with the file, and has had its entries removed.
 * However, POSIX 1003.1e states that a zero entry ACL should be 
 * returned if the caller asks for ACL_TYPE_DEFAULT, and no ACL is 
 * associated with the path; it
 * does not specifically state that a request for ACL_TYPE_EXTENDED
 * should not return a zero entry ACL, however.
 */

/* Determine if we've been given a zero entry ACL, or create an ACL if 
 * none exists. There are some issues to consider here: Should we create
 * a zero-entry ACL for a delete or check canonicity operation?
 */

	if (path == NULL)
		chmod_usage();

	if (optflags & ACL_CLEAR_FLAG) {
		filesec_t fsec = filesec_init();
		if (fsec == NULL) {
			// err(1, "filesec_init() failed");
            fprintf(stderr, "chmod: filesec_init() failed: %s\n", strerror(errno));
            pthread_exit(NULL);
		}
		if (filesec_set_property(fsec, FILESEC_ACL, _FILESEC_REMOVE_ACL) != 0) {
            // err(1, "filesec_set_property() failed");
            fprintf(stderr, "chmod: filesec_set_property() failed: %s\n", strerror(errno));
            pthread_exit(NULL);
                }
		if (follow) {
			if (chmodx_np(path, fsec) != 0) {
                if (!chmod_fflag) {
					// warn("Failed to clear ACL on file %s", path);
                    fprintf(stderr, "chmod: Failed to clear ACL on file %s: %s\n", path, strerror(errno));
				}
				retval = 1;
			}
		} else {
			int fd = open(path, O_SYMLINK);
			if (fd != -1) {
				if (fchmodx_np(fd, fsec) != 0) {
					if (!chmod_fflag) {
                        fprintf(stderr, "chmod: Failed to clear ACL on file %s: %s\n", path, strerror(errno));
                        // warn("Failed to clear ACL on file %s", path);
					}
					retval = 1;
				}
				close(fd);
			} else {
				if (!chmod_fflag) {
					// warn("Failed to open file %s", path);
                    fprintf(stderr, "chmod: Failed to open file %s: %s\n", path, strerror(errno));
				}
				retval = 1;
			}
		}
		filesec_free(fsec);
		return (retval);
	}

	if (optflags & ACL_FROM_STDIN) {
		oacl = acl_dup(modifier);
	} else {
		if (follow) {
			oacl = acl_get_file(path, ACL_TYPE_EXTENDED);
		} else {
			int fd = open(path, O_SYMLINK);
			if (fd != -1) {
				oacl = acl_get_fd_np(fd, ACL_TYPE_EXTENDED);
				close(fd);
			}
		}
		if ((oacl == NULL) ||
		    (acl_get_entry(oacl,ACL_FIRST_ENTRY, &newent) != 0)) {
            if ((oacl = acl_init(1)) == NULL) {
				// err(1, "acl_init() failed");
                fprintf(stderr, "chmod: acl_init() failed: %s\n", strerror(errno));
                pthread_exit(NULL);
            }
			flag_new_acl = 1;
			position = 0;
		}
	
		if ((0 == flag_new_acl) && (optflags & (ACL_REMOVE_INHERIT_FLAG | 
							ACL_REMOVE_INHERITED_ENTRIES))) {
			acl_t facl = NULL;
            if ((facl = acl_init(1)) == NULL) {
				//err(1, "acl_init() failed");
                fprintf(stderr, "chmod: acl_init() failed: %s\n", strerror(errno));
                pthread_exit(NULL);
            }
			for (aindex = 0; 
			     acl_get_entry(oacl, 
					   (entry == NULL ? ACL_FIRST_ENTRY : 
					    ACL_NEXT_ENTRY), &entry) == 0; 
			     aindex++) {
				acl_flagset_t eflags;
				acl_entry_t fent = NULL;
				if (acl_get_flagset_np(entry, &eflags) != 0) {
                    fprintf(stderr,  "chmod: Unable to obtain flagset: %s\n", strerror(errno));
                    pthread_exit(NULL);
                    // err(1, "Unable to obtain flagset");
				}
				
				if (acl_get_flag_np(eflags, ACL_ENTRY_INHERITED)) {
					if (optflags & ACL_REMOVE_INHERIT_FLAG) {
						acl_delete_flag_np(eflags, ACL_ENTRY_INHERITED);
						acl_set_flagset_np(entry, eflags);
						acl_create_entry(&facl, &fent);
						acl_copy_entry(fent, entry);
					}
				}
				else {
					acl_create_entry(&facl, &fent);
					acl_copy_entry(fent, entry);
				}
			}
			if (oacl)
				acl_free(oacl);
			oacl = facl;
		} else if (optflags & ACL_TO_STDOUT) {
			ssize_t len; /* need to get printacl() from ls(1) */
			char *text = acl_to_text(oacl, &len);
			puts(text);
			acl_free(text);
		} else if (optflags & ACL_CHECK_CANONICITY) {
			if (flag_new_acl) {
				// warnx("No ACL currently associated with file '%s'", path);
                fprintf(stderr, "chmod: No ACL currently associated with file '%s'\n", path);
			}
			retval = is_canonical(oacl);
		} else if ((optflags & ACL_SET_FLAG) && (position == -1) && 
		    (!is_canonical(oacl))) {
			// warnx("The specified file '%s' does not have an ACL in canonical order, please specify a position with +a# ", path);
            fprintf(stderr, "chmod: The specified file '%s' does not have an ACL in canonical order, please specify a position with +a# \n", path);
			retval = 1;
		} else if (((optflags & ACL_DELETE_FLAG) && (position != -1))
		    || (optflags & ACL_CHECK_CANONICITY)) {
			retval = modify_acl(&oacl, NULL, optflags, position, 
					    inheritance_level, flag_new_acl, path);
		} else if ((optflags & (ACL_REMOVE_INHERIT_FLAG|ACL_REMOVE_INHERITED_ENTRIES)) && flag_new_acl) {
			// warnx("No ACL currently associated with file '%s'", path);
            fprintf(stderr, "chmod: No ACL currently associated with file '%s'\n", path);
			retval = 1;
		} else {
			if (!modifier) { /* avoid bus error in acl_get_entry */
				// errx(1, "Internal error: modifier should not be NULL");
                fprintf(stderr, "Internal error: modifier should not be NULL\n");
                pthread_exit(NULL);
			}
			for (aindex = 0; 
			     acl_get_entry(modifier, 
					   (entry == NULL ? ACL_FIRST_ENTRY : 
					    ACL_NEXT_ENTRY), &entry) == 0; 
			     aindex++) {

				retval += modify_acl(&oacl, entry, optflags, 
						     position, inheritance_level, 
						     flag_new_acl, path);
			}
		}
	}

/* XXX Potential race here, since someone else could've modified or
 * read the ACL on this file (with the intention of modifying it) in
 * the interval from acl_get_file() to acl_set_file(); we can
 * minimize one aspect of this  window by comparing the original acl
 * to a fresh one from acl_get_file() but we could consider a
 * "changeset" mechanism, common locking  strategy, or kernel
 * supplied reservation mechanism to prevent this race.
 */
	if (!(optflags & (ACL_TO_STDOUT|ACL_CHECK_CANONICITY))) {
		int status = -1;
		if (follow) {
	    		status = acl_set_file(path, ACL_TYPE_EXTENDED, oacl);
		} else {
			int fd = open(path, O_SYMLINK);
			if (fd != -1) {
				status = acl_set_fd_np(fd, oacl,
							ACL_TYPE_EXTENDED);
				close(fd);
			}
		}
		if (status != 0) {
			if (!chmod_fflag)
                fprintf(stderr, "chmod: Failed to set ACL on file '%s': %s\n", path, strerror(errno));
            // warn("Failed to set ACL on file '%s'", path);
			retval = 1;
		}
	}
	
	if (oacl)
		acl_free(oacl);
	
	return retval;
}
Example #10
0
static int32_t aacls(xar_file_t f, const char *file) {
#ifdef HAVE_SYS_ACL_H
#if !defined(__APPLE__)
	acl_t a;
	const char *type;

	xar_prop_get(f, "type", &type);
	if( !type || (strcmp(type, "symlink") == 0) )
		return 0;

	a = acl_get_file(file, ACL_TYPE_DEFAULT);
	if( a ) {
		char *t;
		acl_entry_t e;

		/* If the acl is empty, or not valid, skip it */
		if( acl_get_entry(a, ACL_FIRST_ENTRY, &e) != 1 )
			goto NEXT;

		t = acl_to_text(a, NULL);
		if( t ) {
			xar_prop_set(f, "acl/default", t);
			acl_free(t);
		}
		acl_free(a);
	}
NEXT:

	a = acl_get_file(file, ACL_TYPE_ACCESS);
	if( a ) {
		char *t;
		acl_entry_t e;

		/* If the acl is empty, or not valid, skip it */
		if( acl_get_entry(a, ACL_FIRST_ENTRY, &e) != 1 )
			goto DONE;

		t = acl_to_text(a, NULL);
		if( t ) {
			xar_prop_set(f, "acl/access", t);
			acl_free(t);
		}
		acl_free(a);
	}
DONE:
#else /* !__AAPLE__ */
	acl_entry_t e = NULL;
	acl_t a;
	int i;

	a = acl_get_file(file, ACL_TYPE_EXTENDED);
	if( !a )
		return 0;

	for( i = 0; acl_get_entry(a, e == NULL ? ACL_FIRST_ENTRY : ACL_NEXT_ENTRY, &e) == 0; i++ ) {
		char *t;
		t = acl_to_text(a, NULL);
		if( t ) {
			xar_prop_set(f, "acl/appleextended", t);
			acl_free(t);
		}
		
	}
	acl_free(a);
#endif /* !__APPLE__ */
#endif
	return 0;
}