Beispiel #1
0
int calc_acl_mask_if_needed(acl_t *acl_p) {
        acl_entry_t i;
        int r;

        assert(acl_p);

        for (r = acl_get_entry(*acl_p, ACL_FIRST_ENTRY, &i);
             r > 0;
             r = acl_get_entry(*acl_p, ACL_NEXT_ENTRY, &i)) {
                acl_tag_t tag;

                if (acl_get_tag_type(i, &tag) < 0)
                        return -errno;

                if (tag == ACL_MASK)
                        return 0;
                if (IN_SET(tag, ACL_USER, ACL_GROUP))
                        goto calc;
        }
        if (r < 0)
                return -errno;
        return 0;

calc:
        if (acl_calc_mask(acl_p) < 0)
                return -errno;
        return 1;
}
Beispiel #2
0
/* Iterate through an ACL, and find the canonical position for the
 * specified entry 
 */
unsigned int
find_canonical_position(acl_t acl, acl_entry_t modifier) {

	acl_entry_t entry;
	int mscore = 0;
	unsigned mpos = 0;

	/* Check if there's an entry with the same qualifier
	 * and tag type; if not, find the appropriate slot
	 * for the score.
	 */

	if (0 != acl_get_entry(acl, ACL_FIRST_ENTRY, &entry))
		return 0;

	mscore = score_acl_entry(modifier);

	while (mscore < score_acl_entry(entry)) {

		mpos++;

	       if (0 != acl_get_entry(acl, ACL_NEXT_ENTRY, &entry))
		       break;

	       }
	return mpos;
}
/* 
 *   deletes an access acl or directory default acl if one exists
 */ 
static int 
acl_delete_file(const char *path, acl_type_t type)
{
	int error = 0;

	/* converts access ACL to a minimal ACL */
	if (type == ACL_TYPE_ACCESS) {
		acl_t acl;
		acl_entry_t entry;
		acl_tag_t tag;

		acl = acl_get_file(path, ACL_TYPE_ACCESS);
		if (!acl)
			return -1;
		error = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
		while (error == 1) {
			acl_get_tag_type(entry, &tag);
			switch(tag) {
				case ACL_USER:
				case ACL_GROUP:
				case ACL_MASK:
					acl_delete_entry(acl, entry);
					break;
			 }
			error = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
		}
		if (!error)
			error = acl_set_file(path, ACL_TYPE_ACCESS, acl);
	} else
		error = acl_delete_def_file(path);
	return(error);
}
Beispiel #4
0
static int flush_acl(acl_t acl) {
        acl_entry_t i;
        int found;
        bool changed = false;

        assert(acl);

        for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
             found > 0;
             found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {

                acl_tag_t tag;

                if (acl_get_tag_type(i, &tag) < 0)
                        return -errno;

                if (tag != ACL_USER)
                        continue;

                if (acl_delete_entry(acl, i) < 0)
                        return -errno;

                changed = true;
        }

        if (found < 0)
                return -errno;

        return changed;
}
Beispiel #5
0
struct name_list *get_list(const struct stat *st, acl_t acl)
{
	struct name_list *first = NULL, *last = NULL;
	acl_entry_t ent;
	int ret = 0;

	if (acl != NULL)
		ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &ent);
	if (ret != 1)
		return NULL;
	while (ret > 0) {
		acl_tag_t e_type;
		const id_t *id_p;
		const char *name = "";
		int len;

		acl_get_tag_type(ent, &e_type);
		switch(e_type) {
			case ACL_USER_OBJ:
				name = user_name(st->st_uid, opt_numeric);
				break;

			case ACL_USER:
				id_p = acl_get_qualifier(ent);
				if (id_p != NULL)
					name = user_name(*id_p, opt_numeric);
				break;

			case ACL_GROUP_OBJ:
				name = group_name(st->st_gid, opt_numeric);
				break;

			case ACL_GROUP:
				id_p = acl_get_qualifier(ent);
				if (id_p != NULL)
					name = group_name(*id_p, opt_numeric);
				break;
		}
		name = xquote(name, "\t\n\r");
		len = strlen(name);
		if (last == NULL) {
			first = last = (struct name_list *)
				malloc(sizeof(struct name_list) + len + 1);
		} else {
			last->next = (struct name_list *)
				malloc(sizeof(struct name_list) + len + 1);
			last = last->next;
		}
		if (last == NULL) {
			free_list(first);
			return NULL;
		}
		last->next = NULL;
		strcpy(last->name, name);

		ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &ent);
	}
	return first;
}
/*
 * Translate POSIX.1e ACL into libarchive internal structure.
 */
