On (20/09/13 14:28), Jakub Hrozek wrote: >On Fri, Sep 20, 2013 at 11:00:18AM +0200, Lukas Slebodnik wrote: >> On (20/09/13 10:54), Pavel Březina wrote: >> >On 09/20/2013 02:30 AM, Simo Sorce wrote: >> >>On Thu, 2013-09-19 at 18:45 +0200, Jakub Hrozek wrote: >> >>>On Wed, Sep 18, 2013 at 10:40:13PM +0200, Jakub Hrozek wrote: >> >>>>On Wed, Sep 18, 2013 at 01:41:36PM -0400, Simo Sorce wrote: >> >>>>>On Wed, 2013-09-18 at 17:58 +0200, Jakub Hrozek wrote: >> >>>>>>Hi, >> >>>>>> >> >>>>>>the first patch fixes the bug that Jean-Baptiste Denis found earlier >> >>>>>>today. In case the lookup was not done using a FQDN, the code would >> >>>>>>skip >> >>>>>>setting the entries to the ncache. >> >>>>>> >> >>>>>>The second patch is an incremental improvement. I don't think we should >> >>>>>>abort the whole lookup if setting an entry in negcache would fail. The >> >>>>>>negative cache is a performance optimization after all. >> >>>>> >> >>>>>It seem to me that with the first patch you are changing behavior as you >> >>>>>leave 'ret' unchanged to whatever error is returned instead of setting >> >>>>>it to ENOENT before going to 'done'. >> >>>>> >> >>>>>Simo. >> >>>> >> >>>>Ugh, that is a bug. >> >>>> >> >>>>I was going back and forth on changing the particular return to goto >> >>>>and when I made my mind, I forgot to set the errno. >> >>>> >> >>>>Thanks Simo for catching it, I'll prepare a new version. >> >>> >> >>>I think we were both confused by the poor label naming. The label >> >>>actually, >> >>>despite being named "done", made the function return ENOENT so the code >> >>>was correct. But even I was confused couple of hours after sending the >> >>>patch so the code had to be improved :) >> >>> >> >>>So in the attached patch I renamed the label to notfound. I hope that's >> >>>OK if we don't use the commonly used "done" in this case. I think the most >> >>>important thing is that there is only a single label we jump to. >> >>> >> >>>Alternatively, if you prefer strictly one exit point, I could convert >> >>>the function to only use goto done and set negcache based on errno value >> >>>(if ENOENT->ncache) but I didn't see that as necessary. >> >> >> >>I prefer the idiom: >> >> ret = ENOENT; >> >> goto done; >> >> >> >>to: >> >> goto notfound; >> >> >> >> >> >>Simo. >> > >> >I agree. We should not introduce new labels. > >Well, I think this particular usage was OK as it was strictly a >"exception", but I won't argue too hard. I also didn't want to change >too much code in a bugfix patch.. > >> I agree too. Compilers are smart enough to do this kind of optimization. >> >> LS > >Yeah, my point was minimal code change during a bugfix that might make >its way even to a stable branch (as this bug affects even sssd-1-9) >rather than optimization.. > >Anyway, new patches are attached.
>From d98862aa128aee9aeec9af14ff00fcd57a254091 Mon Sep 17 00:00:00 2001 >From: Jakub Hrozek <jhro...@redhat.com> >Date: Wed, 18 Sep 2013 15:42:41 +0200 >Subject: [PATCH 1/2] NSS: Set UID and GID to negative cache after searching > all domains > >https://fedorahosted.org/sssd/ticket/2090 > >Previously, when searching by UID or GID, the negative cache will only >work in case the UID was searched for using fully qualified names. >--- > src/responder/nss/nsssrv_cmd.c | 171 +++++++++++++++++++++++++---------------- > 1 file changed, 105 insertions(+), 66 deletions(-) > >diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c >index >229548976744220b6f10b184a28a8ac8c11559a7..ad78b47a664c986b2040f53e8fbf8be0c96c6c6e > 100644 >--- a/src/responder/nss/nsssrv_cmd.c >+++ b/src/responder/nss/nsssrv_cmd.c >@@ -1236,7 +1236,8 @@ static int nss_cmd_getpwuid_search(struct nss_dom_ctx >*dctx) > dom = get_next_domain(dom, true); > continue; > } >- return ENOENT; >+ ret = ENOENT; >+ goto done; > } > > if (dom != dctx->domain) { >@@ -1253,18 +1254,21 @@ static int nss_cmd_getpwuid_search(struct nss_dom_ctx >*dctx) > sysdb = dom->sysdb; > if (sysdb == NULL) { > DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n")); >- return EIO; >+ ret = EIO; >+ goto done; > } > > ret = sysdb_getpwuid(cmdctx, sysdb, dom, cmdctx->id, &dctx->res); > if (ret != EOK) { > DEBUG(1, ("Failed to make request to our cache!\n")); >- return EIO; >+ ret = EIO; >+ goto done; > } > > if (dctx->res->count > 1) { > DEBUG(0, ("getpwuid call returned more than one result !?!\n")); >- return ENOENT; >+ ret = ENOENT; >+ goto done; > } > > if (dctx->res->count == 0 && !dctx->check_provider) { >@@ -1274,15 +1278,10 @@ static int nss_cmd_getpwuid_search(struct nss_dom_ctx >*dctx) > continue; > } > >- DEBUG(2, ("No results for getpwuid call\n")); >- > /* set negative cache only if not result of cache check */ >- ret = sss_ncache_set_uid(nctx->ncache, false, cmdctx->id); >- if (ret != EOK) { >- return ret; >- } >- >- return ENOENT; >+ DEBUG(SSSDBG_MINOR_FAILURE, ("No results for getpwuid call\n")); >+ ret = ENOENT; >+ goto done; > } > > /* if this is a caching provider (or if we haven't checked the cache >@@ -1296,18 +1295,30 @@ static int nss_cmd_getpwuid_search(struct nss_dom_ctx >*dctx) > /* Anything but EOK means we should reenter the mainloop > * because we may be refreshing the cache > */ >- return ret; >+ goto done; > } > } > > /* One result found */ > DEBUG(6, ("Returning info for uid [%d@%s]\n", cmdctx->id, dom->name)); > >- return EOK; >+ ret = EOK; >+ goto done; > } > >- DEBUG(2, ("No matching domain found for [%d], fail!\n", cmdctx->id)); >- return ENOENT; >+ /* All domains were tried and none had the entry. */ >+ ret = ENOENT; >+done: >+ if (ret == ENOENT) { >+ /* The entry was not found, need to set result in negative cache */ >+ ret = sss_ncache_set_uid(nctx->ncache, false, cmdctx->id); >+ if (ret != EOK) { >+ return ret; >+ } >+ } >+ >+ DEBUG(SSSDBG_MINOR_FAILURE, ("No matching domain found for [%d]\n", >cmdctx->id)); >+ return ret; > } > > static int nss_cmd_getgrgid_search(struct nss_dom_ctx *dctx); >@@ -2668,7 +2679,8 @@ static int nss_cmd_getgrgid_search(struct nss_dom_ctx >*dctx) > dom = get_next_domain(dom, true); > continue; > } >- return ENOENT; >+ ret = ENOENT; >+ goto done; > } > > if (dom != dctx->domain) { >@@ -2685,18 +2697,21 @@ static int nss_cmd_getgrgid_search(struct nss_dom_ctx >*dctx) > sysdb = dom->sysdb; > if (sysdb == NULL) { > DEBUG(0, ("Fatal: Sysdb CTX not found for this domain!\n")); >- return EIO; >+ ret = EIO; >+ goto done; > } > > ret = sysdb_getgrgid(cmdctx, sysdb, dom, cmdctx->id, &dctx->res); > if (ret != EOK) { > DEBUG(1, ("Failed to make request to our cache!\n")); >- return EIO; >+ ret = EIO; >+ goto done; > } > > if (dctx->res->count > 1) { > DEBUG(0, ("getgrgid call returned more than one result !?!\n")); >- return ENOENT; >+ ret = ENOENT; >+ goto done; > } > > if (dctx->res->count == 0 && !dctx->check_provider) { >@@ -2706,15 +2721,10 @@ static int nss_cmd_getgrgid_search(struct nss_dom_ctx >*dctx) > continue; > } > >- DEBUG(2, ("No results for getgrgid call\n")); >- > /* set negative cache only if not result of cache check */ >- ret = sss_ncache_set_gid(nctx->ncache, false, cmdctx->id); >- if (ret != EOK) { >- return ret; >- } >- >- return ENOENT; >+ DEBUG(SSSDBG_MINOR_FAILURE, ("No results for getgrgid call\n")); >+ ret = ENOENT; >+ goto done; > } > > /* if this is a caching provider (or if we haven't checked the cache >@@ -2728,18 +2738,31 @@ static int nss_cmd_getgrgid_search(struct nss_dom_ctx >*dctx) > /* Anything but EOK means we should reenter the mainloop > * because we may be refreshing the cache > */ >- return ret; >+ goto done; > } > } > > /* One result found */ > DEBUG(6, ("Returning info for gid [%d@%s]\n", cmdctx->id, dom->name)); > >- return EOK; >+ /* Success. Break from the loop and return EOK */ >+ ret = EOK; >+ goto done; > } > >- DEBUG(2, ("No matching domain found for [%d], fail!\n", cmdctx->id)); >- return ENOENT; >+ /* All domains were tried and none had the entry. */ >+ ret = ENOENT; >+done: >+ if (ret == ENOENT) { >+ /* The entry was not found, need to set result in negative cache */ >+ ret = sss_ncache_set_gid(nctx->ncache, false, cmdctx->id); >+ if (ret != EOK) { >+ return ret; >+ } >+ } >+ >+ DEBUG(SSSDBG_MINOR_FAILURE, ("No matching domain found for [%d]\n", >cmdctx->id)); >+ return ret; > } > > static int nss_cmd_getgrgid(struct cli_ctx *cctx) >@@ -3639,7 +3662,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > dom = get_next_domain(dom, true); > continue; > } >- return ENOENT; >+ ret = ENOMEM; ^^^^^^ Is it aim or mistake? s/ENOMEM/ENOENT/ >+ goto done; > } > } else { > /* if it is a domainless search, skip domains that require fully >@@ -3670,7 +3694,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > name = sss_get_cased_name(cmdctx, cmdctx->name, > dom->case_sensitive); > if (name == NULL) { > DEBUG(SSSDBG_OP_FAILURE, ("sss_get_cased_name failed.\n")); >- return ENOMEM; >+ ret = ENOMEM; >+ goto done; > } > > /* For subdomains a fully qualified name is needed for >@@ -3679,7 +3704,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > sysdb_name = sss_tc_fqname(cmdctx, dom->names, dom, name); > if (sysdb_name == NULL) { > DEBUG(SSSDBG_OP_FAILURE, ("talloc_asprintf failed.\n")); >- return ENOMEM; >+ ret = ENOMEM; >+ goto done; > } > } > >@@ -3702,7 +3728,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > /* There are no further domains or this was a > * fully-qualified user request. > */ >- return ENOENT; >+ ret = ENOENT; >+ goto done; > } > > DEBUG(SSSDBG_TRACE_FUNC, ("Requesting info for [%s@%s]\n", >@@ -3714,7 +3741,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > if (sysdb == NULL) { > DEBUG(SSSDBG_FATAL_FAILURE, > ("Fatal: Sysdb CTX not found for this domain!\n")); >- return EIO; >+ ret = EIO; >+ goto done; > } > > if (cmdctx->cmd == SSS_NSS_GETSIDBYID) { >@@ -3723,7 +3751,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > if (ret != EOK && ret != ENOENT) { > DEBUG(SSSDBG_CRIT_FAILURE, > ("Failed to make request to our cache!\n")); >- return EIO; >+ ret = EIO; >+ goto done; > } > > if (ret == EOK) { >@@ -3735,7 +3764,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > if (ret != EOK && ret != ENOENT) { > DEBUG(SSSDBG_CRIT_FAILURE, > ("Failed to make request to our cache!\n")); >- return EIO; >+ ret = EIO; >+ goto done; > } > > if (ret == EOK) { >@@ -3749,7 +3779,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > if (ret != EOK && ret != ENOENT) { > DEBUG(SSSDBG_CRIT_FAILURE, > ("Failed to make request to our cache!\n")); >- return EIO; >+ ret = EIO; >+ goto done; > } > > if (ret == EOK) { >@@ -3762,7 +3793,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > if (ret != EOK && ret != ENOENT) { > DEBUG(SSSDBG_CRIT_FAILURE, > ("Failed to make request to our cache!\n")); >- return EIO; >+ ret = EIO; >+ goto done; > } > > if (ret == EOK) { >@@ -3774,7 +3806,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > dctx->res = talloc_zero(cmdctx, struct ldb_result); > if (dctx->res == NULL) { > DEBUG(SSSDBG_OP_FAILURE, ("talloc_zero failed.\n")); >- return ENOMEM; >+ ret = ENOMEM; >+ goto done; > } > > if (user_found || group_found) { >@@ -3782,7 +3815,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > dctx->res->msgs = talloc_array(dctx->res, struct ldb_message *, > 1); > if (dctx->res->msgs == NULL) { > DEBUG(SSSDBG_OP_FAILURE, ("talloc_array failed.\n")); >- return ENOMEM; >+ ret = ENOMEM; >+ goto done; > } > dctx->res->msgs[0] = talloc_steal(dctx->res, msg); > } >@@ -3806,20 +3840,8 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > } > > DEBUG(SSSDBG_OP_FAILURE, ("No matching user or group found.\n")); >- >- if (cmdctx->cmd == SSS_NSS_GETSIDBYID) { >- ret = sss_ncache_set_uid(nctx->ncache, false, cmdctx->id); >- if (ret != EOK) { >- return ret; >- } >- >- ret = sss_ncache_set_gid(nctx->ncache, false, cmdctx->id); >- if (ret != EOK) { >- return ret; >- } >- } >- >- return ENOENT; >+ ret = ENOENT; >+ goto done; > } > > /* if this is a caching provider (or if we haven't checked the cache >@@ -3848,7 +3870,7 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > /* Anything but EOK means we should reenter the mainloop > * because we may be refreshing the cache > */ >- return ret; >+ goto done; > } > } > >@@ -3861,17 +3883,34 @@ static errno_t nss_cmd_getsidby_search(struct >nss_dom_ctx *dctx) > name, dom->name)); > } > >- return EOK; >+ /* Success. Break from the loop and return EOK */ >+ ret = EOK; >+ goto done; > } > >- if (cmdctx->cmd == SSS_NSS_GETSIDBYID) { >- DEBUG(SSSDBG_MINOR_FAILURE, >- ("No matching domain found for [%d], fail!\n", cmdctx->id)); >- } else { >- DEBUG(SSSDBG_MINOR_FAILURE, >- ("No matching domain found for [%s], fail!\n", cmdctx->name)); >+ /* All domains were tried and none had the entry. */ >+ ret = ENOENT; >+done: >+ if (ret == ENOENT) { >+ /* The entry was not found, need to set result in negative cache */ >+ if (cmdctx->cmd == SSS_NSS_GETSIDBYID) { >+ DEBUG(SSSDBG_MINOR_FAILURE, >+ ("No matching domain found for [%d], fail!\n", cmdctx->id)); >+ ret = sss_ncache_set_uid(nctx->ncache, false, cmdctx->id); >+ if (ret != EOK) { >+ return ret; >+ } >+ >+ ret = sss_ncache_set_gid(nctx->ncache, false, cmdctx->id); >+ if (ret != EOK) { >+ return ret; >+ } >+ } else { >+ DEBUG(SSSDBG_MINOR_FAILURE, >+ ("No matching domain found for [%s], fail!\n", >cmdctx->name)); >+ } > } >- return ENOENT; >+ return ret; > } > > static errno_t nss_cmd_getbysid_search(struct nss_dom_ctx *dctx) >-- >1.8.3.1 > >From 65e1d921c6109614550ddfc09279a89f0801b27b Mon Sep 17 00:00:00 2001 >From: Jakub Hrozek <jhro...@redhat.com> >Date: Wed, 18 Sep 2013 15:49:46 +0200 >Subject: [PATCH 2/2] NSS: Failure to store entry negative cache should not be > fatal 2nd patch ACK LS _______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/sssd-devel