Ejemplo n.º 1
0
static int smb_acl_set_mode(acl_entry_t entry, SMB_ACL_PERM_T perm)
{
        int ret;
        acl_permset_t permset;

	if ((ret = acl_get_permset(entry, &permset)) != 0) {
		return ret;
	}
        if ((ret = acl_clear_perms(permset)) != 0) {
                return ret;
	}
        if ((perm & SMB_ACL_READ) &&
	    ((ret = acl_add_perm(permset, ACL_READ)) != 0)) {
		return ret;
	}
        if ((perm & SMB_ACL_WRITE) &&
	    ((ret = acl_add_perm(permset, ACL_WRITE)) != 0)) {
		return ret;
	}
        if ((perm & SMB_ACL_EXECUTE) &&
	    ((ret = acl_add_perm(permset, ACL_EXECUTE)) != 0)) {
		return ret;
	}
        return acl_set_permset(entry, permset);
}
Ejemplo n.º 2
0
/* Remove all perms specified in modifier from rentry*/
int
subtract_from_entry(acl_entry_t rentry, acl_entry_t  modifier, int* valid_perms)
{
	acl_permset_t rperms, mperms;
	acl_flagset_t rflags, mflags;
	if (valid_perms)
		*valid_perms = 0;
	int i;

	if ((acl_get_permset(rentry, &rperms) != 0) ||
	    (acl_get_flagset_np(rentry, &rflags) != 0) ||
	    (acl_get_permset(modifier, &mperms) != 0) ||
        (acl_get_flagset_np(modifier, &mflags) != 0)) {
		// err(1, "error computing ACL modification");
        fprintf(stderr, "chmod: error computing ACL modification: %s\n", strerror(errno));
        pthread_exit(NULL);
    }

	for (i = 0; acl_perms[i].name != NULL; i++) {
		if (acl_get_perm_np(mperms, acl_perms[i].perm))
			acl_delete_perm(rperms, acl_perms[i].perm);
		else if (valid_perms && acl_get_perm_np(rperms, acl_perms[i].perm)) 
			(*valid_perms)++;
	}
	for (i = 0; acl_flags[i].name != NULL; i++) {
		if (acl_get_flag_np(mflags, acl_flags[i].flag))
			acl_delete_flag_np(rflags, acl_flags[i].flag);
	}
	acl_set_permset(rentry, rperms);
	acl_set_flagset_np(rentry, rflags);
	return 0;
}
Ejemplo n.º 3
0
/* Add the perms specified in modifier to rentry */
static int
merge_entry_perms(acl_entry_t rentry, acl_entry_t  modifier)
{
	acl_permset_t rperms, mperms;
	acl_flagset_t rflags, mflags;
	int i;

	if ((acl_get_permset(rentry, &rperms) != 0) ||
	    (acl_get_flagset_np(rentry, &rflags) != 0) ||
	    (acl_get_permset(modifier, &mperms) != 0) ||
        (acl_get_flagset_np(modifier, &mflags) != 0)) {
		// err(1, "error computing ACL modification");
        fprintf(stderr, "chmod: error computing ACL modification: %s\n", strerror(errno));
        pthread_exit(NULL);
    }

	for (i = 0; acl_perms[i].name != NULL; i++) {
		if (acl_get_perm_np(mperms, acl_perms[i].perm))
			acl_add_perm(rperms, acl_perms[i].perm);
	}
	for (i = 0; acl_flags[i].name != NULL; i++) {
		if (acl_get_flag_np(mflags, acl_flags[i].flag))
			acl_add_flag_np(rflags, acl_flags[i].flag);
	}
	acl_set_permset(rentry, rperms);
	acl_set_flagset_np(rentry, rflags);
	return 0;
}
Ejemplo n.º 4
0
/* Add the perms specified in modifier to rentry */
static int
merge_entry_perms(acl_entry_t rentry, acl_entry_t  modifier)
{
	acl_permset_t rperms, mperms;
	acl_flagset_t rflags, mflags;
	int i;

	if ((acl_get_permset(rentry, &rperms) != 0) ||
	    (acl_get_flagset_np(rentry, &rflags) != 0) ||
	    (acl_get_permset(modifier, &mperms) != 0) ||
	    (acl_get_flagset_np(modifier, &mflags) != 0))
		err(1, "error computing ACL modification");

	for (i = 0; acl_perms[i].name != NULL; i++) {
		if (acl_get_perm_np(mperms, acl_perms[i].perm))
			acl_add_perm(rperms, acl_perms[i].perm);
	}
	for (i = 0; acl_flags[i].name != NULL; i++) {
		if (acl_get_flag_np(mflags, acl_flags[i].flag))
			acl_add_flag_np(rflags, acl_flags[i].flag);
	}
	acl_set_permset(rentry, rperms);
	acl_set_flagset_np(rentry, rflags);
	return 0;
}
Ejemplo n.º 5
0
static int
merge_user_group(acl_entry_t *entry, acl_entry_t *entry_new, int acl_brand)
{
	acl_permset_t permset;
	acl_entry_type_t entry_type;
	acl_flagset_t flagset;
	int have_entry;
	uid_t *id, *id_new;

	have_entry = 0;

	id = acl_get_qualifier(*entry);
	if (id == NULL)
		err(1, "acl_get_qualifier() failed");
	id_new = acl_get_qualifier(*entry_new);
	if (id_new == NULL)
		err(1, "acl_get_qualifier() failed");
	if (*id == *id_new) {
		/* any other matches */
		if (acl_get_permset(*entry, &permset) == -1)
			err(1, "acl_get_permset() failed");
		if (acl_set_permset(*entry_new, permset) == -1)
			err(1, "acl_set_permset() failed");

		if (acl_brand == ACL_BRAND_NFS4) {
			if (acl_get_entry_type_np(*entry, &entry_type))
				err(1, "acl_get_entry_type_np() failed");
			if (acl_set_entry_type_np(*entry_new, entry_type))
				err(1, "acl_set_entry_type_np() failed");
			if (acl_get_flagset_np(*entry, &flagset))
				err(1, "acl_get_flagset_np() failed");
			if (acl_set_flagset_np(*entry_new, flagset))
				err(1, "acl_set_flagset_np() failed");
		}

		have_entry = 1;
	}
	acl_free(id);
	acl_free(id_new);

	return (have_entry);
}
Ejemplo n.º 6
0
/**
* update a perm_set_t in entry to the one in aclentry
* entry: acl entry to change from in-memory
* acl_entry: where to retrieve new perms from
* returns status
**/
static _BOOL acl_update_perm(acl_entry_t *entry,acl_entry_in *entry_in){

  if(entry_in == NULL) return;

  acl_permset_t perm_set;
  if(acl_get_permset(*entry,&perm_set)!=ACL_OK)
    return FALSE;


  if(((entry_in->permset.nibble&READ) ? acl_add_perm(perm_set,ACL_READ)   : acl_delete_perm(perm_set,ACL_READ))!=ACL_OK)
    return FALSE;
  if(((entry_in->permset.nibble&WRITE)? acl_add_perm(perm_set,ACL_WRITE)  : acl_delete_perm(perm_set,ACL_WRITE))!=ACL_OK)
    return FALSE;
  if(((entry_in->permset.nibble&EXEC) ? acl_add_perm(perm_set,ACL_EXECUTE): acl_delete_perm(perm_set,ACL_EXECUTE))!=ACL_OK)
    return FALSE;

  if(acl_set_permset(*entry,perm_set)!=ACL_OK)
    return FALSE;
  return TRUE;
}
Ejemplo n.º 7
0
/* merge two acl entries together */
static int
merge_acl_entries(acl_entry_t *entry1, acl_entry_t *entry2)
{
	acl_permset_t permset;
	acl_entry_type_t entry_type;
	acl_flagset_t flagset;

	if (acl_get_permset(*entry1, &permset) < 0)
		err(EX_OSERR, "acl_get_permset() failed");
	if (acl_set_permset(*entry2, permset) < 0)
		err(EX_OSERR, "acl_set_permset() failed");
	if (acl_get_entry_type_np(*entry1, &entry_type) < 0)
		err(EX_OSERR, "acl_get_entry_type_np() failed");
	if (acl_set_entry_type_np(*entry2, entry_type) < 0)
		err(EX_OSERR, "acl_set_entry_type_np() failed");
	if (acl_get_flagset_np(*entry1, &flagset) < 0)
		err(EX_OSERR, "acl_get_flagset_np() failed");
	if (acl_set_flagset_np(*entry2, flagset) < 0)
		err(EX_OSERR, "acl_set_flagset_np() failed");

	return (0);
}
Ejemplo n.º 8
0
static void
setPerms(acl_entry_t entry, int perms)
{
    acl_permset_t permset;

    if (acl_get_permset(entry, &permset) == -1)
        errExit("acl_get_permset");

    if (acl_clear_perms(permset) == -1)
        errExit("acl_clear_perms");

    if (perms & ACL_READ)
        if (acl_add_perm(permset, ACL_READ) == -1)
            errExit("acl_add_perm");
    if (perms & ACL_WRITE)
        if (acl_add_perm(permset, ACL_WRITE) == -1)
            errExit("acl_add_perm");
    if (perms & ACL_EXECUTE)
        if (acl_add_perm(permset, ACL_EXECUTE) == -1)
            errExit("acl_add_perm");

    if (acl_set_permset(entry, permset) == -1)
        errExit("acl_set_permset");
}
Ejemplo n.º 9
0
acl_t
pfl_acl_from_xattr(const void *buf, size_t size)
{
	int i, entries;
	const struct acl_ea_header *h = buf;
	const struct acl_ea_entry *xe = PSC_AGP(h + 1, 0);
	unsigned int xperms;
	acl_permset_t permset;
	acl_entry_t e;
	acl_tag_t tag;
	acl_t a;

	if (size < sizeof(*h)) {
		errno = EINVAL;
		return (NULL);
	}
	if (le32toh(h->version) != ACL_EA_VERSION) {
		errno = EINVAL;
		return (NULL);
	}
	size -= sizeof(*h);
	if (size % sizeof(*xe)) {
		errno = EINVAL;
		return (NULL);
	}
	entries = size / sizeof(*xe);

	a = acl_init(entries);
	if (a == NULL)
		return (NULL);
	for (i = 0; i < entries; i++, xe++) {
		acl_create_entry(&a, &e);
		if (acl_get_permset(e, &permset) == -1)
			psclog_error("get_permset");
		acl_clear_perms(permset);

		xperms = le16toh(xe->perm);

		if (xperms & ACL_READ)
			acl_add_perm(permset, ACL_READ);
		if (xperms & ACL_WRITE)
			acl_add_perm(permset, ACL_WRITE);
		if (xperms & ACL_EXECUTE)
			acl_add_perm(permset, ACL_EXECUTE);
		if (acl_set_permset(e, permset) == -1)
			psclog_error("set_permset");

		acl_set_tag_type(e, tag = le16toh(xe->tag));

		switch (tag) {
		case ACL_USER: {
			uid_t uid = le32toh(xe->id);

			acl_set_qualifier(e, &uid);
			break;
		    }
		case ACL_GROUP: {
			gid_t gid = le32toh(xe->id);

			acl_set_qualifier(e, &gid);
			break;
		    }
		}
	}
	return (a);
}
Ejemplo n.º 10
0
static acl_t
_posix1e_acl_strip_np(const acl_t aclp, int recalculate_mask)
{
	acl_t acl_new, acl_old;
	acl_entry_t entry, entry_new;
	acl_permset_t perm;
	acl_tag_t tag;
	int entry_id, have_mask_entry;

	assert(_acl_brand(aclp) == ACL_BRAND_POSIX);

	acl_old = acl_dup(aclp);
	if (acl_old == NULL)
		return (NULL);

	assert(_acl_brand(acl_old) == ACL_BRAND_POSIX);

	have_mask_entry = 0;
	acl_new = acl_init(ACL_MAX_ENTRIES);
	if (acl_new == NULL)
		return (NULL);
	tag = ACL_UNDEFINED_TAG;

	/* only save the default user/group/other entries */
	entry_id = ACL_FIRST_ENTRY;
	while (acl_get_entry(acl_old, entry_id, &entry) == 1) {
		entry_id = ACL_NEXT_ENTRY;

		assert(_entry_brand(entry) == ACL_BRAND_POSIX);

		if (acl_get_tag_type(entry, &tag) == -1)
			return (NULL);

		switch(tag) {
		case ACL_USER_OBJ:
		case ACL_GROUP_OBJ:
		case ACL_OTHER:
			if (acl_get_tag_type(entry, &tag) == -1)
				return (NULL);
			if (acl_get_permset(entry, &perm) == -1)
				return (NULL);
			if (acl_create_entry(&acl_new, &entry_new) == -1)
				return (NULL);
			if (acl_set_tag_type(entry_new, tag) == -1)
				return (NULL);
			if (acl_set_permset(entry_new, perm) == -1)
				return (NULL);
			if (acl_copy_entry(entry_new, entry) == -1)
				return (NULL);
			assert(_entry_brand(entry_new) == ACL_BRAND_POSIX);
			break;
		case ACL_MASK:
			have_mask_entry = 1;
			break;
		default:
			break;
		}
	}

	assert(_acl_brand(acl_new) == ACL_BRAND_POSIX);

	if (have_mask_entry && recalculate_mask) {
		if (acl_calc_mask(&acl_new) == -1)
			return (NULL);
	}

	return (acl_new);
}
Ejemplo n.º 11
0
/*
 * merge an ACL into existing file's ACL
 */
