|
|
905b4d |
From 663fb2625181ca8b80d26526a8298674ab6242a1 Mon Sep 17 00:00:00 2001
|
|
|
905b4d |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
905b4d |
Date: Sun, 23 Nov 2014 19:43:04 +0100
|
|
|
905b4d |
Subject: [PATCH 116/117] PAM: Check for trusted domain before sending the
|
|
|
905b4d |
request to BE
|
|
|
905b4d |
|
|
|
905b4d |
https://fedorahosted.org/sssd/ticket/2501
|
|
|
905b4d |
|
|
|
905b4d |
Moving the checks to one place has the advantage of not duplicating
|
|
|
905b4d |
security decisions. Previously, the checks were scattered all over the
|
|
|
905b4d |
responder code, making testing hard.
|
|
|
905b4d |
|
|
|
905b4d |
The disadvantage is that we actually check for the presence of the user,
|
|
|
905b4d |
which might trigger some back end lookups. But I think the benefits
|
|
|
905b4d |
overweight the disadvantage.
|
|
|
905b4d |
|
|
|
905b4d |
Also only check the requested domains from a trusted client. An untrusted
|
|
|
905b4d |
client should simply have no say in what domains he wants to talk to, it
|
|
|
905b4d |
should ignore the 'domains' option.
|
|
|
905b4d |
|
|
|
905b4d |
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
|
|
905b4d |
---
|
|
|
905b4d |
src/responder/pam/pamsrv_cmd.c | 67 ++++++++++++++++--------------------------
|
|
|
905b4d |
1 file changed, 26 insertions(+), 41 deletions(-)
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
|
|
|
905b4d |
index dd0e6e4cf54e6d98da807808ad6973dddc013413..b60ccba2d4ff669e7ed0252923a53755410851e3 100644
|
|
|
905b4d |
--- a/src/responder/pam/pamsrv_cmd.c
|
|
|
905b4d |
+++ b/src/responder/pam/pamsrv_cmd.c
|
|
|
905b4d |
@@ -898,17 +898,6 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- /* Untrusted users can access only public domains. */
|
|
|
905b4d |
- if (!pctx->is_uid_trusted &&
|
|
|
905b4d |
- !is_domain_public(pd->domain, pctx->public_domains,
|
|
|
905b4d |
- pctx->public_domains_count)) {
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
905b4d |
- "Untrusted user %"PRIu32" cannot access unpublic domain %s.\n",
|
|
|
905b4d |
- cctx->client_euid, pd->domain);
|
|
|
905b4d |
- ret = EPERM;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout,
|
|
|
905b4d |
preq->domain, pd->user);
|
|
|
905b4d |
if (ncret == EEXIST) {
|
|
|
905b4d |
@@ -916,34 +905,12 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
|
|
|
905b4d |
ret = ENOENT;
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
-
|
|
|
905b4d |
- /* skip this domain if not requested */
|
|
|
905b4d |
- if (!is_domain_requested(pd, pd->domain)) {
|
|
|
905b4d |
- ret = ENOENT;
|
|
|
905b4d |
- goto done;
|
|
|
905b4d |
- }
|
|
|
905b4d |
} else {
|
|
|
905b4d |
for (dom = preq->cctx->rctx->domains;
|
|
|
905b4d |
dom;
|
|
|
905b4d |
dom = get_next_domain(dom, false)) {
|
|
|
905b4d |
if (dom->fqnames) continue;
|
|
|
905b4d |
|
|
|
905b4d |
- /* Untrusted users can access only public domains. */
|
|
|
905b4d |
- if (!pctx->is_uid_trusted &&
|
|
|
905b4d |
- !is_domain_public(dom->name, pctx->public_domains,
|
|
|
905b4d |
- pctx->public_domains_count)) {
|
|
|
905b4d |
- DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
905b4d |
- "Untrusted user %"PRIu32" cannot access unpublic domain %s."
|
|
|
905b4d |
- " Trying next domain.\n",
|
|
|
905b4d |
- cctx->client_euid, dom->name);
|
|
|
905b4d |
- continue;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
- /* skip this domain if not requested */
|
|
|
905b4d |
- if (!is_domain_requested(pd, dom->name)) {
|
|
|
905b4d |
- continue;
|
|
|
905b4d |
- }
|
|
|
905b4d |
-
|
|
|
905b4d |
ncret = sss_ncache_check_user(pctx->ncache, pctx->neg_timeout,
|
|
|
905b4d |
dom, pd->user);
|
|
|
905b4d |
if (ncret == ENOENT) {
|
|
|
905b4d |
@@ -959,7 +926,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd)
|
|
|
905b4d |
"Trying next domain.\n", pd->user, dom->name);
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- if (!dom || !is_domain_requested(pd, dom->name)) {
|
|
|
905b4d |
+ if (!dom) {
|
|
|
905b4d |
ret = ENOENT;
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
@@ -1055,14 +1022,9 @@ static int pam_check_user_search(struct pam_auth_req *preq)
|
|
|
905b4d |
|
|
|
905b4d |
while (dom) {
|
|
|
905b4d |
/* if it is a domainless search, skip domains that require fully
|
|
|
905b4d |
- * qualified names instead, also untrusted users can access only
|
|
|
905b4d |
- * public domains */
|
|
|
905b4d |
+ * qualified names instead */
|
|
|
905b4d |
while (dom && !preq->pd->domain && !preq->pd->name_is_upn
|
|
|
905b4d |
- && (dom->fqnames ||
|
|
|
905b4d |
- (!pctx->is_uid_trusted &&
|
|
|
905b4d |
- !is_domain_public(dom->name,
|
|
|
905b4d |
- pctx->public_domains,
|
|
|
905b4d |
- pctx->public_domains_count)))) {
|
|
|
905b4d |
+ && dom->fqnames) {
|
|
|
905b4d |
dom = get_next_domain(dom, false);
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
@@ -1334,11 +1296,34 @@ done:
|
|
|
905b4d |
static void pam_dom_forwarder(struct pam_auth_req *preq)
|
|
|
905b4d |
{
|
|
|
905b4d |
int ret;
|
|
|
905b4d |
+ struct pam_ctx *pctx =
|
|
|
905b4d |
+ talloc_get_type(preq->cctx->rctx->pvt_ctx, struct pam_ctx);
|
|
|
905b4d |
|
|
|
905b4d |
if (!preq->pd->domain) {
|
|
|
905b4d |
preq->pd->domain = preq->domain->name;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
+ /* Untrusted users can access only public domains. */
|
|
|
905b4d |
+ if (!pctx->is_uid_trusted &&
|
|
|
905b4d |
+ !is_domain_public(preq->pd->domain, pctx->public_domains,
|
|
|
905b4d |
+ pctx->public_domains_count)) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
905b4d |
+ "Untrusted user %"PRIu32" cannot access non-public domain %s.\n",
|
|
|
905b4d |
+ preq->cctx->client_euid, preq->pd->domain);
|
|
|
905b4d |
+ preq->pd->pam_status = PAM_PERM_DENIED;
|
|
|
905b4d |
+ pam_reply(preq);
|
|
|
905b4d |
+ return;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ /* skip this domain if not requested and the user is trusted
|
|
|
905b4d |
+ * as untrusted users can't request a domain */
|
|
|
905b4d |
+ if (pctx->is_uid_trusted &&
|
|
|
905b4d |
+ !is_domain_requested(preq->pd, preq->pd->domain)) {
|
|
|
905b4d |
+ preq->pd->pam_status = PAM_USER_UNKNOWN;
|
|
|
905b4d |
+ pam_reply(preq);
|
|
|
905b4d |
+ return;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
if (!NEED_CHECK_PROVIDER(preq->domain->provider)) {
|
|
|
905b4d |
preq->callback = pam_reply;
|
|
|
905b4d |
ret = LOCAL_pam_handler(preq);
|
|
|
905b4d |
--
|
|
|
905b4d |
1.9.3
|
|
|
905b4d |
|