Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 704998 Details for
Bug 910938
CVE-2013-0287 sssd: simple access provider flaw prevents intended ACL use when client to an AD provider
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
[PATCH 5/5] Resolve GIDs in the simple access provider
0005-Resolve-GIDs-in-the-simple-access-provider.patch (text/plain), 49.22 KB, created by
Jakub Hrozek
on 2013-03-04 14:07:58 UTC
(
hide
)
Description:
[PATCH 5/5] Resolve GIDs in the simple access provider
Filename:
MIME Type:
Creator:
Jakub Hrozek
Created:
2013-03-04 14:07:58 UTC
Size:
49.22 KB
patch
obsolete
>From 14a8749533bae1ed263bdfbf7be10db704ff2bed Mon Sep 17 00:00:00 2001 >From: Jakub Hrozek <jhrozek@redhat.com> >Date: Sat, 23 Feb 2013 10:44:54 +0100 >Subject: [PATCH 5/5] Resolve GIDs in the simple access provider > >--- > Makefile.am | 12 +- > src/providers/simple/simple_access.c | 31 +- > src/providers/simple/simple_access.h | 11 +- > src/providers/simple/simple_access_check.c | 675 ++++++++++++++++++++++++----- > src/tests/simple_access-tests.c | 373 +++++++++++----- > 5 files changed, 869 insertions(+), 233 deletions(-) > >diff --git a/Makefile.am b/Makefile.am >index e0010d85fb7fe991cce84267cd6da2df6780ca3b..00a44556d65bc084f460d31e48f035bdfc7a6407 100644 >--- a/Makefile.am >+++ b/Makefile.am >@@ -1018,15 +1018,21 @@ ad_ldap_opt_tests_LDADD = \ > > simple_access_tests_SOURCES = \ > src/tests/simple_access-tests.c \ >- src/tests/common.c \ >- src/providers/simple/simple_access_check.c >+ src/providers/simple/simple_access_check.c \ >+ src/providers/data_provider_be.c \ >+ src/providers/data_provider_fo.c \ >+ src/providers/data_provider_callbacks.c \ >+ $(SSSD_FAILOVER_OBJ) > simple_access_tests_CFLAGS = \ > $(AM_CFLAGS) \ > $(CHECK_CFLAGS) > simple_access_tests_LDADD = \ > $(SSSD_LIBS) \ >+ $(CARES_LIBS) \ > $(CHECK_LIBS) \ >- libsss_util.la >+ $(PAM_LIBS) \ >+ libsss_util.la \ >+ libsss_test_common.la > > util_tests_SOURCES = \ > src/tests/util-tests.c >diff --git a/src/providers/simple/simple_access.c b/src/providers/simple/simple_access.c >index 3dcea86915c538fc9603647597386690885214b5..e617e93dc7972dbb31b20aac11fa722d0ca7b748 100644 >--- a/src/providers/simple/simple_access.c >+++ b/src/providers/simple/simple_access.c >@@ -32,12 +32,13 @@ > #define CONFDB_SIMPLE_ALLOW_GROUPS "simple_allow_groups" > #define CONFDB_SIMPLE_DENY_GROUPS "simple_deny_groups" > >+static void simple_access_check(struct tevent_req *req); >+ > void simple_access_handler(struct be_req *be_req) > { > struct be_ctx *be_ctx = be_req_get_be_ctx(be_req); >- int ret; >- bool access_granted = false; > struct pam_data *pd; >+ struct tevent_req *req; > struct simple_ctx *ctx; > > pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); >@@ -53,7 +54,30 @@ void simple_access_handler(struct be_req *be_req) > ctx = talloc_get_type(be_ctx->bet_info[BET_ACCESS].pvt_bet_data, > struct simple_ctx); > >- ret = simple_access_check(ctx, pd->user, &access_granted); >+ req = simple_access_check_send(be_req, be_ctx->ev, ctx, pd->user); >+ if (!req) { >+ pd->pam_status = PAM_SYSTEM_ERR; >+ goto done; >+ } >+ tevent_req_set_callback(req, simple_access_check, be_req); >+ return; >+ >+done: >+ be_req_terminate(be_req, DP_ERR_OK, pd->pam_status, NULL); >+} >+ >+static void simple_access_check(struct tevent_req *req) >+{ >+ bool access_granted = false; >+ errno_t ret; >+ struct pam_data *pd; >+ struct be_req *be_req; >+ >+ be_req = tevent_req_callback_data(req, struct be_req); >+ pd = talloc_get_type(be_req_get_data(be_req), struct pam_data); >+ >+ ret = simple_access_check_recv(req, &access_granted); >+ talloc_free(req); > if (ret != EOK) { > pd->pam_status = PAM_SYSTEM_ERR; > goto done; >@@ -87,6 +111,7 @@ int sssm_simple_access_init(struct be_ctx *bectx, struct bet_ops **ops, > } > > ctx->domain = bectx->domain; >+ ctx->be_ctx = bectx; > > /* Users */ > ret = confdb_get_string_as_list(bectx->cdb, ctx, bectx->conf_path, >diff --git a/src/providers/simple/simple_access.h b/src/providers/simple/simple_access.h >index 2ddf27692d6f0d1fccfe30e707e4281d811aaa1b..15dfaceb2d9a6670d3559e4a945c2c7a633fad44 100644 >--- a/src/providers/simple/simple_access.h >+++ b/src/providers/simple/simple_access.h >@@ -26,6 +26,7 @@ > > struct simple_ctx { > struct sss_domain_info *domain; >+ struct be_ctx *be_ctx; > > char **allow_users; > char **deny_users; >@@ -33,6 +34,12 @@ struct simple_ctx { > char **deny_groups; > }; > >-errno_t simple_access_check(struct simple_ctx *ctx, const char *username, >- bool *access_granted); >+struct tevent_req *simple_access_check_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct simple_ctx *ctx, >+ const char *username); >+ >+errno_t simple_access_check_recv(struct tevent_req *req, >+ bool *access_granted); >+ > #endif /* __SIMPLE_ACCESS_H__ */ >diff --git a/src/providers/simple/simple_access_check.c b/src/providers/simple/simple_access_check.c >index cb5f5282597a39876d4cdc359396349bdec29883..eca4e38a6c99cad326c95a4bf96444b6cb7e156c 100644 >--- a/src/providers/simple/simple_access_check.c >+++ b/src/providers/simple/simple_access_check.c >@@ -19,36 +19,40 @@ > along with this program. If not, see <http://www.gnu.org/licenses/>. > */ > >+#include "providers/dp_backend.h" > #include "providers/simple/simple_access.h" > #include "util/sss_utf8.h" > #include "db/sysdb.h" > >-errno_t simple_access_check(struct simple_ctx *ctx, const char *username, >- bool *access_granted) >+static bool >+is_posix(const struct ldb_message *group) > { >- 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; >+ const char *val; >+ >+ val = ldb_msg_find_attr_as_string(group, SYSDB_POSIX, NULL); >+ if (!val || strcasecmp(val, "TRUE") == 0) { >+ /* Groups are posix by default */ >+ return true; >+ } >+ >+ return false; >+} >+ >+/* Returns EOK if the result is definitive, EAGAIN if only partial result >+ */ >+static errno_t >+simple_check_users(struct simple_ctx *ctx, const char *username, >+ bool *access_granted) >+{ >+ int i; > 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", >+ DEBUG(SSSDBG_TRACE_LIBS, >+ ("User [%s] found in allow list, access granted.\n", > username)); > > /* Do not return immediately on explicit allow >@@ -62,6 +66,8 @@ errno_t simple_access_check(struct simple_ctx *ctx, const char *username, > /* If neither allow rule is in place, we'll assume allowed > * unless a deny rule disables us below. > */ >+ DEBUG(SSSDBG_TRACE_LIBS, >+ ("No allow rule, assumuing allow unless explicitly denied\n")); > *access_granted = true; > } > >@@ -69,7 +75,8 @@ errno_t simple_access_check(struct simple_ctx *ctx, const char *username, > 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", >+ DEBUG(SSSDBG_TRACE_LIBS, >+ ("User [%s] found in deny list, access denied.\n", > username)); > > /* Return immediately on explicit denial */ >@@ -79,97 +86,16 @@ errno_t simple_access_check(struct simple_ctx *ctx, const char *username, > } > } > >- if (!ctx->allow_groups && !ctx->deny_groups) { >- /* There are no group restrictions, so just return >- * here with whatever we've decided. >- */ >- return EOK; >- } >- >- /* 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; >- } >- >- ret = sysdb_search_user_by_name(tmp_ctx, ctx->domain->sysdb, ctx->domain, >- username, user_attrs, &msg); >- if (ret != EOK) { >- DEBUG(1, ("Could not look up username [%s]: [%d][%s]\n", >- username, ret, strerror(ret))); >- 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->domain->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; >- } >- >- /* Get the user's primary group */ >- gid = ldb_msg_find_attr_as_uint64(msg, SYSDB_GIDNUM, 0); >- if (!gid) { >- ret = EINVAL; >- goto done; >- } >- talloc_zfree(msg); >- >- ret = sysdb_search_group_by_gid(tmp_ctx, ctx->domain->sysdb, ctx->domain, >- 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; >+ return EAGAIN; >+} >+ >+static errno_t >+simple_check_groups(struct simple_ctx *ctx, const char *username, >+ const char **group_names, bool *access_granted) >+{ >+ bool matched; >+ int i, j; >+ bool cs = ctx->domain->case_sensitive; > > /* Now process allow and deny group rules > * If access was already granted above, we'll skip >@@ -178,8 +104,8 @@ errno_t simple_access_check(struct simple_ctx *ctx, const char *username, > 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])) { >+ for(j = 0; group_names[j]; j++) { >+ if (sss_string_equal(cs, group_names[j], ctx->allow_groups[i])) { > matched = true; > break; > } >@@ -189,6 +115,9 @@ errno_t simple_access_check(struct simple_ctx *ctx, const char *username, > * processing early > */ > if (matched) { >+ DEBUG(SSSDBG_TRACE_LIBS, >+ ("Group [%s] found in allow list, access granted.\n", >+ group_names[j])); > *access_granted = true; > break; > } >@@ -199,8 +128,8 @@ errno_t simple_access_check(struct simple_ctx *ctx, const char *username, > 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])) { >+ for(j = 0; group_names[j]; j++) { >+ if (sss_string_equal(cs, group_names[j], ctx->deny_groups[i])) { > matched = true; > break; > } >@@ -210,15 +139,525 @@ errno_t simple_access_check(struct simple_ctx *ctx, const char *username, > * processing early > */ > if (matched) { >+ DEBUG(SSSDBG_TRACE_LIBS, >+ ("Group [%s] found in deny list, access denied.\n", >+ group_names[j])); > *access_granted = false; > break; > } > } > } > >- ret = EOK; >+ return EOK; >+} >+ >+struct simple_resolve_group_state { >+ gid_t gid; >+ struct simple_ctx *ctx; >+ >+ const char *name; >+}; >+ >+static void simple_resolve_group_callback(struct be_req *be_req, >+ int dp_err, int dp_ret, >+ const char *errstr); >+ >+static struct tevent_req * >+simple_resolve_group_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct simple_ctx *ctx, >+ gid_t gid) >+{ >+ errno_t ret; >+ struct tevent_req *req; >+ struct simple_resolve_group_state *state; >+ struct be_req *be_req; >+ struct be_acct_req *ar; >+ >+ req = tevent_req_create(mem_ctx, &state, >+ struct simple_resolve_group_state); >+ if (!req) return NULL; >+ >+ state->gid = gid; >+ state->ctx = ctx; >+ >+ be_req = be_req_create(state, NULL, ctx->be_ctx, >+ simple_resolve_group_callback, req); >+ if (!be_req) { >+ ret = ENOMEM; >+ goto done; >+ } >+ >+ ar = talloc(be_req, struct be_acct_req); >+ if (!ar) { >+ ret = ENOMEM; >+ goto done; >+ } >+ >+ ar->entry_type = BE_REQ_GROUP; >+ ar->attr_type = BE_ATTR_CORE; >+ ar->filter_type = BE_FILTER_IDNUM; >+ ar->filter_value = talloc_asprintf(ar, "%llu", (unsigned long long) gid); >+ ar->domain = talloc_strdup(ar, ctx->domain->name); >+ if (!ar->domain || !ar->filter_value) { >+ ret = ENOMEM; >+ goto done; >+ } >+ >+ ret = be_file_account_request(be_req, ar); >+ if (ret != EOK) { >+ goto done; >+ } >+ >+ return req; >+ >+done: >+ if (ret == EOK) { >+ tevent_req_done(req); >+ } else { >+ tevent_req_error(req, ret); >+ } >+ tevent_req_post(req, ev); >+ return req; >+} >+ >+static void simple_resolve_group_callback(struct be_req *be_req, >+ int dp_err, int dp_ret, >+ const char *errstr) >+{ >+ struct tevent_req *req; >+ struct simple_resolve_group_state *state; >+ errno_t ret; >+ struct ldb_message *group; >+ const char *group_attrs[] = { SYSDB_NAME, >+ NULL }; >+ >+ req = talloc_get_type(be_req_get_pvt_data(be_req), struct tevent_req); >+ state = tevent_req_data(req, struct simple_resolve_group_state); >+ >+ talloc_free(be_req); >+ >+ /* Check the cache by GID again and fetch the name */ >+ ret = sysdb_search_group_by_gid(state, state->ctx->domain->sysdb, >+ state->ctx->domain, state->gid, >+ group_attrs, &group); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_OP_FAILURE, >+ ("Could not look up group by gid [%lu]: [%d][%s]\n", >+ state->gid, ret, strerror(ret))); >+ tevent_req_error(req, ret); >+ return; >+ } >+ >+ state->name = ldb_msg_find_attr_as_string(group, SYSDB_NAME, NULL); >+ if (!state->name) { >+ DEBUG(SSSDBG_OP_FAILURE, ("No group name after refresh\n")); >+ tevent_req_error(req, ENOENT); >+ return; >+ } >+ >+ tevent_req_done(req); >+} >+ >+static errno_t >+simple_resolve_group_recv(struct tevent_req *req, >+ TALLOC_CTX *mem_ctx, >+ const char **name) >+{ >+ struct simple_resolve_group_state *state; >+ >+ state = tevent_req_data(req, struct simple_resolve_group_state); >+ >+ TEVENT_REQ_RETURN_ON_ERROR(req); >+ >+ *name = talloc_strdup(mem_ctx, state->name); >+ return EOK; >+} >+ >+struct simple_check_groups_state { >+ struct tevent_context *ev; >+ struct simple_ctx *ctx; >+ >+ gid_t *lookup_gids; >+ size_t num_gids; >+ size_t giter; >+ >+ const char **group_names; >+ size_t num_names; >+}; >+ >+static void simple_check_get_groups_next(struct tevent_req *subreq); >+ >+static errno_t >+simple_check_get_groups_primary(struct simple_check_groups_state *state, >+ gid_t gid, >+ struct simple_ctx *ctx, >+ bool *_posix, >+ const char **_name); >+static struct tevent_req * >+simple_check_get_groups_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct simple_ctx *ctx, >+ const char *username) >+{ >+ errno_t ret; >+ struct tevent_req *req; >+ struct tevent_req *subreq; >+ struct simple_check_groups_state *state; >+ const char *attrs[] = { SYSDB_NAME, SYSDB_POSIX, SYSDB_GIDNUM, NULL }; >+ size_t group_count; >+ struct ldb_message *user; >+ struct ldb_message **groups; >+ int i; >+ const char *gname; >+ bool posix; >+ gid_t pgid; >+ char *cname; >+ >+ req = tevent_req_create(mem_ctx, &state, >+ struct simple_check_groups_state); >+ if (!req) return NULL; >+ >+ state->ev = ev; >+ state->ctx = ctx; >+ >+ cname = sss_get_cased_name(state, username, ctx->domain->case_sensitive); >+ if (!cname) { >+ ret = ENOMEM; >+ goto done; >+ } >+ >+ DEBUG(SSSDBG_TRACE_LIBS, ("Looking up groups for user %s\n", cname)); >+ >+ ret = sysdb_search_user_by_name(state, ctx->domain->sysdb, ctx->domain, >+ cname, attrs, &user); >+ if (ret == ENOENT) { >+ DEBUG(SSSDBG_MINOR_FAILURE, ("No such user %s\n", cname)); >+ goto done; >+ } else if (ret != EOK) { >+ DEBUG(SSSDBG_OP_FAILURE, >+ ("Could not look up username [%s]: [%d][%s]\n", >+ username, ret, strerror(ret))); >+ goto done; >+ } >+ >+ pgid = ldb_msg_find_attr_as_uint64(user, SYSDB_GIDNUM, 0); >+ if (!pgid) { >+ DEBUG(SSSDBG_MINOR_FAILURE, ("User %s has no gid?\n", cname)); >+ ret = EINVAL; >+ goto done; >+ } >+ >+ ret = sysdb_asq_search(state, ctx->domain->sysdb, >+ user->dn, NULL, SYSDB_MEMBEROF, >+ attrs, &group_count, &groups); >+ if (ret != EOK) { >+ goto done; >+ } >+ >+ DEBUG(SSSDBG_TRACE_FUNC, >+ ("User %s is a member of %d groups\n", cname, group_count)); >+ >+ /* One extra space for terminator, one extra space for private group */ >+ state->group_names = talloc_zero_array(state, const char *, group_count + 2); >+ state->lookup_gids = talloc_zero_array(state, gid_t, group_count + 2); >+ if (!state->group_names || !state->lookup_gids) { >+ ret = ENOMEM; >+ goto done; >+ } >+ >+ for (i=0; i < group_count; i++) { >+ /* Some providers (like the AD provider) might perform initgroups >+ * without resolving the group names. In order for the simple access >+ * provider to work correctly, we need to resolve the groups before >+ * performing the access check. In AD provider, the situation is >+ * even more tricky b/c the groups HAVE name, but their name >+ * attribute is set to SID and they are set as non-POSIX >+ */ >+ >+ posix = is_posix(groups[i]); >+ gname = ldb_msg_find_attr_as_string(groups[i], SYSDB_NAME, NULL); >+ if (gname && posix) { >+ state->group_names[state->num_names] = talloc_strdup(state->group_names, >+ gname); >+ if (!state->group_names[state->num_names]) { >+ ret = ENOMEM; >+ goto done; >+ } >+ DEBUG(SSSDBG_TRACE_INTERNAL, ("Adding group %s\n", gname)); >+ state->num_names++; >+ } else { >+ /* This group has no name. Add its gid to the list of gids >+ * to resolve */ >+ state->lookup_gids[state->num_gids] = \ >+ ldb_msg_find_attr_as_uint64(groups[i], SYSDB_GIDNUM, 0); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_MINOR_FAILURE, >+ ("A group [%s] has no name and no GID, skipping\n", >+ ldb_dn_get_linearized(groups[i]->dn))); >+ continue; >+ } >+ state->num_gids++; >+ } >+ } >+ >+ ret = simple_check_get_groups_primary(state, pgid, ctx, &posix, &gname); >+ if (ret != EOK) { >+ goto done; >+ } >+ >+ if (gname && posix) { >+ state->group_names[state->num_names] = talloc_strdup(state->group_names, >+ gname); >+ if (state->group_names[state->num_names] == NULL) { >+ ret = ENOMEM; >+ goto done; >+ } >+ DEBUG(SSSDBG_TRACE_INTERNAL, ("Adding primay group %s\n", gname)); >+ state->num_names++; >+ } else { >+ state->lookup_gids[state->num_gids] = pgid; >+ state->num_gids++; >+ } >+ >+ if (state->num_gids == 0) { >+ /* If all groups could have been resolved by name, we are >+ * done >+ */ >+ DEBUG(SSSDBG_TRACE_FUNC, ("All groups had name attribute\n")); >+ ret = EOK; >+ goto done; >+ } >+ >+ DEBUG(SSSDBG_TRACE_FUNC, ("Need to resolve %d groups\n", state->num_gids)); >+ state->giter = 0; >+ subreq = simple_resolve_group_send(req, state->ev, state->ctx, >+ state->lookup_gids[state->giter]); >+ if (!subreq) { >+ ret = ENOMEM; >+ goto done; >+ } >+ tevent_req_set_callback(subreq, simple_check_get_groups_next, req); >+ >+ return req; > > done: >- talloc_free(tmp_ctx); >- return ret; >+ if (ret == EOK) { >+ tevent_req_done(req); >+ } else { >+ tevent_req_error(req, ret); >+ } >+ tevent_req_post(req, ev); >+ return req; >+} >+ >+static void simple_check_get_groups_next(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = >+ tevent_req_callback_data(subreq, struct tevent_req); >+ struct simple_check_groups_state *state = >+ tevent_req_data(req, struct simple_check_groups_state); >+ errno_t ret; >+ >+ ret = simple_resolve_group_recv(subreq, state, >+ &state->group_names[state->num_names]); >+ talloc_zfree(subreq); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_OP_FAILURE, >+ ("Could not resolve name of group with GID %llu\n", >+ state->lookup_gids[state->giter])); >+ tevent_req_error(req, ret); >+ return; >+ } >+ state->num_names++; >+ >+ if (state->giter < state->num_gids) { >+ state->giter++; >+ subreq = simple_resolve_group_send(req, state->ev, state->ctx, >+ state->lookup_gids[state->giter]); >+ if (!subreq) { >+ tevent_req_error(req, ENOMEM); >+ return; >+ } >+ tevent_req_set_callback(subreq, simple_check_get_groups_next, req); >+ return; >+ } >+ >+ DEBUG(SSSDBG_TRACE_INTERNAL, ("All groups resolved. Done.\n")); >+ tevent_req_done(req); >+} >+ >+static errno_t >+simple_check_get_groups_primary(struct simple_check_groups_state *state, >+ gid_t gid, >+ struct simple_ctx *ctx, >+ bool *_posix, >+ const char **_name) >+{ >+ errno_t ret; >+ const char *group_attrs[] = { SYSDB_NAME, SYSDB_POSIX, NULL }; >+ const char *primary_group = NULL; >+ struct ldb_message *msg; >+ bool posix = true; >+ >+ ret = sysdb_search_group_by_gid(state, ctx->domain->sysdb, ctx->domain, >+ gid, group_attrs, &msg); >+ if (ret != EOK) { >+ DEBUG(SSSDBG_OP_FAILURE, >+ ("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) { >+ return EINVAL; >+ } >+ posix = is_posix(msg); >+ talloc_zfree(msg); >+ } >+ >+ *_posix = posix; >+ *_name = primary_group; >+ return EOK; >+} >+ >+static errno_t >+simple_check_get_groups_recv(struct tevent_req *req, >+ TALLOC_CTX *mem_ctx, >+ const char ***_group_names) >+{ >+ struct simple_check_groups_state *state; >+ >+ state = tevent_req_data(req, struct simple_check_groups_state); >+ >+ TEVENT_REQ_RETURN_ON_ERROR(req); >+ >+ *_group_names = talloc_steal(mem_ctx, state->group_names); >+ return EOK; >+} >+ >+struct simple_access_check_state { >+ bool access_granted; >+ struct simple_ctx *ctx; >+ const char *username; >+ >+ const char **group_names; >+}; >+ >+static void simple_access_check_done(struct tevent_req *subreq); >+ >+struct tevent_req *simple_access_check_send(TALLOC_CTX *mem_ctx, >+ struct tevent_context *ev, >+ struct simple_ctx *ctx, >+ const char *username) >+{ >+ errno_t ret; >+ struct tevent_req *req; >+ struct tevent_req *subreq; >+ struct simple_access_check_state *state; >+ >+ req = tevent_req_create(mem_ctx, &state, >+ struct simple_access_check_state); >+ if (!req) return NULL; >+ >+ state->access_granted = false; >+ state->ctx = ctx; >+ state->username = talloc_strdup(state, username); >+ if (!state->username) { >+ ret = ENOMEM; >+ goto immediate; >+ } >+ >+ DEBUG(SSSDBG_FUNC_DATA, ("Simple access check for %s\n", username)); >+ >+ ret = simple_check_users(ctx, username, &state->access_granted); >+ if (ret != EAGAIN) { >+ /* Both access denied and an error */ >+ goto immediate; >+ } >+ >+ if (!ctx->allow_groups && !ctx->deny_groups) { >+ /* There are no group restrictions, so just return >+ * here with whatever we've decided. >+ */ >+ DEBUG(SSSDBG_TRACE_LIBS, ("No group restrictions, end request\n")); >+ ret = EOK; >+ goto immediate; >+ } >+ >+ /* The group names might not be available. Fire a request to >+ * gather them. In most cases, the request will just shortcut >+ */ >+ subreq = simple_check_get_groups_send(state, ev, ctx, username); >+ if (!subreq) { >+ ret = EIO; >+ goto immediate; >+ } >+ tevent_req_set_callback(subreq, simple_access_check_done, req); >+ >+ return req; >+ >+immediate: >+ if (ret == EOK) { >+ tevent_req_done(req); >+ } else { >+ tevent_req_error(req, ret); >+ } >+ tevent_req_post(req, ev); >+ return req; >+} >+ >+ >+static void simple_access_check_done(struct tevent_req *subreq) >+{ >+ struct tevent_req *req = >+ tevent_req_callback_data(subreq, struct tevent_req); >+ struct simple_access_check_state *state = >+ tevent_req_data(req, struct simple_access_check_state); >+ errno_t ret; >+ >+ /* We know the names now. Run the check. */ >+ ret = simple_check_get_groups_recv(subreq, state, &state->group_names); >+ talloc_zfree(subreq); >+ if (ret == ENOENT) { >+ /* If the user wasn't found, just shortcut */ >+ state->access_granted = false; >+ tevent_req_done(req); >+ return; >+ } else if (ret != EOK) { >+ DEBUG(SSSDBG_OP_FAILURE, >+ ("Could not collect groups of user %s\n", state->username)); >+ tevent_req_error(req, ret); >+ return; >+ } >+ >+ ret = simple_check_groups(state->ctx, state->username, >+ state->group_names, &state->access_granted); >+ if (ret != EOK) { >+ tevent_req_error(req, ret); >+ return; >+ } >+ >+ /* Now just return whatever we decided */ >+ DEBUG(SSSDBG_TRACE_INTERNAL, ("Group check done\n")); >+ tevent_req_done(req); >+} >+ >+errno_t simple_access_check_recv(struct tevent_req *req, bool *access_granted) >+{ >+ struct simple_access_check_state *state = >+ tevent_req_data(req, struct simple_access_check_state); >+ >+ TEVENT_REQ_RETURN_ON_ERROR(req); >+ >+ DEBUG(SSSDBG_TRACE_LIBS, >+ ("Access %sgranted\n", state->access_granted ? "" : "not ")); >+ if (access_granted) { >+ *access_granted = state->access_granted; >+ } >+ >+ return EOK; > } >diff --git a/src/tests/simple_access-tests.c b/src/tests/simple_access-tests.c >index 19c72b66e2db30262d99c3a677f6fbc6256da64f..1c2d1a9ea83a005ecb3a8ecc847df496f383961f 100644 >--- a/src/tests/simple_access-tests.c >+++ b/src/tests/simple_access-tests.c >@@ -35,16 +35,40 @@ > > const char *ulist_1[] = {"u1", "u2", NULL}; > const char *glist_1[] = {"g1", "g2", NULL}; >+const char *glist_1_case[] = {"G1", "G2", NULL}; > > struct simple_test_ctx *test_ctx = NULL; > > struct simple_test_ctx { > struct sysdb_ctx *sysdb; > struct confdb_ctx *confdb; >+ struct tevent_context *ev; >+ bool done; >+ int error; > >+ bool access_granted; > struct simple_ctx *ctx; > }; > >+static int test_loop(struct simple_test_ctx *tctx) >+{ >+ while (!tctx->done) >+ tevent_loop_once(tctx->ev); >+ >+ return tctx->error; >+} >+ >+static void simple_access_check_done(struct tevent_req *req) >+{ >+ struct simple_test_ctx *tctx = >+ tevent_req_callback_data(req, struct simple_test_ctx); >+ >+ >+ tctx->error = simple_access_check_recv(req, &tctx->access_granted); >+ talloc_free(req); >+ tctx->done = true; >+} >+ > void setup_simple(void) > { > errno_t ret; >@@ -52,19 +76,22 @@ void setup_simple(void) > const char *val[2]; > val[1] = NULL; > >- /* Create tests directory if it doesn't exist */ >- /* (relative to current dir) */ >- ret = mkdir(TESTS_PATH, 0775); >- fail_if(ret == -1 && errno != EEXIST, >- "Could not create %s directory", TESTS_PATH); >- > fail_unless(test_ctx == NULL, "Simple context already initialized."); > test_ctx = talloc_zero(NULL, struct simple_test_ctx); > fail_unless(test_ctx != NULL, "Cannot create simple test context."); > >+ test_ctx->ev = tevent_context_init(test_ctx); >+ fail_unless(test_ctx->ev != NULL, "Cannot create tevent context."); >+ > test_ctx->ctx = talloc_zero(test_ctx, struct simple_ctx); > fail_unless(test_ctx->ctx != NULL, "Cannot create simple context."); > >+ /* Create tests directory if it doesn't exist */ >+ /* (relative to current dir) */ >+ ret = mkdir(TESTS_PATH, 0775); >+ fail_if(ret == -1 && errno != EEXIST, >+ "Could not create %s directory", TESTS_PATH); >+ > conf_db = talloc_asprintf(test_ctx, "%s/%s", TESTS_PATH, TEST_CONF_FILE); > fail_if(conf_db == NULL, "Out of memory, aborting!"); > DEBUG(SSSDBG_TRACE_LIBS, ("CONFDB: %s\n", conf_db)); >@@ -98,7 +125,7 @@ void setup_simple(void) > fail_if(ret != EOK, "Could not initialize connection to the sysdb (%d)", ret); > test_ctx->sysdb = test_ctx->ctx->domain->sysdb; > test_ctx->ctx->domain->case_sensitive = true; >- >+ test_ctx->ctx->domain->mpg = false; /* Simulate an LDAP domain better */ > } > > void teardown_simple(void) >@@ -118,18 +145,22 @@ void setup_simple_group(void) > > /* Add test users u1 and u2 that would be members of test groups > * g1 and g2 respectively */ >+ ret = sysdb_add_group(test_ctx->sysdb, test_ctx->ctx->domain, >+ "pvt", 999, NULL, 0, 0); >+ fail_if(ret != EOK, "Could not add private group"); >+ > ret = sysdb_store_user(test_ctx->sysdb, test_ctx->ctx->domain, >- "u1", NULL, 123, 0, "u1", "/home/u1", >+ "u1", NULL, 123, 999, "u1", "/home/u1", > "/bin/bash", NULL, NULL, NULL, -1, 0); > fail_if(ret != EOK, "Could not add u1"); > > ret = sysdb_store_user(test_ctx->sysdb, test_ctx->ctx->domain, >- "u2", NULL, 456, 0, "u1", "/home/u1", >+ "u2", NULL, 456, 999, "u1", "/home/u1", > "/bin/bash", NULL, NULL, NULL, -1, 0); > fail_if(ret != EOK, "Could not add u2"); > > ret = sysdb_store_user(test_ctx->sysdb, test_ctx->ctx->domain, >- "u3", NULL, 789, 0, "u1", "/home/u1", >+ "u3", NULL, 789, 999, "u1", "/home/u1", > "/bin/bash", NULL, NULL, NULL, -1, 0); > fail_if(ret != EOK, "Could not add u3"); > >@@ -164,190 +195,317 @@ void teardown_simple_group(void) > fail_if(ret != EOK, "Could not delete g1"); > ret = sysdb_delete_group(test_ctx->sysdb, test_ctx->ctx->domain, "g2", 0); > fail_if(ret != EOK, "Could not delete g2"); >+ ret = sysdb_delete_group(test_ctx->sysdb, test_ctx->ctx->domain, "pvt", 0); >+ fail_if(ret != EOK, "Could not delete pvt"); > > teardown_simple(); > } > > START_TEST(test_both_empty) > { >- int ret; >- bool access_granted = false; >+ struct tevent_req *req; > > test_ctx->ctx->allow_users = NULL; > test_ctx->ctx->deny_users = NULL; > >- ret = simple_access_check(test_ctx->ctx, "u1", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == true, "Access denied " >- "while both lists are empty."); >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u1"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == true, >+ "Access denied while both lists are empty."); > } > END_TEST > > START_TEST(test_allow_empty) > { >- int ret; >- bool access_granted = true; >+ struct tevent_req *req; > > test_ctx->ctx->allow_users = NULL; > test_ctx->ctx->deny_users = discard_const(ulist_1); > >- ret = simple_access_check(test_ctx->ctx, "u1", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == false, "Access granted " >- "while user is in deny list."); >- >- ret = simple_access_check(test_ctx->ctx, "u3", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == true, "Access denied " >- "while user is not in deny list."); >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u1"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ test_ctx->done = false; >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == false, >+ "Access granted while user is in deny list."); >+ >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u3"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == true, >+ "Access denied while user is not in deny list."); > } > END_TEST > > START_TEST(test_deny_empty) > { >- int ret; >- bool access_granted = false; >+ struct tevent_req *req; > > test_ctx->ctx->allow_users = discard_const(ulist_1); > test_ctx->ctx->deny_users = NULL; > >- ret = simple_access_check(test_ctx->ctx, "u1", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == true, "Access denied " >- "while user is in allow list."); >- >- ret = simple_access_check(test_ctx->ctx, "u3", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == false, "Access granted " >- "while user is not in allow list."); >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u1"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ test_ctx->done = false; >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == true, >+ "Access denied while user is in allow list."); >+ >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u3"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == false, >+ "Access granted while user is not in allow list."); > } > END_TEST > > START_TEST(test_both_set) > { >- int ret; >- bool access_granted = false; >+ struct tevent_req *req; > > test_ctx->ctx->allow_users = discard_const(ulist_1); > test_ctx->ctx->deny_users = discard_const(ulist_1); > >- ret = simple_access_check(test_ctx->ctx, "u1", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == false, "Access granted " >- "while user is in deny list."); >- >- ret = simple_access_check(test_ctx->ctx, "u3", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == false, "Access granted " >- "while user is not in allow list."); >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u1"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ test_ctx->done = false; >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == false, >+ "Access granted while user is in deny list."); >+ >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u3"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == false, >+ "Access granted while user is not in allow list."); > } > END_TEST > > START_TEST(test_case) > { >- int ret; >- bool access_granted = false; >+ struct tevent_req *req; > > test_ctx->ctx->allow_users = discard_const(ulist_1); > test_ctx->ctx->deny_users = NULL; > >- ret = simple_access_check(test_ctx->ctx, "U1", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == false, "Access granted " >- "for user with different case " >- "in case-sensitive domain"); >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "U1"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ test_ctx->done = false; >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == false, >+ "Access granted for user with different case " >+ "in case-sensitive domain"); > > test_ctx->ctx->domain->case_sensitive = false; > >- ret = simple_access_check(test_ctx->ctx, "U1", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == true, "Access denied " >- "for user with different case " >- "in case-insensitive domain"); >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "U1"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ test_ctx->done = false; >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == true, >+ "Access denied for user with different case " >+ "in case-sensitive domain"); > } > END_TEST > >+START_TEST(test_unknown_user) >+{ >+ struct tevent_req *req; >+ >+ test_ctx->ctx->allow_users = discard_const(ulist_1); >+ test_ctx->ctx->deny_users = NULL; >+ >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "foo"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ test_ctx->done = false; >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == false, >+ "Access granted for user not present in domain"); >+} >+END_TEST >+ >+ > START_TEST(test_group_allow_empty) > { >- int ret; >- bool access_granted = true; >+ struct tevent_req *req; > > test_ctx->ctx->allow_groups = NULL; > test_ctx->ctx->deny_groups = discard_const(glist_1); > >- ret = simple_access_check(test_ctx->ctx, "u1", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == false, "Access granted " >- "while group is in deny list."); >- >- ret = simple_access_check(test_ctx->ctx, "u3", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == true, "Access denied " >- "while group is not in deny list."); >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u1"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ test_ctx->done = false; >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == false, >+ "Access granted while group is in deny list."); >+ >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u3"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == true, >+ "Access denied while group is not in deny list."); > } > END_TEST > > START_TEST(test_group_deny_empty) > { >- int ret; >- bool access_granted = false; >+ struct tevent_req *req; > > test_ctx->ctx->allow_groups = discard_const(glist_1); > test_ctx->ctx->deny_groups = NULL; > >- ret = simple_access_check(test_ctx->ctx, "u1", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == true, "Access denied " >- "while group is in allow list."); >- >- ret = simple_access_check(test_ctx->ctx, "u3", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == false, "Access granted " >- "while group is not in allow list."); >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u1"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ test_ctx->done = false; >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == true, >+ "Access denied while user is in allow list."); >+ >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u3"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == false, >+ "Access granted while user is not in allow list."); > } > END_TEST > > START_TEST(test_group_both_set) > { >- int ret; >- bool access_granted = false; >+ struct tevent_req *req; > > test_ctx->ctx->allow_groups = discard_const(ulist_1); > test_ctx->ctx->deny_groups = discard_const(ulist_1); > >- ret = simple_access_check(test_ctx->ctx, "u1", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == false, "Access granted " >- "while group is in deny list."); >- >- ret = simple_access_check(test_ctx->ctx, "u3", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == false, "Access granted " >- "while group is not in allow list."); >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u1"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ test_ctx->done = false; >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == false, >+ "Access granted while user is in deny list."); >+ >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "u3"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == false, >+ "Access granted while user is not in allow list."); > } > END_TEST > > START_TEST(test_group_case) > { >- int ret; >- bool access_granted = false; >+ struct tevent_req *req; > >- test_ctx->ctx->allow_groups = discard_const(ulist_1); >+ test_ctx->ctx->allow_groups = discard_const(glist_1_case); > test_ctx->ctx->deny_groups = NULL; > >- ret = simple_access_check(test_ctx->ctx, "U1", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == false, "Access granted " >- "for group with different case " >- "in case-sensitive domain"); >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "U1"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ test_ctx->done = false; >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == false, >+ "Access granted for user with different case " >+ "in case-sensitive domain"); > > test_ctx->ctx->domain->case_sensitive = false; > >- ret = simple_access_check(test_ctx->ctx, "U1", &access_granted); >- fail_unless(ret == EOK, "access_simple_check failed."); >- fail_unless(access_granted == true, "Access denied " >- "for group with different case " >- "in case-insensitive domain"); >+ req = simple_access_check_send(test_ctx, test_ctx->ev, >+ test_ctx->ctx, "U1"); >+ fail_unless(test_ctx != NULL, "Cannot create request\n"); >+ tevent_req_set_callback(req, simple_access_check_done, test_ctx); >+ >+ test_loop(test_ctx); >+ test_ctx->done = false; >+ >+ fail_unless(test_ctx->error == EOK, "access_simple_check failed."); >+ fail_unless(test_ctx->access_granted == true, >+ "Access denied for user with different case " >+ "in case-sensitive domain"); > } > END_TEST > >@@ -362,6 +520,7 @@ Suite *access_simple_suite (void) > tcase_add_test(tc_allow_deny, test_deny_empty); > tcase_add_test(tc_allow_deny, test_both_set); > tcase_add_test(tc_allow_deny, test_case); >+ tcase_add_test(tc_allow_deny, test_unknown_user); > suite_add_tcase(s, tc_allow_deny); > > TCase *tc_grp_allow_deny = tcase_create("group allow/deny"); >-- >1.8.1.2 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 910938
:
704993
|
704995
|
704996
|
704997
|
704998
|
705198
|
705200
|
705201
|
705202