Tarantool development patches archive
 help / color / mirror / Atom feed
From: Cyrill Gorcunov <gorcunov@gmail.com>
To: tml <tarantool-patches@dev.tarantool.org>
Cc: Alexander Turenko <alexander.turenko@tarantool.org>
Subject: [Tarantool-patches] [PATCH 3/3] lua/pwd: workaround the systemd bug
Date: Thu, 17 Sep 2020 16:51:21 +0300	[thread overview]
Message-ID: <20200917135121.60380-4-gorcunov@gmail.com> (raw)
In-Reply-To: <20200917135121.60380-1-gorcunov@gmail.com>

There is a bug in systemd-209 source code: it returns
ENOENT when no more entries in a password database left.

Later the issue been fixed but we still meet the systems
where it hits. The problem affects getpwent/getgrent calls
only thus we can expect them to return the buggy error code
to skip.

Notes:

1) See systemd's commit where issue been fixed

   | commit 06202b9e659e5cc72aeecc5200155b7c012fccbc
   | Author: Yu Watanabe <watanabe.yu+github@gmail.com>
   | Date:   Sun Jul 15 23:00:00 2018 +0900
   |
   |     nss: do not modify errno when NSS_STATUS_NOTFOUND or NSS_STATUS_SUCCESS

2) Another option is to call getpwall on Tarantool startup
   unconditionally where we could simply ignore any errors. This
   is a very bad choise since traversig a password database might
   introduce significant lags if backend does some network activiy
   or have expired caches. Thus drop getpwall() unconditional call
   run it iif a user does an explicit request.

Fixes #5034

Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
---
 src/lua/pwd.lua | 52 +++++++++++++++++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 12 deletions(-)

diff --git a/src/lua/pwd.lua b/src/lua/pwd.lua
index 31cfbd8bf..907eb5a8e 100644
--- a/src/lua/pwd.lua
+++ b/src/lua/pwd.lua
@@ -196,6 +196,44 @@ local function getpw(uid)
     return pwtotable(pw, gr)
 end
 
+--
+-- systemd v209 sets errno is set to ENOENT in
+-- _nss_systemd_getpwent_r and _nss_systemd_getgrent_r
+-- when there are no more entries to enumerate.
+--
+-- This is a bug which has been fixed later in
+-- systemd code but we have to deal with buggy
+-- systems thus ignore such error if appears.
+--
+-- See the reference for details
+-- https://github.com/systemd/systemd/issues/9585
+--
+-- This issue affects getpwent/getgrent calls only
+-- thus provide own wrappings to keep workaround
+-- in one place and do not affect any other calls
+-- where ENOENT might become a valid error case.
+--
+-- Initially we observed this issue on Fedora 29
+-- when a password database is traversed for the
+-- first time.
+local function getpwent()
+    errno(0)
+    local pw = ffi.C.getpwent()
+    if pw == nil and errno() == errno.ENOENT then
+        errno(0)
+    end
+    return pw
+end
+
+local function getgrent()
+    errno(0)
+    local gr = ffi.C.getgrent()
+    if gr == nil and errno() == errno.ENOENT then
+        errno(0)
+    end
+    return gr
+end
+
 local function getpwall()
     ffi.C.setpwent()
     local pws = {}
@@ -203,8 +241,7 @@ local function getpwall()
     -- of a getpwent() current entry to a first one on CentOS 6
     -- and FreeBSD 12.
     while true do
-        errno(0)
-        local pw = ffi.C.getpwent()
+        local pw = getpwent()
         if pw == nil then
             pwgrcheck('getpwall', pw)
             break
@@ -223,8 +260,7 @@ local function getgrall()
     -- of a getgrent() current entry to a first one on CentOS 6
     -- and FreeBSD 12.
     while true do
-        errno(0)
-        local gr = ffi.C.getgrent()
+        local gr = getgrent()
         if gr == nil then
             pwgrcheck('getgrall', gr)
             break
@@ -237,14 +273,6 @@ end
 
 -- }}}
 
--- Workaround pwd.getpwall() issue on Fedora 29: successful
--- getgrent() call that should normally return NULL and preserve
--- errno, set it to ENOENT due to systemd-nss issue [1] when a
--- password database is traversed first time.
---
--- [1]: https://github.com/systemd/systemd/issues/9585
-pcall(getpwall)
-
 return {
     getpw = getpw,
     getgr = getgr,
-- 
2.26.2

  parent reply	other threads:[~2020-09-17 13:52 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-17 13:51 [Tarantool-patches] [PATCH 0/3] " Cyrill Gorcunov
2020-09-17 13:51 ` [Tarantool-patches] [PATCH 1/3] lua/errno: use lengthof helper Cyrill Gorcunov
2020-09-17 13:51 ` [Tarantool-patches] [PATCH 2/3] lua/errno: shrink memory usage on error declaration Cyrill Gorcunov
2020-09-17 13:51 ` Cyrill Gorcunov [this message]
2020-09-18 11:54   ` [Tarantool-patches] [PATCH 3/3] lua/pwd: workaround the systemd bug Cyrill Gorcunov
2020-09-18 12:26 ` [Tarantool-patches] [PATCH 0/3] " Kirill Yukhin
2020-09-18 12:39   ` Cyrill Gorcunov
2020-09-21  1:45 ` Alexander Turenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200917135121.60380-4-gorcunov@gmail.com \
    --to=gorcunov@gmail.com \
    --cc=alexander.turenko@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH 3/3] lua/pwd: workaround the systemd bug' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox