URL: https://github.com/SSSD/sssd/pull/31
Author: sumit-bose
 Title: #31: nss: allow UPNs in SSS_NSS_GETSIDBYNAME and SSS_NSS_GETORIGBYNAME
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/31/head:pr31
git checkout pr31
From 27757f7c99f29d1b6392487547b3597e4f185203 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sb...@redhat.com>
Date: Wed, 21 Sep 2016 13:23:52 +0200
Subject: [PATCH] nss: allow UPNs in SSS_NSS_GETSIDBYNAME and
 SSS_NSS_GETORIGBYNAME

When adding support for UPNs, email addresses and aliases the
SSS_NSS_GETSIDBYNAME and SSS_NSS_GETORIGBYNAME request were forgotten.
This patch adds the missing support because it might be irritating if
getpwnam() can resolve the name but the other requests fail. The same
logic as for the plain user lookup is used, this add some code
duplication which is expected to be removed when the nss responder will
be switched to use the new cache_req code.

Resolves https://fedorahosted.org/sssd/ticket/3194
---
 src/responder/nss/nsssrv_cmd.c | 76 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 66 insertions(+), 10 deletions(-)

diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index b64cea2..dcb3bcb 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -1190,6 +1190,13 @@ static int nss_cmd_assume_upn(struct nss_dom_ctx *dctx)
             ret = nss_cmd_initgr_send_reply(dctx);
         }
         break;
+    case SSS_NSS_GETSIDBYNAME:
+    case SSS_NSS_GETORIGBYNAME:
+        ret = nss_cmd_getsidby_search(dctx);
+        if (ret == EOK) {
+            ret = nss_cmd_getbysid_send_reply(dctx);
+        }
+        break;
     default:
         DEBUG(SSSDBG_CRIT_FAILURE, "Invalid command [%d][%s].\n",
               dctx->cmdctx->cmd, sss_cmd2str(dctx->cmdctx->cmd));
