diff options
Diffstat (limited to 'src/providers/simple/simple_access.c')
-rw-r--r-- | src/providers/simple/simple_access.c | 228 |
1 files changed, 27 insertions, 201 deletions
diff --git a/src/providers/simple/simple_access.c b/src/providers/simple/simple_access.c index 70d1f0728..d53a04b4d 100644 --- a/src/providers/simple/simple_access.c +++ b/src/providers/simple/simple_access.c @@ -35,227 +35,52 @@ #define CONFDB_SIMPLE_ALLOW_GROUPS "simple_allow_groups" #define CONFDB_SIMPLE_DENY_GROUPS "simple_deny_groups" -errno_t simple_access_check(struct simple_ctx *ctx, const char *username, - bool *access_granted) -{ - int i, j; - errno_t ret; - TALLOC_CTX *tmp_ctx = NULL; - const char *user_attrs[] = { SYSDB_MEMBEROF, - SYSDB_GIDNUM, - NULL }; - const char *group_attrs[] = { SYSDB_NAME, - NULL }; - struct ldb_message *msg; - struct ldb_message_element *el; - char **groups; - const char *primary_group; - gid_t gid; - bool matched; - bool cs = ctx->domain->case_sensitive; - - *access_granted = false; - - /* First, check whether the user is in the allowed users list */ - if (ctx->allow_users != NULL) { - for(i = 0; ctx->allow_users[i] != NULL; i++) { - if (sss_string_equal(cs, username, ctx->allow_users[i])) { - DEBUG(9, ("User [%s] found in allow list, access granted.\n", - username)); - - /* Do not return immediately on explicit allow - * We need to make sure none of the user's groups - * are denied. - */ - *access_granted = true; - } - } - } else if (!ctx->allow_groups) { - /* If neither allow rule is in place, we'll assume allowed - * unless a deny rule disables us below. - */ - *access_granted = true; - } +static void simple_access_check(struct tevent_req *req); - /* Next check whether this user has been specifically denied */ - if (ctx->deny_users != NULL) { - for(i = 0; ctx->deny_users[i] != NULL; i++) { - if (sss_string_equal(cs, username, ctx->deny_users[i])) { - DEBUG(9, ("User [%s] found in deny list, access denied.\n", - username)); - - /* Return immediately on explicit denial */ - *access_granted = false; - return EOK; - } - } - } +void simple_access_handler(struct be_req *be_req) +{ + struct be_ctx *be_ctx = be_req->be_ctx; + struct pam_data *pd; + struct tevent_req *req; + struct simple_ctx *ctx; - if (!ctx->allow_groups && !ctx->deny_groups) { - /* There are no group restrictions, so just return - * here with whatever we've decided. - */ - return EOK; - } + pd = talloc_get_type(be_req->req_data, struct pam_data); - /* Now get a list of this user's groups and check those against the - * simple_allow_groups list. - */ - tmp_ctx = talloc_new(NULL); - if (!tmp_ctx) { - ret = ENOMEM; - goto done; - } + pd->pam_status = PAM_SYSTEM_ERR; - ret = sysdb_search_user_by_name(tmp_ctx, ctx->sysdb, - username, user_attrs, &msg); - if (ret != EOK) { - DEBUG(1, ("Could not look up username [%s]: [%d][%s]\n", - username, ret, strerror(ret))); + if (pd->cmd != SSS_PAM_ACCT_MGMT) { + DEBUG(4, ("simple access does not handles pam task %d.\n", pd->cmd)); + pd->pam_status = PAM_MODULE_UNKNOWN; goto done; } - /* Construct a list of the user's groups */ - el = ldb_msg_find_element(msg, SYSDB_MEMBEROF); - if (el && el->num_values) { - /* Get the groups from the memberOf entries - * Allocate the array with room for both the NULL - * terminator and the primary group - */ - groups = talloc_array(tmp_ctx, char *, el->num_values + 2); - if (!groups) { - ret = ENOMEM; - goto done; - } - - for (j = 0; j < el->num_values; j++) { - ret = sysdb_group_dn_name( - ctx->sysdb, tmp_ctx, - (char *)el->values[j].data, - &groups[j]); - if (ret != EOK) { - goto done; - } - } - } else { - /* User is not a member of any groups except primary */ - groups = talloc_array(tmp_ctx, char *, 2); - if (!groups) { - ret = ENOMEM; - goto done; - } - j = 0; - } + ctx = talloc_get_type(be_req->be_ctx->bet_info[BET_ACCESS].pvt_bet_data, + struct simple_ctx); - /* Get the user's primary group */ - gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0); - if (!gid) { - ret = EINVAL; + req = simple_access_check_send(be_req, be_ctx->ev, ctx, pd->user); + if (!req) { + pd->pam_status = PAM_SYSTEM_ERR; goto done; } - talloc_zfree(msg); - - ret = sysdb_search_group_by_gid(tmp_ctx, ctx->sysdb, - gid, group_attrs, &msg); - if (ret != EOK) { - DEBUG(1, ("Could not look up primary group [%lu]: [%d][%s]\n", - gid, ret, strerror(ret))); - /* We have to treat this as non-fatal, because the primary - * group may be local to the machine and not available in - * our ID provider. - */ - } else { - primary_group = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); - if (!primary_group) { - ret = EINVAL; - goto done; - } - - groups[j] = talloc_strdup(tmp_ctx, primary_group); - if (!groups[j]) { - ret = ENOMEM; - goto done; - } - j++; - - talloc_zfree(msg); - } - - groups[j] = NULL; - - /* Now process allow and deny group rules - * If access was already granted above, we'll skip - * this redundant rule check - */ - if (ctx->allow_groups && !*access_granted) { - matched = false; - for (i = 0; ctx->allow_groups[i]; i++) { - for(j = 0; groups[j]; j++) { - if (sss_string_equal(cs, groups[j], ctx->allow_groups[i])) { - matched = true; - break; - } - } - - /* If any group has matched, we can skip out on the - * processing early - */ - if (matched) { - *access_granted = true; - break; - } - } - } - - /* Finally, process the deny group rules */ - if (ctx->deny_groups) { - matched = false; - for (i = 0; ctx->deny_groups[i]; i++) { - for(j = 0; groups[j]; j++) { - if (sss_string_equal(cs, groups[j], ctx->deny_groups[i])) { - matched = true; - break; - } - } - - /* If any group has matched, we can skip out on the - * processing early - */ - if (matched) { - *access_granted = false; - break; - } - } - } - - ret = EOK; + tevent_req_set_callback(req, simple_access_check, be_req); + return; done: - talloc_free(tmp_ctx); - return ret; + be_req->fn(be_req, DP_ERR_OK, pd->pam_status, NULL); } -void simple_access_handler(struct be_req *be_req) +static void simple_access_check(struct tevent_req *req) { - int ret; bool access_granted = false; + errno_t ret; struct pam_data *pd; - struct simple_ctx *ctx; + struct be_req *be_req; + be_req = tevent_req_callback_data(req, struct be_req); pd = talloc_get_type(be_req->req_data, struct pam_data); - pd->pam_status = PAM_SYSTEM_ERR; - - if (pd->cmd != SSS_PAM_ACCT_MGMT) { - DEBUG(4, ("simple access does not handles pam task %d.\n", pd->cmd)); - pd->pam_status = PAM_MODULE_UNKNOWN; - goto done; - } - - ctx = talloc_get_type(be_req->be_ctx->bet_info[BET_ACCESS].pvt_bet_data, - struct simple_ctx); - - ret = simple_access_check(ctx, pd->user, &access_granted); + ret = simple_access_check_recv(req, &access_granted); + talloc_free(req); if (ret != EOK) { pd->pam_status = PAM_SYSTEM_ERR; goto done; @@ -290,6 +115,7 @@ int sssm_simple_access_init(struct be_ctx *bectx, struct bet_ops **ops, ctx->sysdb = bectx->sysdb; ctx->domain = bectx->domain; + ctx->be_ctx = bectx; /* Users */ ret = confdb_get_string_as_list(bectx->cdb, ctx, bectx->conf_path, |