示例#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);
}
示例#2
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");
}
示例#3
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);
}
示例#4
0
文件: acl_posix.c 项目: ajlill/core
static int ParseModePosixLinux(char *mode, acl_permset_t perms)
{
    int retv;
    int more_entries;
    acl_perm_t perm;
    enum { add, del } op;

    op = add;

    if (*mode == '\0' || *mode == ':')
    {
        if (acl_clear_perms(perms) != 0)
        {
            Log(LOG_LEVEL_ERR, "Error clearing perms. (acl_clear_perms: %s)", GetErrorStr());
            return false;
        }
        else
        {
            return true;
        }
    }

    more_entries = true;

    while (more_entries)
    {
        switch (*mode)
        {
        case '+':
            op = add;
            mode++;
            break;

        case '-':
            op = del;
            mode++;
            break;

        case '=':
            mode++;
            // fallthrough

        default:
            // if mode does not start with + or -, we clear existing perms
            op = add;

            if (acl_clear_perms(perms) != 0)
            {
                Log(LOG_LEVEL_ERR, "Unable to clear ACL permissions. (acl_clear_perms: %s)", GetErrorStr());
                return false;
            }
        }

        // parse generic perms (they are 1-1 on Posix)

        while (*mode != '\0' && strchr(CF_VALID_GPERMS, *mode))
        {
            if (*mode == '\0')
            {
                break;
            }
            switch (*mode)
            {
            case 'r':
                perm = ACL_READ;
                break;

            case 'w':
                perm = ACL_WRITE;
                break;

            case 'x':
                perm = ACL_EXECUTE;
                break;

            default:
                Log(LOG_LEVEL_ERR, "No linux support for generic permission flag '%c'", *mode);
                return false;
            }

            if (op == add)
            {
                retv = acl_add_perm(perms, perm);
            }
            else
            {
                retv = acl_delete_perm(perms, perm);
            }

            if (retv != 0)
            {
                Log(LOG_LEVEL_ERR, "Could not change ACE permission. (acl_[add|delete]_perms: %s)", GetErrorStr());
                return false;
            }
            mode++;
        }

        // parse native perms

        if (*mode == CF_NATIVE_PERMS_SEP_START)
        {
            mode++;

            while (*mode != '\0' && strchr(CF_VALID_NPERMS_POSIX, *mode))
            {
                switch (*mode)
                {
                case 'r':
                    perm = ACL_READ;
                    break;

                case 'w':
                    perm = ACL_WRITE;
                    break;

                case 'x':
                    perm = ACL_EXECUTE;
                    break;

                default:
                    Log(LOG_LEVEL_ERR, "No linux support for native permission flag '%c'", *mode);
                    return false;
                }

                if (op == add)
                {
                    retv = acl_add_perm(perms, perm);
                }
                else
                {
                    retv = acl_delete_perm(perms, perm);
                }

                if (retv != 0)
                {
                    Log(LOG_LEVEL_ERR, "Could not change ACE permission. (acl_[add|delete]_perm: %s)", GetErrorStr());
                    return false;
                }
                mode++;
            }

            // scan past native perms end seperator
            mode++;
        }

        if (*mode == ',')
        {
            more_entries = true;
            mode++;
        }
        else
        {
            more_entries = false;
        }
    }

    return true;
}
示例#5
0
文件: acl_posix.c 项目: ajlill/core
static int CheckPosixLinuxACEs(EvalContext *ctx, Rlist *aces, AclMethod method, const char *file_path, acl_type_t acl_type, Attributes a,
                               const Promise *pp, PromiseResult *result)
{
    acl_t acl_existing;
    acl_t acl_new;
    acl_t acl_tmp;
    acl_entry_t ace_parsed;
    acl_entry_t ace_current;
    acl_permset_t perms;
    char *cf_ace;
    int retv;
    int has_mask;
    Rlist *rp;
    char *acl_type_str;

    acl_new = NULL;
    acl_existing = NULL;
    acl_tmp = NULL;
    has_mask = false;

    acl_type_str = acl_type == ACL_TYPE_ACCESS ? "Access" : "Default";

// read existing acl

    if ((acl_existing = acl_get_file(file_path, acl_type)) == NULL)
    {
        Log(LOG_LEVEL_VERBOSE, "No ACL for '%s' could be read. (acl_get_file: %s)", file_path, GetErrorStr());
        return false;
    }

// allocate memory for temp ace (it needs to reside in a temp acl)

    if ((acl_tmp = acl_init(1)) == NULL)
    {
        Log(LOG_LEVEL_ERR, "New ACL could not be allocated (acl_init: %s)", GetErrorStr());
        acl_free((void *) acl_existing);
        return false;
    }

    if (acl_create_entry(&acl_tmp, &ace_parsed) != 0)
    {
        Log(LOG_LEVEL_ERR, "New ACL could not be allocated (acl_create_entry: %s)", GetErrorStr());
        acl_free((void *) acl_existing);
        acl_free((void *) acl_tmp);
        return false;
    }

// copy existing aces if we are appending

    if (method == ACL_METHOD_APPEND)
    {
        if ((acl_new = acl_dup(acl_existing)) == NULL)
        {
            Log(LOG_LEVEL_ERR, "Error copying existing ACL (acl_dup: %s)", GetErrorStr());
            acl_free((void *) acl_existing);
            acl_free((void *) acl_tmp);
            return false;
        }
    }
    else                        // overwrite existing acl
    {
        if ((acl_new = acl_init(5)) == NULL)    // TODO: Always OK with 5 here ?
        {
            Log(LOG_LEVEL_ERR, "New ACL could not be allocated (acl_init: %s)", GetErrorStr());
            acl_free((void *) acl_existing);
            acl_free((void *) acl_tmp);
            return false;
        }
    }

    for (rp = aces; rp != NULL; rp = rp->next)
    {
        cf_ace = RlistScalarValue(rp);

        if (!ParseEntityPosixLinux(&cf_ace, ace_parsed, &has_mask))
        {
            Log(LOG_LEVEL_ERR, "Error parsing entity in 'cf_ace'.");
            acl_free((void *) acl_existing);
            acl_free((void *) acl_tmp);
            acl_free((void *) acl_new);
            return false;
        }

        // check if an ACE with this entity-type and id already exist in the Posix Linux ACL

        ace_current = FindACE(acl_new, ace_parsed);

        // create new entry in ACL if it did not exist

        if (ace_current == NULL)
        {
            if (acl_create_entry(&acl_new, &ace_current) != 0)
            {
                Log(LOG_LEVEL_ERR, "Failed to allocate ace (acl_create_entry: %s)", GetErrorStr());
                acl_free((void *) acl_existing);
                acl_free((void *) acl_tmp);
                acl_free((void *) acl_new);
                return false;
            }

            // copy parsed entity-type and id

            if (acl_copy_entry(ace_current, ace_parsed) != 0)
            {
                Log(LOG_LEVEL_ERR, "Error copying Linux entry in 'cf_ace' (acl_copy_entry: %s)", GetErrorStr());
                acl_free((void *) acl_existing);
                acl_free((void *) acl_tmp);
                acl_free((void *) acl_new);
                return false;
            }

            // clear ace_current's permissions to avoid ace_parsed from last
            // loop iteration to be taken into account when applying mode below
            if ((acl_get_permset(ace_current, &perms) != 0))
            {
                Log(LOG_LEVEL_ERR, "Error obtaining permset for 'ace_current' (acl_get_permset: %s)", GetErrorStr());
                acl_free((void *) acl_existing);
                acl_free((void *) acl_tmp);
                acl_free((void *) acl_new);
                return false;
            }

            if (acl_clear_perms(perms) != 0)
            {
                Log(LOG_LEVEL_ERR, "Error clearing permset for 'ace_current'. (acl_clear_perms: %s)", GetErrorStr());
                acl_free((void *) acl_existing);
                acl_free((void *) acl_tmp);
                acl_free((void *) acl_new);
                return false;
            }
        }

        // mode string should be prefixed with an entry seperator

        if (*cf_ace != ':')
        {
            Log(LOG_LEVEL_ERR, "No separator before mode-string in 'cf_ace'");
            acl_free((void *) acl_existing);
            acl_free((void *) acl_tmp);
            acl_free((void *) acl_new);
            return false;
        }

        cf_ace += 1;

        if (acl_get_permset(ace_current, &perms) != 0)
        {
            Log(LOG_LEVEL_ERR, "Error obtaining permset for 'cf_ace'");
            acl_free((void *) acl_existing);
            acl_free((void *) acl_tmp);
            acl_free((void *) acl_new);
            return false;
        }

        if (!ParseModePosixLinux(cf_ace, perms))
        {
            Log(LOG_LEVEL_ERR, "Error parsing mode-string in 'cf_ace'");
            acl_free((void *) acl_existing);
            acl_free((void *) acl_tmp);
            acl_free((void *) acl_new);
            return false;
        }

        // only allow permissions exist on posix acls, so we do
        // not check what follows next
    }

// if no mask exists, calculate one (or both?): run acl_calc_mask and add one
    if (!has_mask)
    {
        if (acl_calc_mask(&acl_new) != 0)
        {
            Log(LOG_LEVEL_ERR, "Error calculating new acl mask");
            acl_free((void *) acl_existing);
            acl_free((void *) acl_tmp);
            acl_free((void *) acl_new);
            return false;
        }
    }

    if ((retv = ACLEquals(acl_existing, acl_new)) == -1)
    {
        Log(LOG_LEVEL_ERR, "Error while comparing existing and new ACL, unable to repair.");
        acl_free((void *) acl_existing);
        acl_free((void *) acl_tmp);
        acl_free((void *) acl_new);
        return false;
    }

    if (retv == 1)              // existing and new acl differ, update existing
    {

        switch (a.transaction.action)
        {
        case cfa_warn:

            cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_WARN, pp, a, "%s ACL on file '%s' needs to be updated", acl_type_str, file_path);
            *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN);
            break;

        case cfa_fix:

            if (!DONTDO)
            {
                if ((retv = acl_set_file(file_path, acl_type, acl_new)) != 0)
                {
                    Log(LOG_LEVEL_ERR, "Error setting new %s ACL on file '%s' (acl_set_file: %s), are required ACEs present ?",
                          acl_type_str, file_path, GetErrorStr());
                    acl_free((void *) acl_existing);
                    acl_free((void *) acl_tmp);
                    acl_free((void *) acl_new);
                    return false;
                }
            }

            cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, a, "%s ACL on '%s' successfully changed.", acl_type_str, file_path);
            *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE);

            break;

        default:
            ProgrammingError("CFEngine: internal error: illegal file action");
        }

    }
    else
    {
        cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_NOOP, pp, a, "'%s' ACL on '%s' needs no modification.", acl_type_str, file_path);
    }

    acl_free((void *) acl_existing);
    acl_free((void *) acl_new);
    acl_free((void *) acl_tmp);
    return true;
}
示例#6
0
static int
set_acl(struct archive *a, int fd, const char *name,
        struct archive_acl *abstract_acl,
        acl_type_t acl_type, int ae_requested_type, const char *tname)
{
    acl_t		 acl;
    acl_entry_t	 acl_entry;
    acl_permset_t	 acl_permset;
#ifdef ACL_TYPE_NFS4
    acl_flagset_t	 acl_flagset;
    int		 r;
#endif
    int		 ret;
    int		 ae_type, ae_permset, ae_tag, ae_id;
    uid_t		 ae_uid;
    gid_t		 ae_gid;
    const char	*ae_name;
    int		 entries;
    int		 i;

    ret = ARCHIVE_OK;
    entries = archive_acl_reset(abstract_acl, ae_requested_type);
    if (entries == 0)
        return (ARCHIVE_OK);
    acl = acl_init(entries);
    while (archive_acl_next(a, abstract_acl, ae_requested_type, &ae_type,
                            &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
        acl_create_entry(&acl, &acl_entry);

        switch (ae_tag) {
        case ARCHIVE_ENTRY_ACL_USER:
            acl_set_tag_type(acl_entry, ACL_USER);
            ae_uid = archive_write_disk_uid(a, ae_name, ae_id);
            acl_set_qualifier(acl_entry, &ae_uid);
            break;
        case ARCHIVE_ENTRY_ACL_GROUP:
            acl_set_tag_type(acl_entry, ACL_GROUP);
            ae_gid = archive_write_disk_gid(a, ae_name, ae_id);
            acl_set_qualifier(acl_entry, &ae_gid);
            break;
        case ARCHIVE_ENTRY_ACL_USER_OBJ:
            acl_set_tag_type(acl_entry, ACL_USER_OBJ);
            break;
        case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
            acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
            break;
        case ARCHIVE_ENTRY_ACL_MASK:
            acl_set_tag_type(acl_entry, ACL_MASK);
            break;
        case ARCHIVE_ENTRY_ACL_OTHER:
            acl_set_tag_type(acl_entry, ACL_OTHER);
            break;
#ifdef ACL_TYPE_NFS4
        case ARCHIVE_ENTRY_ACL_EVERYONE:
            acl_set_tag_type(acl_entry, ACL_EVERYONE);
            break;
#endif
        default:
            /* XXX */
            break;
        }

#ifdef ACL_TYPE_NFS4
        switch (ae_type) {
        case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
            acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALLOW);
            break;
        case ARCHIVE_ENTRY_ACL_TYPE_DENY:
            acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_DENY);
            break;
        case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
            acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_AUDIT);
            break;
        case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
            acl_set_entry_type_np(acl_entry, ACL_ENTRY_TYPE_ALARM);
            break;
        case ARCHIVE_ENTRY_ACL_TYPE_ACCESS:
        case ARCHIVE_ENTRY_ACL_TYPE_DEFAULT:
            // These don't translate directly into the system ACL.
            break;
        default:
            // XXX error handling here.
            break;
        }