static void
setup_acl_posix1e(struct archive_read_disk *a,
    struct archive_entry *entry, acl_t acl, int archive_entry_acl_type)
{
	acl_tag_t	 acl_tag;
	acl_entry_t	 acl_entry;
	acl_permset_t	 acl_permset;
	int		 s, ae_id, ae_tag, ae_perm;
	const char	*ae_name;

	s = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
	while (s == 1) {
		ae_id = -1;
		ae_name = NULL;

		acl_get_tag_type(acl_entry, &acl_tag);
		if (acl_tag == ACL_USER) {
			ae_id = (int)*(uid_t *)acl_get_qualifier(acl_entry);
			ae_name = archive_read_disk_uname(&a->archive, ae_id);
			ae_tag = ARCHIVE_ENTRY_ACL_USER;
		} else if (acl_tag == ACL_GROUP) {
			ae_id = (int)*(gid_t *)acl_get_qualifier(acl_entry);
			ae_name = archive_read_disk_gname(&a->archive, ae_id);
			ae_tag = ARCHIVE_ENTRY_ACL_GROUP;
		} else if (acl_tag == ACL_MASK) {
			ae_tag = ARCHIVE_ENTRY_ACL_MASK;
		} else if (acl_tag == ACL_USER_OBJ) {
			ae_tag = ARCHIVE_ENTRY_ACL_USER_OBJ;
		} else if (acl_tag == ACL_GROUP_OBJ) {
			ae_tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ;
		} else if (acl_tag == ACL_OTHER) {
			ae_tag = ARCHIVE_ENTRY_ACL_OTHER;
		} else {
			/* Skip types that libarchive can't support. */
			continue;
		}

		acl_get_permset(acl_entry, &acl_permset);
		ae_perm = 0;
		/*
		 * acl_get_perm() is spelled differently on different
		 * platforms; see above.
		 */
		if (ACL_GET_PERM(acl_permset, ACL_EXECUTE))
			ae_perm |= ARCHIVE_ENTRY_ACL_EXECUTE;
		if (ACL_GET_PERM(acl_permset, ACL_READ))
			ae_perm |= ARCHIVE_ENTRY_ACL_READ;
		if (ACL_GET_PERM(acl_permset, ACL_WRITE))
			ae_perm |= ARCHIVE_ENTRY_ACL_WRITE;

		archive_entry_acl_add_entry(entry,
		    archive_entry_acl_type, ae_perm, ae_tag,
		    ae_id, ae_name);

		s = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
	}
}
Beispiel #7
0
int search_acl_groups(char*** dst, const char* path, bool* belong) {
        acl_t acl;

        assert(path);
        assert(belong);

        acl = acl_get_file(path, ACL_TYPE_DEFAULT);
        if (acl) {
                acl_entry_t entry;
                int r;

                r = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
                while (r > 0) {
                        acl_tag_t tag;
                        gid_t *gid;
                        char *name;

                        r = acl_get_tag_type(entry, &tag);
                        if (r < 0)
                                break;

                        if (tag != ACL_GROUP)
                                goto next;

                        gid = acl_get_qualifier(entry);
                        if (!gid)
                                break;

                        if (in_gid(*gid) > 0) {
                                *belong = true;
                                break;
                        }

                        name = gid_to_name(*gid);
                        if (!name) {
                                acl_free(acl);
                                return log_oom();
                        }

                        r = strv_consume(dst, name);
                        if (r < 0) {
                                acl_free(acl);
                                return log_oom();
                        }

                next:
                        r = acl_get_entry(acl, ACL_NEXT_ENTRY, &entry);
                }

                acl_free(acl);
        }

        return 0;
}
Beispiel #8
0
static int
remove_extended_entries(
	acl_t acl)
{
	acl_entry_t ent, group_obj;
	acl_permset_t mask_permset, group_obj_permset;
	acl_tag_t tag;
	int error;
	
	/*
	 * Removing the ACL_MASK entry from the ACL results in
	 * increased permissions for the owning group if the
	 * ACL_GROUP_OBJ entry contains permissions not contained
	 * in the ACL_MASK entry. We remove these permissions from
	 * the ACL_GROUP_OBJ entry to avoid that.
	 *
	 * After removing the ACL, the file owner and the owning group
	 * therefore have the same permissions as before.
	 */

	ent = find_entry(acl, ACL_MASK, ACL_UNDEFINED_ID);
	group_obj = find_entry(acl, ACL_GROUP_OBJ, ACL_UNDEFINED_ID);
	if (ent && group_obj) {
		if (!acl_get_permset(ent, &mask_permset) &&
		    !acl_get_permset(group_obj, &group_obj_permset)) {
			if (!acl_get_perm(mask_permset, ACL_READ))
				acl_delete_perm(group_obj_permset, ACL_READ);
			if (!acl_get_perm(mask_permset, ACL_WRITE))
				acl_delete_perm(group_obj_permset, ACL_WRITE);
			if (!acl_get_perm(mask_permset, ACL_EXECUTE))
				acl_delete_perm(group_obj_permset, ACL_EXECUTE);
		}
	}

	error = acl_get_entry(acl, ACL_FIRST_ENTRY, &ent);
	while (error == 1) {
		acl_get_tag_type(ent, &tag);
		switch(tag) {
			case ACL_USER:
			case ACL_GROUP:
			case ACL_MASK:
				acl_delete_entry(acl, ent);
				break;
			default:
				break;
		}
	
		error = acl_get_entry(acl, ACL_NEXT_ENTRY, &ent);
	}
	if (error < 0)
		return -1;
	return 0;
}
Beispiel #9
0
/* only directories can have inherit flags set */
static int
remove_inherit_flags(acl_t *acl)
{
	int entry_id;
	acl_entry_t acl_entry;
	acl_flagset_t acl_flags;

	entry_id = ACL_FIRST_ENTRY;
	while (acl_get_entry(*acl, entry_id, &acl_entry) > 0) {
		entry_id = ACL_NEXT_ENTRY;

		if (acl_get_flagset_np(acl_entry, &acl_flags) < 0)
			err(EX_OSERR, "acl_get_flagset_np() failed");

		acl_delete_flag_np(acl_flags, ACL_ENTRY_FILE_INHERIT);
		acl_delete_flag_np(acl_flags, ACL_ENTRY_DIRECTORY_INHERIT);
		acl_delete_flag_np(acl_flags, ACL_ENTRY_NO_PROPAGATE_INHERIT);
		acl_delete_flag_np(acl_flags, ACL_ENTRY_INHERIT_ONLY);

		if (acl_set_flagset_np(acl_entry, acl_flags) < 0)
			err(EX_OSERR, "acl_set_flagset_np() failed");
	}

	return (0);
}
Beispiel #10
0
static struct smb_acl_t *smb_acl_to_internal(acl_t acl)
{
	struct smb_acl_t *result = SMB_MALLOC_P(struct smb_acl_t);
	int entry_id = ACL_FIRST_ENTRY;
	acl_entry_t e;
	if (result == NULL) {
		return NULL;
	}
	ZERO_STRUCTP(result);
	while (acl_get_entry(acl, entry_id, &e) == 1) {

		entry_id = ACL_NEXT_ENTRY;

		result = (struct smb_acl_t *)SMB_REALLOC(
			result, sizeof(struct smb_acl_t) +
			(sizeof(struct smb_acl_entry) * (result->count+1)));
		if (result == NULL) {
			DEBUG(0, ("SMB_REALLOC failed\n"));
			errno = ENOMEM;
			return NULL;
		}

		if (!smb_ace_to_internal(e, &result->acl[result->count])) {
			SAFE_FREE(result);
			return NULL;
		}

		result->count += 1;
	}
	return result;
}
Beispiel #11
0
char		get_acl(char *filename)
{
	acl_t		acl;
	acl_entry_t	dummy;
	ssize_t		xattr;
	char		str[10];

	xattr = 0;
	acl = NULL;
	acl = acl_get_link_np(filename, ACL_TYPE_EXTENDED);
	if (acl && acl_get_entry(acl, ACL_FIRST_ENTRY, &dummy) == -1)
	{
		acl_free(acl);
		acl = NULL;
	}
	xattr = listxattr(filename, NULL, 0, XATTR_NOFOLLOW);
	if (xattr < 0)
		xattr = 0;
	str[1] = '\0';
	if (xattr > 0)
		str[0] = '@';
	else if (acl)
		str[0] = '+';
	else
		str[0] = ' ';
	return (str[0]);
}
Beispiel #12
0
static struct smb_acl_t *smb_acl_to_internal(acl_t acl, TALLOC_CTX *mem_ctx)
{
	struct smb_acl_t *result = sys_acl_init(mem_ctx);
	int entry_id = ACL_FIRST_ENTRY;
	acl_entry_t e;
	if (result == NULL) {
		return NULL;
	}
	while (acl_get_entry(acl, entry_id, &e) == 1) {

		entry_id = ACL_NEXT_ENTRY;

		result->acl = talloc_realloc(result, result->acl,
					     struct smb_acl_entry, result->count+1);
		if (result->acl == NULL) {
			TALLOC_FREE(result);
			DEBUG(0, ("talloc_realloc failed\n"));
			errno = ENOMEM;
			return NULL;
		}

		if (!smb_ace_to_internal(e, &result->acl[result->count])) {
			TALLOC_FREE(result);
			return NULL;
		}

		result->count += 1;
	}
	return result;
}
Beispiel #13
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
}
Beispiel #14
0
int
acl_entries (acl_t acl)
{
  int count = 0;

  if (acl != NULL)
    {
#if HAVE_ACL_FIRST_ENTRY /* Linux, FreeBSD, Mac OS X */
# if HAVE_ACL_TYPE_EXTENDED /* Mac OS X */
      /* acl_get_entry returns 0 when it successfully fetches an entry,
         and -1/EINVAL at the end.  */
      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))
        count++;
