simple_access.c revision c8119652b17229a5aca9b110365c310a6afdce30
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin Simple access control
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin Copyright (C) Sumit Bose <sbose@redhat.com> 2010
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin This program is free software; you can redistribute it and/or modify
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin it under the terms of the GNU General Public License as published by
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin the Free Software Foundation; either version 3 of the License, or
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin (at your option) any later version.
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin This program is distributed in the hope that it will be useful,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin but WITHOUT ANY WARRANTY; without even the implied warranty of
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin GNU General Public License for more details.
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin You should have received a copy of the GNU General Public License
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin along with this program. If not, see <http://www.gnu.org/licenses/>.
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define CONFDB_SIMPLE_ALLOW_USERS "simple_allow_users"
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define CONFDB_SIMPLE_DENY_USERS "simple_deny_users"
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define CONFDB_SIMPLE_ALLOW_GROUPS "simple_allow_groups"
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin#define CONFDB_SIMPLE_DENY_GROUPS "simple_deny_groups"
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinstatic bool string_equal(bool cs, const char *s1, const char *s2)
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin return sss_utf8_case_eq((const uint8_t *)s1, (const uint8_t *)s2) == EOK;
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalinerrno_t simple_access_check(struct simple_ctx *ctx, const char *username,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin const char *user_attrs[] = { SYSDB_MEMBEROF,
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin /* First, check whether the user is in the allowed users list */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin for(i = 0; ctx->allow_users[i] != NULL; i++) {
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin if (string_equal(cs, username, ctx->allow_users[i])) {
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin DEBUG(9, ("User [%s] found in allow list, access granted.\n",
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin /* Do not return immediately on explicit allow
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin * We need to make sure none of the user's groups
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin * are denied.
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* If neither allow rule is in place, we'll assume allowed
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin * unless a deny rule disables us below.
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* Next check whether this user has been specifically denied */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin for(i = 0; ctx->deny_users[i] != NULL; i++) {
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin if (string_equal(cs, username, ctx->deny_users[i])) {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin DEBUG(9, ("User [%s] found in deny list, access denied.\n",
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin /* Return immediately on explicit denial */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin if (!ctx->allow_groups && !ctx->deny_groups) {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* There are no group restrictions, so just return
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin * here with whatever we've decided.
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin /* Now get a list of this user's groups and check those against the
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin * simple_allow_groups list.
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin ret = sysdb_search_user_by_name(tmp_ctx, ctx->sysdb,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin DEBUG(1, ("Could not look up username [%s]: [%d][%s]\n",
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin /* Construct a list of the user's groups */
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin el = ldb_msg_find_element(msg, SYSDB_MEMBEROF);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* Get the groups from the memberOf entries
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin * Allocate the array with room for both the NULL
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin * terminator and the primary group
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin groups = talloc_array(tmp_ctx, char *, el->num_values + 2);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* User is not a member of any groups except primary */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* Get the user's primary group */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin ret = sysdb_search_group_by_gid(tmp_ctx, ctx->sysdb,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin DEBUG(1, ("Could not look up primary group [%lu]: [%d][%s]\n",
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* We have to treat this as non-fatal, because the primary
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin * group may be local to the machine and not available in
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin * our ID provider.
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin primary_group = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin groups[j] = talloc_strdup(tmp_ctx, primary_group);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* Now process allow and deny group rules
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin * If access was already granted above, we'll skip
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin * this redundant rule check
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin for(j = 0; groups[j]; j++) {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin if (string_equal(cs, groups[j], ctx->allow_groups[i])) {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* If any group has matched, we can skip out on the
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin * processing early
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* Finally, process the deny group rules */
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin for(j = 0; groups[j]; j++) {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin if (string_equal(cs, groups[j], ctx->deny_groups[i])) {
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin /* If any group has matched, we can skip out on the
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin * processing early
eba7df9ee0a1963984ef212e7ddfc0e0835af288Stéphane Grabervoid simple_access_handler(struct be_req *be_req)
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin pd = talloc_get_type(be_req->req_data, struct pam_data);
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin DEBUG(4, ("simple access does not handles pam task %d.\n", pd->cmd));
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin ctx = talloc_get_type(be_req->be_ctx->bet_info[BET_ACCESS].pvt_bet_data,
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin ret = simple_access_check(ctx, pd->user, &access_granted);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin be_req->fn(be_req, DP_ERR_OK, pd->pam_status, NULL);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalinint sssm_simple_access_init(struct be_ctx *bectx, struct bet_ops **ops,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin ctx = talloc_zero(bectx, struct simple_ctx);
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin ret = confdb_get_string_as_list(bectx->cdb, ctx, bectx->conf_path,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin DEBUG(1, ("confdb_get_string_as_list failed.\n"));
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin ret = confdb_get_string_as_list(bectx->cdb, ctx, bectx->conf_path,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin DEBUG(1, ("confdb_get_string_as_list failed.\n"));
e29bf450cafa2ce2564aeb0b64d2014c17228407Dwight Engen ret = confdb_get_string_as_list(bectx->cdb, ctx, bectx->conf_path,
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin DEBUG(1, ("confdb_get_string_as_list failed.\n"));
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin ret = confdb_get_string_as_list(bectx->cdb, ctx, bectx->conf_path,
b031f0d2ca1b40eab86286b82d3c5e8b379122e6Alexey Shabalin DEBUG(1, ("confdb_get_string_as_list failed.\n"));
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin DEBUG(1, ("No rules supplied for simple access provider. "
262f4e48a51a55ad9cee06abbcfe4a6ad6166f49Alexey Shabalin "Access will be granted for all users.\n"));