#endif

        acl_get_permset(acl_entry, &acl_permset);
        acl_clear_perms(acl_permset);

        for (i = 0; i < (int)(sizeof(acl_perm_map) / sizeof(acl_perm_map[0])); ++i) {
            if (ae_permset & acl_perm_map[i].archive_perm)
                acl_add_perm(acl_permset,
                             acl_perm_map[i].platform_perm);
        }

#ifdef ACL_TYPE_NFS4
        // XXX acl_get_flagset_np on FreeBSD returns EINVAL for
        // non-NFSv4 ACLs
        r = acl_get_flagset_np(acl_entry, &acl_flagset);
        if (r == 0) {
            acl_clear_flags_np(acl_flagset);
            for (i = 0; i < (int)(sizeof(acl_inherit_map) / sizeof(acl_inherit_map[0])); ++i) {
                if (ae_permset & acl_inherit_map[i].archive_inherit)
                    acl_add_flag_np(acl_flagset,
                                    acl_inherit_map[i].platform_inherit);
            }
        }
#endif
    }

    /* Try restoring the ACL through 'fd' if we can. */
#if HAVE_ACL_SET_FD
    if (fd >= 0 && acl_type == ACL_TYPE_ACCESS && acl_set_fd(fd, acl) == 0)
        ret = ARCHIVE_OK;
    else