# else /* Linux, FreeBSD */
      /* acl_get_entry returns 1 when it successfully fetches an entry,
         and 0 at the end.  */
      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))
        count++;
      if (got_one < 0)
        return -1;
# endif
#else /* IRIX, Tru64 */
# if HAVE_ACL_TO_SHORT_TEXT /* IRIX */
      /* Don't use acl_get_entry: it is undocumented.  */
      count = acl->acl_cnt;
# endif
# if HAVE_ACL_FREE_TEXT /* Tru64 */
      /* Don't use acl_get_entry: it takes only one argument and does not
         work.  */
      count = acl->acl_num;
# endif
#endif
    }

  return count;
}
Beispiel #15
0
int getacl(const char *pathp, aclent_t *aclpbuf)
{
	acl_t acl = NULL, default_acl = NULL;	
	struct stat st;
	
	if (stat(pathp, &st) != 0) {
		return -1;
	}
		
	acl = acl_get_file(pathp, ACL_TYPE_ACCESS);
	if(acl == NULL && (errno == ENOSYS || errno == ENOTSUP)) {
		acl = acl_from_mode(st.st_mode);
		if (acl == NULL) {
			return -1;
		}
	}	
	
	if (S_ISDIR(st.st_mode)) {
		default_acl = acl_get_file(pathp, ACL_TYPE_DEFAULT);
		if ((default_acl != NULL) && (acl_entries(default_acl) == 0)) {
			acl_free(default_acl);
			default_acl = NULL;
		} 
	}
	
	acl_entry_t acl_entry;
	int ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry);
	int i = 0;
	while(ret > 0) {
		aclpbuf[i++] = getentry(acl_entry, st, 0);
		ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry);
	}
	acl_free(acl);
	
	if((default_acl != NULL) && (ret != -1)) {
		ret = acl_get_entry(default_acl, ACL_FIRST_ENTRY, &acl_entry);
		while(ret > 0) {			
			aclpbuf[i++] = getentry(acl_entry, st, ACL_DEFAULT);
			ret = acl_get_entry(default_acl, ACL_NEXT_ENTRY, &acl_entry);
		}
		acl_free(default_acl);
	}
	
	return i;
}
Beispiel #16
0
static int
acl_entries(acl_t acl)
{
# if defined(HAVE_ACL_GET_ENTRY)
	/* POSIX 1003.1e draft 17 (abandoned) compatible version.  */
	acl_entry_t entry;
	int entries = 0;

	int entries = acl_get_entry(acl, ACL_FIRST_ENTRY, &entry);
	if (entries > 0) {
		while (acl_get_entry(acl, ACL_NEXT_ENTRY, &entry) > 0)
			entries++;
	}
	return entries;
# else
	return -1;
# endif
}
Beispiel #17
0
void acl_mask_perm_str(acl_t acl, char *str)
{
	acl_entry_t entry;

	str[0] = '\0';
	if (acl_get_entry(acl, ACL_FIRST_ENTRY, &entry) != 1)
		return;
	for(;;) {
		acl_tag_t tag;

		acl_get_tag_type(entry, &tag);
		if (tag == ACL_MASK) {
			acl_perm_str(entry, str);
			return;
		}
		if (acl_get_entry(acl, ACL_NEXT_ENTRY, &entry) != 1)
			return;
	}
}
Beispiel #18
0
int
add_acl(acl_t acl, uint entry_number, acl_t *prev_acl, const char *filename)
{
	acl_entry_t entry, entry_new;
	acl_t acl_new;
	int entry_id, acl_brand, prev_acl_brand;

	acl_get_brand_np(acl, &acl_brand);
	acl_get_brand_np(*prev_acl, &prev_acl_brand);

	if (prev_acl_brand != ACL_BRAND_NFS4) {
		warnx("%s: the '-a' option is only applicable to NFSv4 ACLs",
		    filename);
		return (-1);
	}

	if (branding_mismatch(acl_brand, ACL_BRAND_NFS4)) {
		warnx("%s: branding mismatch; existing ACL is NFSv4, "
		    "entry to be added is %s", filename,
		    brand_name(acl_brand));
		return (-1);
	}

	acl_new = acl_dup(*prev_acl);
	if (acl_new == NULL)
		err(1, "%s: acl_dup() failed", filename);

	entry_id = ACL_FIRST_ENTRY;

	while (acl_get_entry(acl, entry_id, &entry) == 1) {
		entry_id = ACL_NEXT_ENTRY;

		if (acl_create_entry_np(&acl_new, &entry_new, entry_number) == -1) {
			warn("%s: acl_create_entry_np() failed", filename); 
			acl_free(acl_new);
			return (-1);
		}

		/*
		 * Without this increment, adding several
		 * entries at once, for example
		 * "setfacl -m user:1:r:allow,user:2:r:allow",
		 * would make them appear in reverse order.
		 */
		entry_number++;

		if (acl_copy_entry(entry_new, entry) == -1)
			err(1, "%s: acl_copy_entry() failed", filename);
	}

	acl_free(*prev_acl);
	*prev_acl = acl_new;

	return (0);
}
Beispiel #19
0
static acl_entry_t
findEntry(acl_t acl, acl_tag_t tag, id_t qaul)
{
    acl_entry_t entry;
    acl_tag_t entryTag;
    uid_t *uidp;
    gid_t *gidp;
    int ent, s;

    for (ent = ACL_FIRST_ENTRY; ; ent = ACL_NEXT_ENTRY) {
        s = acl_get_entry(acl, ent, &entry);
        if (s == -1)
            errExit("acl_get_entry");

        if (s == 0)
            return NULL;

        if (acl_get_tag_type(entry, &entryTag) == -1)
            errExit("acl_get_tag_type");

        if (tag == entryTag) {
            if (tag == ACL_USER) {
                uidp = acl_get_qualifier(entry);
                if (uidp == NULL)
                    errExit("acl_get_qualifier");

                if (qaul == *uidp) {
                    if (acl_free(uidp) == -1)
                        errExit("acl_free");
                    return entry;
                } else {
                    if (acl_free(uidp) == -1)
                        errExit("acl_free");
                }

            } else if (tag == ACL_GROUP) {
                gidp = acl_get_qualifier(entry);
                if (gidp == NULL)
                    errExit("acl_get_qualifier");

                if (qaul == *gidp) {
                    if (acl_free(gidp) == -1)
                        errExit("acl_free");
                    return entry;
                } else {
                    if (acl_free(gidp) == -1)
                        errExit("acl_free");
                }

            } else {
                return entry;
            }
        }
    }
}
Beispiel #20
0
static void
compare_acls(acl_t acl, struct myacl_t *myacls)
{
	int *marker;
	int entry_id = ACL_FIRST_ENTRY;
	int matched;
	int i, n;
	acl_entry_t acl_entry;

	/* Count ACL entries in myacls array and allocate an indirect array. */
	for (n = 0; myacls[n].name != NULL; ++n)
		continue;
	if (n) {
		marker = malloc(sizeof(marker[0]) * n);
		if (marker == NULL)
			return;
		for (i = 0; i < n; i++)
			marker[i] = i;
	} else
		marker = NULL;

	/*
	 * Iterate over acls in system acl object, try to match each
	 * one with an item in the myacls array.
	 */
	while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
		/* After the first time... */
		entry_id = ACL_NEXT_ENTRY;

		/* Search for a matching entry (tag and qualifier) */
		for (i = 0, matched = 0; i < n && !matched; i++) {
			if (acl_match(acl_entry, &myacls[marker[i]])) {
				/* We found a match; remove it. */
				marker[i] = marker[n - 1];
				n--;
				matched = 1;
			}
		}

		/* TODO: Print out more details in this case. */
		failure("ACL entry on file that shouldn't be there");
		assert(matched == 1);
	}

	/* Dump entries in the myacls array that weren't in the system acl. */
	for (i = 0; i < n; ++i) {
		failure(" ACL entry missing from file: "
		    "type=%d,permset=%d,tag=%d,qual=%d,name=``%s''\n",
		    myacls[marker[i]].type, myacls[marker[i]].permset,
		    myacls[marker[i]].tag, myacls[marker[i]].qual,
		    myacls[marker[i]].name);
		assert(0); /* Record this as a failure. */
	}
	free(marker);
}
Beispiel #21
0
int
has_execute_perms(
	acl_t acl)
{
	acl_entry_t ent;

	if (acl_get_entry(acl, ACL_FIRST_ENTRY, &ent) != 1)
		return 0;

	for(;;) {
		acl_permset_t permset;

		acl_get_permset(ent, &permset);
		if (acl_get_perm(permset, ACL_EXECUTE) != 0)
			return 1;

		if (acl_get_entry(acl, ACL_NEXT_ENTRY, &ent) != 1)
			return 0;
	}
}
Beispiel #22
0
/* Verify that an ACL is in canonical order. Currently, the canonical
 * form is:
 * local deny
 * local allow
 * inherited deny (parent)
 * inherited allow (parent)
 * inherited deny (grandparent)
 * inherited allow (grandparent)
 * ...
 */
