Bug 168176 - Cannot create users when nscd is running
Summary: Cannot create users when nscd is running
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: shadow-utils
Version: 4
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Peter Vrabec
QA Contact: David Lawrence
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2005-09-13 08:43 UTC by Marek Greško
Modified: 2007-11-30 22:11 UTC (History)
2 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2005-09-22 09:12:33 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)

Description Marek Greško 2005-09-13 08:43:46 UTC
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050909 Fedora/1.7.10-1.5.2

Description of problem:
When nscd is running I am unable to create users. The useradd quits without any error but user is not created.

I also tried to rm /var/db/nscd/* when nscd offline. Also invalidate passwd and group tables but nothing helps. Only stopping nscd.

When running strace useradd I receive
write(12, "passwd\0", 7)                = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) @ 0 (0) ---
+++ killed by SIGPIPE +++

This problem disappeared on some machines after deleting /var/db/nscd/* but on this machine remains.

Version-Release number of selected component (if applicable):
nscd-2.3.5-10.3

How reproducible:
Always

Steps to Reproduce:
1. Run nscd.
2. Run useradd.
3. User is not created.
  

Actual Results:  Users are not created using useradd.

Expected Results:  Users are created using useradd.

Additional info:

Comment 1 Jakub Jelinek 2005-09-13 11:49:57 UTC
The problem is that nscd expects both the request header and request key
to come together:
      /* We do not want to block on a short read or so.  */
      int fl = fcntl (fd, F_GETFL);
      if (fl == -1 || fcntl (fd, F_SETFL, fl | O_NONBLOCK) == -1)
        goto close_and_out;

      /* Now read the request.  */
      request_header req;
      if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, &req, sizeof (req)))
                            != sizeof (req), 0))
        {
...
        }
...
          if (__builtin_expect (TEMP_FAILURE_RETRY (read (fd, keybuf,
                                                          req.key_len))
                                != req.key_len, 0))
            {
              /* Again, this can also mean we would have blocked.  */
              if (debug_level > 0)
                dbg_log (_("short read while reading request key: %s"),
                         strerror_r (errno, buf, sizeof (buf)));
              goto close_and_out;
            }

nscd -i passwd uses writev syscall to write the request:
socket(PF_FILE, SOCK_STREAM, 0)         = 3
connect(3, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = 0
writev(3, [{"\2\0\0\0\n\0\0\0\7\0\0\0", 12}, {"passwd\0", 7}], 2) = 19
close(3)                                = 0

but shadow-utils send the request header and key separately:
socket(PF_FILE, SOCK_STREAM, 0)         = 12
connect(12, {sa_family=AF_FILE, path="/var/run/nscd/socket"}, 110) = 0
write(12, "\2\0\0\0\n\0\0\0\7\0\0\0", 12) = 12
write(12, "passwd\0", 7)                = -1 EPIPE (Broken pipe)
--- SIGPIPE (Broken pipe) @ 0 (0) ---
+++ killed by SIGPIPE +++

Now, the reason why nscd uses non-blocking reads for the requests (since
mid 2004) is to avoid DoS.
So IMHO shadow-utils should be fixed to either use writev, or construct
request header + key in one buffer and write that using one write.

Comment 2 Ulrich Drepper 2005-09-13 20:24:45 UTC
Indeed, shadowutils should use writev.  It's easy enough to do.

Comment 3 Peter Vrabec 2005-09-22 09:12:33 UTC
Fixed in devel and FC4 by shadow-utils-4.0.12-4.FC4 update.


Note You need to log in before you can comment on or make changes to this bug.