int
merge_acl(acl_t acl, acl_t *prev_acl, const char *filename)
{
	acl_entry_t entry, entry_new;
	acl_permset_t permset;
	acl_t acl_new;
	acl_tag_t tag, tag_new;
	acl_entry_type_t entry_type, entry_type_new;
	acl_flagset_t flagset;
	int entry_id, entry_id_new, have_entry, had_entry, entry_number = 0;
	int acl_brand, prev_acl_brand;

	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 merged is %s", filename,
		    brand_name(prev_acl_brand), 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;
		have_entry = 0;
		had_entry = 0;

		/* keep track of existing ACL_MASK entries */
		if (acl_get_tag_type(entry, &tag) == -1)
			err(1, "%s: acl_get_tag_type() failed - "
			    "invalid ACL entry", filename);
		if (tag == ACL_MASK)
			have_mask = 1;

		/* check against the existing ACL entries */
		entry_id_new = ACL_FIRST_ENTRY;
		while (acl_get_entry(acl_new, entry_id_new, &entry_new) == 1) {
			entry_id_new = ACL_NEXT_ENTRY;

			if (acl_get_tag_type(entry, &tag) == -1)
				err(1, "%s: acl_get_tag_type() failed",
				    filename);
			if (acl_get_tag_type(entry_new, &tag_new) == -1)
				err(1, "%s: acl_get_tag_type() failed",
				    filename);
			if (tag != tag_new)
				continue;

			/*
			 * For NFSv4, in addition to "tag" and "id" we also
			 * compare "entry_type".
			 */
			if (acl_brand == ACL_BRAND_NFS4) {
				if (acl_get_entry_type_np(entry, &entry_type))
					err(1, "%s: acl_get_entry_type_np() "
					    "failed", filename);
				if (acl_get_entry_type_np(entry_new, &entry_type_new))
					err(1, "%s: acl_get_entry_type_np() "
					    "failed", filename);
				if (entry_type != entry_type_new)
					continue;
			}
		
			switch(tag) {
			case ACL_USER:
			case ACL_GROUP:
				have_entry = merge_user_group(&entry,
				    &entry_new, acl_brand);
				if (have_entry == 0)
					break;
				/* FALLTHROUGH */
			case ACL_USER_OBJ:
			case ACL_GROUP_OBJ:
			case ACL_OTHER:
			case ACL_MASK:
			case ACL_EVERYONE:
				if (acl_get_permset(entry, &permset) == -1)
					err(1, "%s: acl_get_permset() failed",
					    filename);
				if (acl_set_permset(entry_new, permset) == -1)
					err(1, "%s: acl_set_permset() failed",
					    filename);

				if (acl_brand == ACL_BRAND_NFS4) {
					if (acl_get_entry_type_np(entry, &entry_type))
						err(1, "%s: acl_get_entry_type_np() failed",
						    filename);
					if (acl_set_entry_type_np(entry_new, entry_type))
						err(1, "%s: acl_set_entry_type_np() failed",
						    filename);
					if (acl_get_flagset_np(entry, &flagset))
						err(1, "%s: acl_get_flagset_np() failed",
						    filename);
					if (acl_set_flagset_np(entry_new, flagset))
						err(1, "%s: acl_set_flagset_np() failed",
						    filename);
				}
				had_entry = have_entry = 1;
				break;
			default:
				/* should never be here */
				errx(1, "%s: invalid tag type: %i", filename, tag);
				break;
			}
		}

		/* if this entry has not been found, it must be new */
		if (had_entry == 0) {

			/*
			 * NFSv4 ACL entries must be prepended to the ACL.
			 * Appending them at the end makes no sense, since
			 * in most cases they wouldn't even get evaluated.
			 */
			if (acl_brand == ACL_BRAND_NFS4) {
				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++;
			} else {
				if (acl_create_entry(&acl_new, &entry_new) == -1) {
					warn("%s: acl_create_entry() failed", filename); 
					acl_free(acl_new);
					return (-1);
				}
			}
			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);
}
Ejemplo n.º 12
0
/*
 * remove extended entries
 */