unsigned int
is_canonical(acl_t acl) {
	
	unsigned aindex;
	acl_entry_t entry;
	int score = 0, next_score = 0;

/* XXX - is a zero entry ACL in canonical form? */	
	if (0 != acl_get_entry(acl, ACL_FIRST_ENTRY, &entry))
		return 1;

	score = score_acl_entry(entry);
	
	for (aindex = 0; acl_get_entry(acl, ACL_NEXT_ENTRY, &entry) == 0;
	     aindex++)	{
		if (score < (next_score = score_acl_entry(entry)))
			return 0;
		score = next_score;
	}
	return 1;
}
static void
compare_acls(acl_t acl, struct myacl_t *myacls, const char *filename, int start, int end)
{
	int *marker;
	int entry_id = ACL_FIRST_ENTRY;
	int matched;
	int i, n;
	acl_entry_t acl_entry;

	n = end - start;
	marker = malloc(sizeof(marker[0]) * (n + 1));
	for (i = 0; i < n; i++)
		marker[i] = i + start;
	/* Always include the first ACE. */
	if (start > 0) {
	  marker[n] = 0;
	  ++n;
	}

	/*
	 * Iterate over acls in system acl object, try to match each
	 * one with an item in the myacls array.
	 */
	while (1 == acl_get_entry(acl, entry_id, &acl_entry)) {
		/* After the first time... */
		entry_id = ACL_NEXT_ENTRY;

		/* Search for a matching entry (tag and qualifier) */
		for (i = 0, matched = 0; i < n && !matched; i++) {
			if (acl_match(acl_entry, &myacls[marker[i]])) {
				/* We found a match; remove it. */
				marker[i] = marker[n - 1];
				n--;
				matched = 1;
			}
		}

		failure("ACL entry on file %s that shouldn't be there", filename);
		assert(matched == 1);
	}

	/* Dump entries in the myacls array that weren't in the system acl. */
	for (i = 0; i < n; ++i) {
		failure(" ACL entry %d missing from %s: "
		    "type=%#010x,permset=%#010x,tag=%d,qual=%d,name=``%s''\n",
		    marker[i], filename,
		    myacls[marker[i]].type, myacls[marker[i]].permset,
		    myacls[marker[i]].tag, myacls[marker[i]].qual,
		    myacls[marker[i]].name);
		assert(0); /* Record this as a failure. */
	}
	free(marker);
}
Beispiel #24
0
/*
 * return true if file has ACLs beyond the traditional Unix owner/group/other ACLs
 */