@@ -1660,6 +1667,8 @@ static void nss_cmd_getbynam_done(struct tevent_req *req)
                                      cctx->rctx->default_domain, rawname,
                                      &domname, &cmdctx->name);
     if (ret == EAGAIN && (dctx->cmdctx->cmd == SSS_NSS_GETPWNAM
+                            || dctx->cmdctx->cmd == SSS_NSS_GETSIDBYNAME
+                            || dctx->cmdctx->cmd == SSS_NSS_GETORIGBYNAME
                             || dctx->cmdctx->cmd == SSS_NSS_INITGR)) {
         /* assume Kerberos principal */
         ret = nss_cmd_assume_upn(dctx);
@@ -4332,6 +4341,9 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
     char *req_name;
     uint32_t req_id;
     enum sss_dp_acct_type req_type;
+    const char *extra_flag = NULL;
+    char *neg_cache_name;
+    const char *sysdb_name;
 
     nctx = talloc_get_type(cctx->rctx->pvt_ctx, struct nss_ctx);
 
@@ -4355,7 +4367,8 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
         } else {
            /* if it is a domainless search, skip domains that require fully
             * qualified names instead */
-            while (dom && cmdctx->check_next && dom->fqnames) {
+            while (dom && cmdctx->check_next && dom->fqnames
+                    && !cmdctx->name_is_upn) {
                 dom = get_next_domain(dom, 0);
             }
 
@@ -4397,20 +4410,28 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
         } else {
             talloc_free(name);
 
-            name = sss_resp_create_fqname(cmdctx, nctx->rctx, dom, false, cmdctx->name);
+            name = sss_resp_create_fqname(cmdctx, nctx->rctx, dom,
+                                          cmdctx->name_is_upn, cmdctx->name);
             if (name == NULL) {
                 DEBUG(SSSDBG_OP_FAILURE, "sss_get_cased_name failed.\n");
                 ret = ENOMEM;
                 goto done;
             }
 
+            if (cmdctx->name_is_upn) {
+                neg_cache_name = talloc_asprintf(name, "@%s", name);
+            } else {
+                neg_cache_name = name;
+            }
+
             /* verify this name has not yet been negatively cached, as user
              * and groupm, or has been permanently filtered */
-            ret = sss_ncache_check_user(nctx->rctx->ncache, dom, cmdctx->name);
+            ret = sss_ncache_check_user(nctx->rctx->ncache, dom,
+                                        neg_cache_name);
 
             if (ret == EEXIST) {
                 ret = sss_ncache_check_group(nctx->rctx->ncache,
-                                             dom, cmdctx->name);
+                                             dom, neg_cache_name);
                 if (ret == EEXIST) {
                     /* if neg cached, return we didn't find it */
                     DEBUG(SSSDBG_TRACE_FUNC,
@@ -4418,7 +4439,11 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
                            name, dom->name);
                     /* if a multidomain search, try with next */
                     if (cmdctx->check_next) {
-                        dom = get_next_domain(dom, 0);
+                        if (cmdctx->name_is_upn) {
+                            dom = get_next_domain(dom, SSS_GND_DESCEND);
+                        } else {
+                            dom = get_next_domain(dom, 0);
+                        }
                         continue;
                     }
                     /* There are no further domains or this was a
@@ -4481,8 +4506,11 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
                 }
             }
         } else {
-            ret = sysdb_search_user_by_name(cmdctx, dom, name, attrs,
-                                            &msg);
+            if (cmdctx->name_is_upn) {
+                ret = sysdb_search_user_by_upn(cmdctx, dom, name, attrs, &msg);
+            } else {
+                ret = sysdb_search_user_by_name(cmdctx, dom, name, attrs, &msg);
+            }
             if (ret != EOK && ret != ENOENT) {
                 DEBUG(SSSDBG_CRIT_FAILURE,
                       "Failed to make request to our cache!\n");
@@ -4492,6 +4520,28 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
 
             if (ret == EOK) {
                 user_found = true;
+
+                if (cmdctx->name_is_upn) {
+                    /* Since sysdb_search_user_by_upn() searches the whole
+                     * cache we have to set the domain so that it matches the
+                     * result. */
+                    sysdb_name = ldb_msg_find_attr_as_string(msg, SYSDB_NAME,
+                                                             NULL);
+                    if (sysdb_name == NULL) {
+                        DEBUG(SSSDBG_CRIT_FAILURE,
+                              "Cached entry has no name.\n");
+                        return EINVAL;
+                    }
+                    dctx->domain =
+                            find_domain_by_object_name(get_domains_head(dom),
+                                                       sysdb_name);
+                    if (dctx->domain == NULL) {
+                        DEBUG(SSSDBG_CRIT_FAILURE,
+                              "Cannot find matching domain for [%s].\n",
+                              sysdb_name);
+                        return EINVAL;
+                    }
+                }
             } else {
                 talloc_free(msg);
                 ret = sysdb_search_group_by_name(cmdctx, dom, name,
@@ -4531,14 +4581,14 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
             if (cmdctx->cmd == SSS_NSS_GETSIDBYNAME
                     || cmdctx->cmd == SSS_NSS_GETORIGBYNAME) {
                 ret = sss_ncache_set_user(nctx->rctx->ncache, false,
-                                          dom, name);
+                                          dom, neg_cache_name);
                 if (ret != EOK) {
                     DEBUG(SSSDBG_MINOR_FAILURE,
                           "Cannot set negcache for %s\n", name);
                 }
 
                 ret = sss_ncache_set_group(nctx->rctx->ncache, false,
-                                           dom, name);
+                                           dom, neg_cache_name);
                 if (ret != EOK) {
                     DEBUG(SSSDBG_MINOR_FAILURE,
                           "Cannot set negcache for %s\n", name);
@@ -4573,8 +4623,14 @@ static errno_t nss_cmd_getsidby_search(struct nss_dom_ctx *dctx)
                 req_type = SSS_DP_USER_AND_GROUP;
             }
 
+            if (cmdctx->name_is_upn) {
+                extra_flag = EXTRA_NAME_IS_UPN;
+            } else {
+                extra_flag = NULL;
+            }
+
             ret = check_cache(dctx, nctx, dctx->res,
-                              req_type, req_name, req_id, NULL,
+                              req_type, req_name, req_id, extra_flag,
                               nss_cmd_getby_dp_callback,
                               dctx);
             if (ret != EOK) {
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org

Reply via email to