dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone
Blob Blame History Raw
From aac4dbb17f3e19a2fbeefb38b3319827d3bf820e Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Wed, 13 May 2020 13:13:43 +0200
Subject: [PATCH] NSS client: preserve errno during _nss_sss_end* calls

glibc does not expect that errno is changed by some of the calls
provided by nss modules. This caused at least issues when
_nss_sss_endpwent() is called in compat mode. According to
https://pubs.opengroup.org/onlinepubs/9699919799/functions/endpwent.html
endpwent() should only set errno in the case of an error. Since there is
no other way to report an error we will set errno in the case of an
error but preserve it otherwise. This should cause no issues because
glibc is taking precautions as well tracked by
https://sourceware.org/bugzilla/show_bug.cgi?id=25976.

To be on the safe side the other _nss_sss_end* calls will show the same
behavior.

Resolves: https://github.com/SSSD/sssd/issues/5153

Reviewed-by: Alexey Tikhonov <atikhonov@redhat.com>
---
 src/sss_client/nss_group.c      | 3 +++
 src/sss_client/nss_hosts.c      | 4 +++-
 src/sss_client/nss_ipnetworks.c | 4 +++-
 src/sss_client/nss_netgroup.c   | 3 +++
 src/sss_client/nss_passwd.c     | 3 +++
 src/sss_client/nss_services.c   | 3 +++
 6 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/sss_client/nss_group.c b/src/sss_client/nss_group.c
index 5ab2bdf78..4a201bf09 100644
--- a/src/sss_client/nss_group.c
+++ b/src/sss_client/nss_group.c
@@ -735,6 +735,7 @@ enum nss_status _nss_sss_endgrent(void)
 {
     enum nss_status nret;
     int errnop;
+    int saved_errno = errno;
 
     sss_nss_lock();
 
@@ -745,6 +746,8 @@ enum nss_status _nss_sss_endgrent(void)
                                 NULL, NULL, NULL, &errnop);
     if (nret != NSS_STATUS_SUCCESS) {
         errno = errnop;
+    } else {
+        errno = saved_errno;
     }
 
     sss_nss_unlock();
diff --git a/src/sss_client/nss_hosts.c b/src/sss_client/nss_hosts.c
index 5e279468b..aa2676286 100644
--- a/src/sss_client/nss_hosts.c
+++ b/src/sss_client/nss_hosts.c
@@ -565,6 +565,7 @@ _nss_sss_endhostent(void)
 {
     enum nss_status nret;
     int errnop;
+    int saved_errno = errno;
 
     sss_nss_lock();
 
@@ -575,9 +576,10 @@ _nss_sss_endhostent(void)
                                 NULL, NULL, NULL, &errnop);
     if (nret != NSS_STATUS_SUCCESS) {
         errno = errnop;
+    } else {
+        errno = saved_errno;
     }
 
     sss_nss_unlock();
-
     return nret;
 }
diff --git a/src/sss_client/nss_ipnetworks.c b/src/sss_client/nss_ipnetworks.c
index 15fee6039..08070499d 100644
--- a/src/sss_client/nss_ipnetworks.c
+++ b/src/sss_client/nss_ipnetworks.c
@@ -510,6 +510,7 @@ _nss_sss_endnetent(void)
 {
     enum nss_status nret;
     int errnop;
+    int saved_errno = errno;
 
     sss_nss_lock();
 
@@ -520,10 +521,11 @@ _nss_sss_endnetent(void)
                                 NULL, NULL, NULL, &errnop);
     if (nret != NSS_STATUS_SUCCESS) {
         errno = errnop;
+    } else {
+        errno = saved_errno;
     }
 
     sss_nss_unlock();
-
     return nret;
 }
 
diff --git a/src/sss_client/nss_netgroup.c b/src/sss_client/nss_netgroup.c
index 3a1834a31..2fc88f8ae 100644
--- a/src/sss_client/nss_netgroup.c
+++ b/src/sss_client/nss_netgroup.c
@@ -309,6 +309,7 @@ enum nss_status _nss_sss_endnetgrent(struct __netgrent *result)
 {
     enum nss_status nret;
     int errnop;
+    int saved_errno = errno;
 
     sss_nss_lock();
 
@@ -319,6 +320,8 @@ enum nss_status _nss_sss_endnetgrent(struct __netgrent *result)
                                 NULL, NULL, NULL, &errnop);
     if (nret != NSS_STATUS_SUCCESS) {
         errno = errnop;
+    } else {
+        errno = saved_errno;
     }
 
     sss_nss_unlock();
diff --git a/src/sss_client/nss_passwd.c b/src/sss_client/nss_passwd.c
index 96368bd6e..c386dd370 100644
--- a/src/sss_client/nss_passwd.c
+++ b/src/sss_client/nss_passwd.c
@@ -455,6 +455,7 @@ enum nss_status _nss_sss_endpwent(void)
 {
     enum nss_status nret;
     int errnop;
+    int saved_errno = errno;
 
     sss_nss_lock();
 
@@ -465,6 +466,8 @@ enum nss_status _nss_sss_endpwent(void)
                                 NULL, NULL, NULL, &errnop);
     if (nret != NSS_STATUS_SUCCESS) {
         errno = errnop;
+    } else {
+        errno = saved_errno;
     }
 
     sss_nss_unlock();
diff --git a/src/sss_client/nss_services.c b/src/sss_client/nss_services.c
index 13cb4c3ab..f8c2092cb 100644
--- a/src/sss_client/nss_services.c
+++ b/src/sss_client/nss_services.c
@@ -484,6 +484,7 @@ _nss_sss_endservent(void)
 {
     enum nss_status nret;
     int errnop;
+    int saved_errno = errno;
 
     sss_nss_lock();
 
@@ -494,6 +495,8 @@ _nss_sss_endservent(void)
                                 NULL, NULL, NULL, &errnop);
     if (nret != NSS_STATUS_SUCCESS) {
         errno = errnop;
+    } else {
+        errno = saved_errno;
     }
 
     sss_nss_unlock();
-- 
2.21.3