bool hasacls(File *file)
{
    acl_type_t acl_types[] = { ACL_TYPE_ACCESS, ACL_TYPE_DEFAULT };
    for (int i = 0; i < sizeof(acl_types)/sizeof(acl_types[0]); i++) {
        if (!isdir(file) && acl_types[i] == ACL_TYPE_DEFAULT) continue;

        errno = 0;
        acl_t acl = acl_get_file(file->path, acl_types[i]);
        // XXX is this valid?
        if (!acl) {
            if (errno == EOPNOTSUPP) {
                /* file system does not support ACLs */
                return false;
            }
            errorf("Error getting ACLs for %s: %s\n", file->name, strerror(errno));
            // error = 1;
            break;
        }
        bool extended_found = 0;
        //bool error = 0;
        for (int entry_id = ACL_FIRST_ENTRY; ; entry_id = ACL_NEXT_ENTRY) {
            acl_entry_t entry;
            errno = 0;
            int status = acl_get_entry(acl, entry_id, &entry);
            if (status == -1) {
                errorf("Error getting ACLs for %s: %s\n", file->name, strerror(errno));
                // XXX return -1 or '?' or something
                //error = 1;
                break;
            } else if (status == 0) {
                /* no more ACL entries */
                break;
            }
            acl_tag_t tag_type;
            status = acl_get_tag_type(entry, &tag_type);
            switch (tag_type) {
            case ACL_USER_OBJ: case ACL_GROUP_OBJ: case ACL_OTHER:
                break;
            default:
                extended_found = 1;
                break;
            }
            /* no acl_free_entry? */
            if (extended_found) break;
        }
        acl_free(acl);
        if (extended_found) return 1;
    }

    return 0;
}
Beispiel #25
0
/*
 * remove ACL entries from an ACL
 */
