This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: NSS error reporting (bug 20532)


On 08/03/2017 01:18 PM, Florian Weimer wrote:
> On 08/03/2017 06:49 PM, Carlos O'Donell wrote:
>> On 08/03/2017 12:28 PM, Florian Weimer wrote:
>>> (L) Carlos added NSS_STATUS_NOTFOUND with *errnop equals 0 as a
>>> documented special case to the manual, in commit
>>> d4e301c5c65393837e438b6d81feabfbfde7b9c7.  This contradicts (A).
>>> NSS_STATUS_NOTFOUND is handled implicitly by __nss_next2, which does not
>>> have access to the errno value, so I do not understand how this could work.
> 
>> I must assume that (A) is not quite correct. I had two reproducers where
>> errno was propagated to the caller, and did result in observable differences?
> 
> Can you dig up the details?  And what was fixed in response to this
> clarification?

https://bugzilla.redhat.com/show_bug.cgi?id=988068

SSSD, installed, client setup, but no server running was returning
NSS_STATUS_UNAVAIL / ENOENT, and that results in the ENOENT being
propagated to the caller. This was not the intent. The intent was
for the SSSD NSS service module to be transparent to the user if
sssd was not running. So I had to clarify a class of NSS service module
was was intalled, answering replies, lacked a connected data source,
but wanted to return a no-error result that would be retried later.

The example reproducer was as simple as:

#include <sys/types.h>
#include <pwd.h>
#include <stdio.h>

int main(int argc, char* argv[]) {
  struct passwd pwd;
  char buf[4096];
  int err;
  struct passwd *res;

  err = getpwnam_r(argv[1], &pwd, buf, 4096, &res);

  printf("<%s> err: <%d>\n", argv[1], err);
  return 0;
}

With SSSD using status==NSS_STATUS_TRYAGAIN errno==EAGAIN:

getgrent() OK group(0) = root 
getgrent() OK group(1) = bin 
getgrent() OK group(2) = daemon 
...
getgrent: Resource temporarily unavailable
getgrent error 11 

With SSSD using status==NSS_STATUS_UNAVAIL errno==ENOENT:

getgrent() OK group(0) = root 
getgrent() OK group(1) = bin 
getgrent() OK group(2) = daemon 
...
getgrent: No such file or directory
getgrent error 2 

With SSSD using status==NSS_STATUS_NOTFOUND errno==0 (as suggested):
getgrent() OK group(0) = root 
getgrent() OK group(1) = bin 
getgrent() OK group(2) = daemon 
getgrent() OK group(3) = sys 
...
getgrent() OK group(185) = wildfly

> Are you sure this wasn't due to a NSS framework bug?
> 
> If errno is indeed propagated, then setting it 0 is probably wrong
> because POSIX does not allow setting it to 0.

You are absolutely right.

It should have been clarified to say "errno is left untouched."

This is the patch I worked up during testing:

diff -urN sssd-1.11.6/src/sss_client/nss_group.c sssd-1.11.6.mod/src/sss_client/nss_group.c
--- sssd-1.11.6/src/sss_client/nss_group.c	2014-06-03 10:31:33.000000000 -0400
+++ sssd-1.11.6.mod/src/sss_client/nss_group.c	2014-09-10 12:21:52.330685026 -0400
@@ -539,6 +539,11 @@
     if (nret != NSS_STATUS_SUCCESS) {
         errno = errnop;
     }
+    /* Always pretend we have no data.  */
+    if (nret == NSS_STATUS_UNAVAIL) {
+	nret = NSS_STATUS_NOTFOUND;
+	errno = 0;
+    }
 
     sss_nss_unlock();
     return nret;
@@ -639,6 +644,11 @@
     if (nret != NSS_STATUS_SUCCESS) {
         errno = errnop;
     }
+    /* Always pretend we have no data.  */
+    if (nret == NSS_STATUS_UNAVAIL) {
+	nret = NSS_STATUS_NOTFOUND;
+	errno = 0;
+    }
 
     sss_nss_unlock();
     return nret;
---

Should we have saved and restored errno?

-- 
Cheers,
Carlos.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]