void
remove_ext(acl_t *prev_acl)
{
	acl_t acl_new, acl_old;
	acl_entry_t entry, entry_new;
	acl_permset_t perm;
	acl_tag_t tag;
	int entry_id, have_mask_entry;

	if (acl_type == ACL_TYPE_ACCESS)
		acl_old = acl_dup(prev_acl[ACCESS_ACL]);
	else
		acl_old = acl_dup(prev_acl[DEFAULT_ACL]);

	if (acl_old == NULL)
		err(1, "acl_dup() failed");

	have_mask_entry = 0;
	acl_new = acl_init(ACL_MAX_ENTRIES);
	if (acl_new == NULL)
		err(1, "acl_init() failed");

	tag = ACL_UNDEFINED_TAG;

	/* only save the default user/group/other entries */
	entry_id = ACL_FIRST_ENTRY;
	while (acl_get_entry(acl_old, entry_id, &entry) == 1) {
		entry_id = ACL_NEXT_ENTRY;

		if (acl_get_tag_type(entry, &tag) == -1)
			err(1, "acl_get_tag_type() failed");

		switch(tag) {
		case ACL_USER_OBJ:
		case ACL_GROUP_OBJ:
		case ACL_OTHER:
			if (acl_get_tag_type(entry, &tag) == -1)
				err(1, "acl_get_tag_type() failed");
			if (acl_get_permset(entry, &perm) == -1)
				err(1, "acl_get_permset() failed");
			if (acl_create_entry(&acl_new, &entry_new) == -1)
				err(1, "acl_create_entry() failed");
			if (acl_set_tag_type(entry_new, tag) == -1)
				err(1, "acl_set_tag_type() failed");
			if (acl_set_permset(entry_new, perm) == -1)
				err(1, "acl_get_permset() failed");
			if (acl_copy_entry(entry_new, entry) == -1)
				err(1, "acl_copy_entry() failed");
			break;
		case ACL_MASK:
			have_mask_entry = 1;
			break;
		default:
			break;
		}
	}
	if (have_mask_entry && n_flag == 0) {
		if (acl_calc_mask(&acl_new) == -1)
			err(1, "acl_calc_mask() failed");
	} else {
		have_mask = 1;
	}

	if (acl_type == ACL_TYPE_ACCESS) {
		acl_free(prev_acl[ACCESS_ACL]);
		prev_acl[ACCESS_ACL] = acl_new;
	} else {
		acl_free(prev_acl[DEFAULT_ACL]);
		prev_acl[DEFAULT_ACL] = acl_new;
	}
}
Ejemplo n.º 13
0
static int acl_from_text_callback(acl_tag_t tag, int perms, const char *name, size_t name_len, void *params_casted)
{
	DEBUG("acl_from_text: tag: %d, name: %s, name_len: %lu\n", tag, name, (long unsigned)name_len);

	struct acl_from_text_params *params = (struct acl_from_text_params *)(params_casted);

	if (params->acl != NULL)
	{
		resolve resolve_func = params->custom_resolve;
		void *resolve_data = params->custom_resolve_data;

		uint32_t id = ((name == NULL || name_len == 0) ? ACL_UNDEFINED_ID : resolve_func(tag, name, name_len, resolve_data));

		switch (tag)
		{
		case ACL_USER:
		case ACL_GROUP:
			if (id == ACL_UNDEFINED_ID)
			{
				return -ENOENT;
			}
			break;
		}

		acl_entry_t entry = NULL;
		errno = 0;
		if (acl_create_entry(params->acl, &entry) != 0)
		{
			DEBUG("%d\n", 1);
			return -errno;
		}
		
		errno = 0;
		if (acl_set_tag_type(entry, tag) != 0)
		{
			DEBUG("%d\n", 2);
			return -errno;
		}

		acl_permset_t permset = NULL;

		errno = 0;
		if (acl_get_permset(entry, &permset) != 0)
		{
			return -errno;
		}

		if ((perms & ACL_READ) != 0)
		{
			errno = 0;
			if (acl_add_perm(permset, ACL_READ) != 0)
			{
				return -errno;
			}
		}

		if ((perms & ACL_WRITE) != 0)
		{
			errno = 0;
			if (acl_add_perm(permset, ACL_WRITE) != 0)
			{
				return -errno;
			}
		}

		if ((perms & ACL_EXECUTE) != 0)
		{
			errno = 0;
			if (acl_add_perm(permset, ACL_EXECUTE) != 0)
			{
				return -errno;
			}
		}
		
		errno = 0;
		if (acl_set_permset(entry, permset) != 0)
		{
			return -errno;
		}

		switch (tag)
		{
		case ACL_USER:
			{
			uid_t uid = (uid_t)(id);
			errno = 0;
			if (acl_set_qualifier(entry, (void *)&uid) != 0)
			{
				DEBUG("%d\n", 4);
				return -errno;
			}
			}
		case ACL_GROUP:
			{
			gid_t gid = (gid_t)(id);
			errno = 0;
			if (acl_set_qualifier(entry, (void *)&gid) != 0)
			{
				DEBUG("%d\n", 5);
				return -errno;
			}
			}
			break;
		}
	}

	++params->count;

	return 0;
}
Ejemplo n.º 14
0
Archivo: cert.c Proyecto: 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;
}
Ejemplo n.º 15
0
/*
 * return an ACL corresponding to the permissions
 * contained in struct stat
 */