int
remove_acl(acl_t acl, acl_t *prev_acl, const char *filename)
{
	acl_entry_t	entry;
	acl_t		acl_new;
	acl_tag_t	tag;
	int		carried_error, entry_id, acl_brand, prev_acl_brand;

	carried_error = 0;

	acl_get_brand_np(acl, &acl_brand);
	acl_get_brand_np(*prev_acl, &prev_acl_brand);

	if (branding_mismatch(acl_brand, prev_acl_brand)) {
		warnx("%s: branding mismatch; existing ACL is %s, "
		    "entry to be removed is %s", filename,
		    brand_name(prev_acl_brand), brand_name(acl_brand));
		return (-1);
	}

	carried_error = 0;

	acl_new = acl_dup(*prev_acl);
	if (acl_new == NULL)
		err(1, "%s: acl_dup() failed", filename);

	tag = ACL_UNDEFINED_TAG;

	/* find and delete the entry */
	entry_id = ACL_FIRST_ENTRY;
	while (acl_get_entry(acl, entry_id, &entry) == 1) {
		entry_id = ACL_NEXT_ENTRY;
		if (acl_get_tag_type(entry, &tag) == -1)
			err(1, "%s: acl_get_tag_type() failed", filename);
		if (tag == ACL_MASK)
			have_mask++;
		if (acl_delete_entry(acl_new, entry) == -1) {
			carried_error++;
			warnx("%s: cannot remove non-existent ACL entry",
			    filename);
		}
	}

	acl_free(*prev_acl);
	*prev_acl = acl_new;

	if (carried_error)
		return (-1);

	return (0);
}
Beispiel #26
0
int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) {
        acl_entry_t i;
        int r;

        assert(acl);
        assert(entry);

        for (r = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
             r > 0;
             r = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {

                acl_tag_t tag;
                uid_t *u;
                bool b;

                if (acl_get_tag_type(i, &tag) < 0)
                        return -errno;

                if (tag != ACL_USER)
                        continue;

                u = acl_get_qualifier(i);
                if (!u)
                        return -errno;

                b = *u == uid;
                acl_free(u);

                if (b) {
                        *entry = i;
                        return 1;
                }
        }
        if (r < 0)
                return -errno;

        return 0;
}
Beispiel #27
0
Datei: acl.c Projekt: Shloub/burp
// section of acl_is_trivial copied from bacula 
static int acl_is_trivial(acl_t acl)
{
#if defined(HAVE_LINUX_OS) \
 || defined(HAVE_FREEBSD_OS) \
 || defined(HAVE_OPENBSD_OS) \
 || defined(HAVE_NETBSD_OS)
	/*
	 * acl is trivial if it has only the following entries:
	 * "user::",
	 * "group::",
	 * "other::"
	 */
	acl_entry_t ace;
	acl_tag_t tag;
	int entry_available;

	entry_available = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace);
	while(entry_available==1)
	{
		/*
		 * Get the tag type of this acl entry.
		 * If we fail to get the tagtype we call the acl non-trivial.
		 */
		if (acl_get_tag_type(ace, &tag) < 0)
			return true;
		/*
		 * Anything other the ACL_USER_OBJ, ACL_GROUP_OBJ
		 * or ACL_OTHER breaks the spell.
		 */
		if(tag!=ACL_USER_OBJ
		  && tag!=ACL_GROUP_OBJ
		  && tag!=ACL_OTHER)
			return 0;
		entry_available=acl_get_entry(acl, ACL_NEXT_ENTRY, &ace);
	}
#endif
	return 1;
}
Beispiel #28
0
static int ACECount(acl_t acl)
{
    int more_aces;
    int count;
    acl_entry_t ace;

    count = 0;

    more_aces = acl_get_entry(acl, ACL_FIRST_ENTRY, &ace);

    if (more_aces <= 0)
    {
        return more_aces;
    }

    while (more_aces)
    {
        more_aces = acl_get_entry(acl, ACL_NEXT_ENTRY, &ace);
        count++;
    }

    return count;
}
Beispiel #29
0
int fpm_unix_set_socket_premissions(struct fpm_worker_pool_s *wp, const char *path) /* {{{ */
{
#ifdef HAVE_FPM_ACL
    if (wp->socket_acl) {
        acl_t aclfile, aclconf;
        acl_entry_t entryfile, entryconf;
        int i;

        /* Read the socket ACL */
        aclconf = wp->socket_acl;
        aclfile = acl_get_file (path, ACL_TYPE_ACCESS);
        if (!aclfile) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to read the ACL of the socket '%s'", wp->config->name, path);
            return -1;
        }
        /* Copy the new ACL entry from config */
        for (i=ACL_FIRST_ENTRY ; acl_get_entry(aclconf, i, &entryconf) ; i=ACL_NEXT_ENTRY) {
            if (0 > acl_create_entry (&aclfile, &entryfile) ||
                    0 > acl_copy_entry(entryfile, entryconf)) {
                zlog(ZLOG_SYSERROR, "[pool %s] failed to add entry to the ACL of the socket '%s'", wp->config->name, path);
                acl_free(aclfile);
                return -1;
            }
        }
        /* Write the socket ACL */
        if (0 > acl_calc_mask (&aclfile) ||
                0 > acl_valid (aclfile) ||
                0 > acl_set_file (path, ACL_TYPE_ACCESS, aclfile)) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to write the ACL of the socket '%s'", wp->config->name, path);
            acl_free(aclfile);
            return -1;
        } else {
            zlog(ZLOG_DEBUG, "[pool %s] ACL of the socket '%s' is set", wp->config->name, path);
        }

        acl_free(aclfile);
        return 0;
    }
    /* When listen.users and listen.groups not configured, continue with standard right */