#else
#if HAVE_ACL_SET_FD_NP
    if (fd >= 0 && acl_set_fd_np(fd, acl, acl_type) == 0)
        ret = ARCHIVE_OK;
    else
#endif
#endif
#if HAVE_ACL_SET_LINK_NP
        if (acl_set_link_np(name, acl_type, acl) != 0) {
            archive_set_error(a, errno, "Failed to set %s acl", tname);
            ret = ARCHIVE_WARN;
        }
#else
        /* TODO: Skip this if 'name' is a symlink. */
        if (acl_set_file(name, acl_type, acl) != 0) {
            archive_set_error(a, errno, "Failed to set %s acl", tname);
            ret = ARCHIVE_WARN;
        }
#endif
    acl_free(acl);
    return (ret);
}
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);
}
示例#8
0
int fpm_unix_resolve_socket_premissions(struct fpm_worker_pool_s *wp) /* {{{ */
{
    struct fpm_worker_pool_config_s *c = wp->config;
#ifdef HAVE_FPM_ACL
    int n;

    /* uninitialized */
    wp->socket_acl  = NULL;
#endif
    wp->socket_uid = -1;
    wp->socket_gid = -1;
    wp->socket_mode = 0660;

    if (!c) {
        return 0;
    }

    if (c->listen_mode && *c->listen_mode) {
        wp->socket_mode = strtoul(c->listen_mode, 0, 8);
    }

#ifdef HAVE_FPM_ACL
    /* count the users and groups configured */
    n = 0;
    if (c->listen_acl_users && *c->listen_acl_users) {
        char *p;
        n++;
        for (p=strchr(c->listen_acl_users, ',') ; p ; p=strchr(p+1, ',')) {
            n++;
        }
    }
    if (c->listen_acl_groups && *c->listen_acl_groups) {
        char *p;
        n++;
        for (p=strchr(c->listen_acl_groups, ',') ; p ; p=strchr(p+1, ',')) {
            n++;
        }
    }
    /* if ACL configured */
    if (n) {
        acl_t acl;
        acl_entry_t entry;
        acl_permset_t perm;
        char *tmp, *p, *end;

        acl = acl_init(n);
        if (!acl) {
            zlog(ZLOG_SYSERROR, "[pool %s] cannot allocate ACL", wp->config->name);
            return -1;
        }
        /* Create USER ACL */
        if (c->listen_acl_users && *c->listen_acl_users) {
            struct passwd *pwd;

            tmp = estrdup(c->listen_acl_users);
            for (p=tmp ; p ; p=end) {
                if ((end = strchr(p, ','))) {
                    *end++ = 0;
                }
                pwd = getpwnam(p);
                if (pwd) {
                    zlog(ZLOG_DEBUG, "[pool %s] user '%s' have uid=%d", wp->config->name, p, pwd->pw_uid);
                } else {
                    zlog(ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, p);
                    acl_free(acl);
                    efree(tmp);
                    return -1;
                }
                if (0 > acl_create_entry(&acl, &entry) ||
                        0 > acl_set_tag_type(entry, ACL_USER) ||
                        0 > acl_set_qualifier(entry, &pwd->pw_uid) ||
                        0 > acl_get_permset(entry, &perm) ||
                        0 > acl_clear_perms (perm) ||
                        0 > acl_add_perm (perm, ACL_READ) ||
                        0 > acl_add_perm (perm, ACL_WRITE)) {
                    zlog(ZLOG_SYSERROR, "[pool %s] cannot create ACL for user '%s'", wp->config->name, p);
                    acl_free(acl);
                    efree(tmp);
                    return -1;
                }
            }
            efree(tmp);
        }
        /* Create GROUP ACL */
        if (c->listen_acl_groups && *c->listen_acl_groups) {
            struct group *grp;

            tmp = estrdup(c->listen_acl_groups);
            for (p=tmp ; p ; p=end) {
                if ((end = strchr(p, ','))) {
                    *end++ = 0;
                }
                grp = getgrnam(p);
                if (grp) {
                    zlog(ZLOG_DEBUG, "[pool %s] group '%s' have gid=%d", wp->config->name, p, grp->gr_gid);
                } else {
                    zlog(ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, p);
                    acl_free(acl);
                    efree(tmp);
                    return -1;
                }
                if (0 > acl_create_entry(&acl, &entry) ||
                        0 > acl_set_tag_type(entry, ACL_GROUP) ||
                        0 > acl_set_qualifier(entry, &grp->gr_gid) ||
                        0 > acl_get_permset(entry, &perm) ||
                        0 > acl_clear_perms (perm) ||
                        0 > acl_add_perm (perm, ACL_READ) ||
                        0 > acl_add_perm (perm, ACL_WRITE)) {
                    zlog(ZLOG_SYSERROR, "[pool %s] cannot create ACL for group '%s'", wp->config->name, p);
                    acl_free(acl);
                    efree(tmp);
                    return -1;
                }
            }
            efree(tmp);
        }
        if (c->listen_owner && *c->listen_owner) {
            zlog(ZLOG_WARNING, "[pool %s] ACL set, listen.owner = '%s' is ignored", wp->config->name, c->listen_owner);
        }
        if (c->listen_group && *c->listen_group) {
            zlog(ZLOG_WARNING, "[pool %s] ACL set, listen.group = '%s' is ignored", wp->config->name, c->listen_group);
        }
        wp->socket_acl  = acl;
        return 0;
    }
    /* When listen.users and listen.groups not configured, continue with standard right */
#endif

    if (c->listen_owner && *c->listen_owner) {
        struct passwd *pwd;

        pwd = getpwnam(c->listen_owner);
        if (!pwd) {
            zlog(ZLOG_SYSERROR, "[pool %s] cannot get uid for user '%s'", wp->config->name, c->listen_owner);
            return -1;
        }

        wp->socket_uid = pwd->pw_uid;
        wp->socket_gid = pwd->pw_gid;
    }

    if (c->listen_group && *c->listen_group) {
        struct group *grp;

        grp = getgrnam(c->listen_group);
        if (!grp) {
            zlog(ZLOG_SYSERROR, "[pool %s] cannot get gid for group '%s'", wp->config->name, c->listen_group);
            return -1;
        }
        wp->socket_gid = grp->gr_gid;
    }

    return 0;
}
示例#9
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);
}