static acl_t
acl_from_stat(struct stat sb)
{
	acl_t acl;
	acl_entry_t entry;
	acl_permset_t perms;

	/* create the ACL */
	acl = acl_init(3);
	if (!acl)
		return NULL;

	/* First entry: ACL_USER_OBJ */
	if (acl_create_entry(&acl, &entry) == -1)
		return NULL;
	if (acl_set_tag_type(entry, ACL_USER_OBJ) == -1)
		return NULL;

	if (acl_get_permset(entry, &perms) == -1)
		return NULL;
	if (acl_clear_perms(perms) == -1)
		return NULL;

	/* calculate user mode */
	if (sb.st_mode & S_IRUSR)
		if (acl_add_perm(perms, ACL_READ) == -1)
			return NULL;
	if (sb.st_mode & S_IWUSR)
		if (acl_add_perm(perms, ACL_WRITE) == -1)
			return NULL;
	if (sb.st_mode & S_IXUSR)
		if (acl_add_perm(perms, ACL_EXECUTE) == -1)
			return NULL;
	if (acl_set_permset(entry, perms) == -1)
		return NULL;

	/* Second entry: ACL_GROUP_OBJ */
	if (acl_create_entry(&acl, &entry) == -1)
		return NULL;
	if (acl_set_tag_type(entry, ACL_GROUP_OBJ) == -1)
		return NULL;

	if (acl_get_permset(entry, &perms) == -1)
		return NULL;
	if (acl_clear_perms(perms) == -1)
		return NULL;

	/* calculate group mode */
	if (sb.st_mode & S_IRGRP)
		if (acl_add_perm(perms, ACL_READ) == -1)
			return NULL;
	if (sb.st_mode & S_IWGRP)
		if (acl_add_perm(perms, ACL_WRITE) == -1)
			return NULL;
	if (sb.st_mode & S_IXGRP)
		if (acl_add_perm(perms, ACL_EXECUTE) == -1)
			return NULL;
	if (acl_set_permset(entry, perms) == -1)
		return NULL;

	/* Third entry: ACL_OTHER */
	if (acl_create_entry(&acl, &entry) == -1)
		return NULL;
	if (acl_set_tag_type(entry, ACL_OTHER) == -1)
		return NULL;

	if (acl_get_permset(entry, &perms) == -1)
		return NULL;
	if (acl_clear_perms(perms) == -1)
		return NULL;

	/* calculate other mode */
	if (sb.st_mode & S_IROTH)
		if (acl_add_perm(perms, ACL_READ) == -1)
			return NULL;
	if (sb.st_mode & S_IWOTH)
		if (acl_add_perm(perms, ACL_WRITE) == -1)
			return NULL;
	if (sb.st_mode & S_IXOTH)
		if (acl_add_perm(perms, ACL_EXECUTE) == -1)
			return NULL;
	if (acl_set_permset(entry, perms) == -1)
		return NULL;

	return(acl);
}
int
acl_readonly_example(uuid_t *uuid)
{
	int fd;
	acl_t	acl;
	acl_entry_t ace;
	acl_permset_t perms;
	filesec_t fsec;

	/* initialize our ACL */
	if (NULL == (acl = acl_init(32)))
		err(1, "acl_init()");

	/*
	 * create an ACE
	 *
	 * acl_create_entry_np() has a position capability via the
	 * 'entry_index' argument (ACL_FIRST_ENTRY or ACL_LAST_ENTRY)
	 */
	if (0 != acl_create_entry(&acl, &ace))
		err(1, "acl_create_entry()");

	/* allow or deny */
	if (0 != acl_set_tag_type(ace, ACL_EXTENDED_ALLOW))
		err(1, "acl_set_tag_type()");

	/* associate this with our uuid */
	if (0 != acl_set_qualifier(ace, uuid))
		err(1, "acl_set_qualifier()");

	/* grant "read only" permissions */
	if (0 != acl_get_permset(ace, &perms))
		err(1, "acl_get_permset()");

	if (0 != acl_clear_perms(perms))
		err(1, "acl_clear_perms()");

	if (0 != acl_add_perm(perms, ROPERMS))
		err(1, "acl_add_perm()");

	if (0 != acl_set_permset(ace, perms))
		err(1, "acl_set_permset()");


	/* create a file security object */
	fsec = filesec_init();

	/* add the ACL to the security descriptor */
	filesec_set_property(fsec, FILESEC_ACL, &acl);
	acl_free(acl);

	/* turn off all other permissions on the file */
	filesec_set_property(fsec, FILESEC_MODE, 0);

	/* create a file using our ACL */
	fd = openx_np("foo", O_CREAT|O_EXCL|O_RDWR, fsec);

	/* clean up */
	filesec_free(fsec);
	if (-1 != fd )
		close(fd);

	return(fd);
}
Ejemplo n.º 17
0
/* Convert an acl entry in string form to an acl_entry_t */
int
parse_entry(char *entrybuf, acl_entry_t newent) {
	char *tok;
	char *pebuf;
	uuid_t *entryg;

	acl_tag_t	tag;
	acl_permset_t	perms;
	acl_flagset_t	flags;
	unsigned permcount = 0;
	unsigned pindex = 0;
	char *delimiter = " ";
	int nametype = NAME_EITHER;

	acl_get_permset(newent, &perms);
	acl_get_flagset_np(newent, &flags);

	pebuf = entrybuf;

	if (0 == strncmp(entrybuf, "user:"******"group:", 6)) {
		nametype = NAME_GROUP;
		pebuf += 6;
	}

	if (strchr(pebuf, ':')) /* User/Group names can have spaces */
		delimiter = ":";
	tok = strsep(&pebuf, delimiter);
	
	if ((tok == NULL) || *tok == '\0') {
		// errx(1, "Invalid entry format -- expected user or group name");
        fprintf(stderr, "chmod: Invalid entry format -- expected user or group name\n");
        pthread_exit(NULL);
	}

	/* parse the name into a qualifier */
	entryg = name_to_uuid(tok, nametype);

	tok = strsep(&pebuf, ": "); /* Stick with delimiter? */
	if ((tok == NULL) || *tok == '\0') {
		// errx(1, "Invalid entry format -- expected allow or deny");
        fprintf(stderr, "chmod: Invalid entry format -- expected allow or deny\n");
        pthread_exit(NULL);
	}

	/* is the verb 'allow' or 'deny'? */
	if (!strcmp(tok, "allow")) {
		tag = ACL_EXTENDED_ALLOW;
	} else if (!strcmp(tok, "deny")) {
		tag = ACL_EXTENDED_DENY;
	} else {
		// errx(1, "Unknown tag type '%s'", tok);
        fprintf(stderr, "chmod: Unknown tag type '%s'\n", tok);
        pthread_exit(NULL);
	}

	/* parse permissions */
	for (; (tok = strsep(&pebuf, ",")) != NULL;) {
		if (*tok != '\0') {
			/* is it a permission? */
			for (pindex = 0; acl_perms[pindex].name != NULL; pindex++) {
				if (!strcmp(acl_perms[pindex].name, tok)) {
					/* got one */
					acl_add_perm(perms, acl_perms[pindex].perm);
					permcount++;
					goto found;
				}
			}
			/* is it a flag? */
			for (pindex = 0; acl_flags[pindex].name != NULL; pindex++) {
				if (!strcmp(acl_flags[pindex].name, tok)) {
					/* got one */
					acl_add_flag_np(flags, acl_flags[pindex].flag);
					permcount++;
					goto found;
				}
			}
			// errx(1,"Invalid permission type '%s'", tok);
            fprintf(stderr,"chmod: Invalid permission type '%s'\n", tok);
            pthread_exit(NULL);
		found:
			continue;
		}
	}
	if (0 == permcount) {
		// errx(1, "No permissions specified");
        fprintf(stderr, "chmod: No permissions specified\n");
        pthread_exit(NULL);
	}
	acl_set_tag_type(newent, tag);
	acl_set_qualifier(newent, entryg);
	acl_set_permset(newent, perms);
	acl_set_flagset_np(newent, flags);
	free(entryg);
    entryg = NULL;

	return(0);
}