#endif

    if (wp->socket_uid != -1 || wp->socket_gid != -1) {
        if (0 > chown(path, wp->socket_uid, wp->socket_gid)) {
            zlog(ZLOG_SYSERROR, "[pool %s] failed to chown() the socket '%s'", wp->config->name, wp->config->listen_address);
            return -1;
        }
    }
    return 0;
}
Beispiel #30
0
int
remove_by_number(uint entry_number, acl_t *prev_acl, const char *filename)
{
	acl_entry_t	entry;
	acl_t		acl_new;
	acl_tag_t	tag;
	int		carried_error, entry_id;
	uint		i;

	carried_error = 0;

	acl_new = acl_dup(*prev_acl);
	if (acl_new == NULL)
		err(1, "%s: acl_dup() failed", filename);

	tag = ACL_UNDEFINED_TAG;

	/*
	 * Find out whether we're removing the mask entry,
	 * to behave the same as the routine above.
	 *
	 * XXX: Is this loop actually needed?
	 */
	entry_id = ACL_FIRST_ENTRY;
	i = 0;
	while (acl_get_entry(acl_new, entry_id, &entry) == 1) {
		entry_id = ACL_NEXT_ENTRY;
		if (i != entry_number)
			continue;
		if (acl_get_tag_type(entry, &tag) == -1)
			err(1, "%s: acl_get_tag_type() failed", filename);
		if (tag == ACL_MASK)
			have_mask++;
	}

	if (acl_delete_entry_np(acl_new, entry_number) == -1) {
		carried_error++;
		warn("%s: acl_delete_entry_np() failed", filename);
	}

	acl_free(*prev_acl);
	*prev_acl = acl_new;

	if (carried_error)
		return (-1);

	return (0);
}