From: Rich Felker <dalias@libc.org>
To: musl@lists.openwall.com
Subject: Re: [PATCH] support alternate backends for the passwd and group dbs
Date: Mon, 23 Feb 2015 01:08:40 -0500 [thread overview]
Message-ID: <20150223060840.GB23507@brightrain.aerifal.cx> (raw)
In-Reply-To: <1424660290-25921-1-git-send-email-josiahw@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1071 bytes --]
On Sun, Feb 22, 2015 at 08:58:10PM -0600, Josiah Worcester wrote:
> when we fail to find the entry in the commonly accepted files, we
> query a server over a Unix domain socket on /var/run/nscd/socket.
> the protocol used here is compatible with glibc's nscd protocol on
> most systems (all that use 32-bit numbers for all the protocol fields,
> which appears to be everything but Alpha).
I'm committing with the attached additional changes amended in as
discussed on #musl. With these changes it at least passes the
following checks:
- With no nscd running, lookups return negative with no error.
- With bad nscd running and dropping connections with no reply,
reverse-endian fallback code retries the query and then fails with
EIO indicating inability to provide a definitive negative answer.
- Replies that don't match the query produce EIO.
- Replies that do match the query produce successful results.
Tested using the attached fake-nscd.c. This code still needs further
testing before release to ensure that we're not introducing
significant bugs.
Rich
[-- Attachment #2: nscd-addl-changes.diff --]
[-- Type: text/plain, Size: 3391 bytes --]
diff --git a/src/passwd/getgr_a.c b/src/passwd/getgr_a.c
index 2d3ed1d..7738c3c 100644
--- a/src/passwd/getgr_a.c
+++ b/src/passwd/getgr_a.c
@@ -96,7 +96,7 @@ int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t
grlist_len += name_len;
}
- if (len > *size) {
+ if (len > *size || !*buf) {
char *tmp = realloc(*buf, len);
if (!tmp) {
rv = errno;
@@ -106,7 +106,7 @@ int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t
*size = len;
}
- if (fread(*buf, 1, len, f) < len) {
+ if (!fread(*buf, len, 1, f)) {
rv = ferror(f) ? errno : EIO;
goto cleanup_f;
}
diff --git a/src/passwd/getpw_a.c b/src/passwd/getpw_a.c
index 9af6cab..b04663d 100644
--- a/src/passwd/getpw_a.c
+++ b/src/passwd/getpw_a.c
@@ -90,7 +90,7 @@ int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t
+ passwdbuf[PWGECOSLEN] + passwdbuf[PWDIRLEN]
+ passwdbuf[PWSHELLLEN];
- if (len > *size) {
+ if (len > *size || !*buf) {
char *tmp = realloc(*buf, len);
if (!tmp) {
rv = errno;
@@ -100,7 +100,7 @@ int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t
*size = len;
}
- if (fread(*buf, 1, len, f) < len) {
+ if (!fread(*buf, len, 1, f)) {
rv = ferror(f) ? errno : EIO;
goto cleanup_f;
}
diff --git a/src/passwd/nscd_query.c b/src/passwd/nscd_query.c
index 539cc2a..f8d0fc1 100644
--- a/src/passwd/nscd_query.c
+++ b/src/passwd/nscd_query.c
@@ -14,34 +14,10 @@ static const struct {
"/var/run/nscd/socket"
};
-static ssize_t full_sendmsg(int fd, struct msghdr *m, int flags)
-{
- ssize_t n, count = 0;
-
- while (m->msg_iovlen) {
- n = sendmsg(fd, m, flags);
- if(n < 0) return n;
- count += n;
-
- while (n) {
- if (n >= m->msg_iov[0].iov_len) {
- n -= m->msg_iov[0].iov_len;
- m->msg_iov++;
- m->msg_iovlen--;
- } else {
- m->msg_iov[0].iov_len -= n;
- n = 0;
- }
- }
- }
- return count;
-}
-
FILE *__nscd_query(int32_t req, const char *key, int32_t *buf, size_t len, int *swap)
{
size_t i;
int fd;
- int res = 0;
FILE *f = 0;
int32_t req_buf[REQ_LEN] = {
NSCDVERSION,
@@ -71,23 +47,24 @@ retry:
* that is precisely what happened
*/
if (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT) {
- res = -1;
+ close(fd);
+ return (FILE *)-1;
}
goto error;
}
- if (full_sendmsg(fd, &msg, MSG_NOSIGNAL) < 0)
+ if (sendmsg(fd, &msg, MSG_NOSIGNAL) < 0)
goto error;
- f = fdopen(fd, "r");
+ if(!(f = fdopen(fd, "r"))) goto error;
- if (fread(buf, 1, len, f) < len) {
+ if (!fread(buf, len, 1, f)) {
/* If the VERSION entry mismatches nscd will disconnect. The
* most likely cause is that the endianness mismatched. So, we
* byteswap and try once more. (if we already swapped, just
* fail out)
*/
- if (!feof(f)) goto error;
+ if (ferror(f)) goto error;
if (!*swap) {
fclose(f);
for (i = 0; i < sizeof(req_buf)/sizeof(req_buf[0]); i++) {
@@ -96,8 +73,7 @@ retry:
*swap = 1;
goto retry;
} else {
- fclose(f);
- res = -1;
+ errno = EIO;
goto error;
}
}
@@ -113,13 +89,12 @@ retry:
* response.
*/
if(buf[0] != NSCDVERSION) {
- res = -1;
errno = EIO;
goto error;
}
return f;
error:
- fclose(f);
- return (FILE*)res;
+ if (f) fclose(f); else close(fd);
+ return 0;
}
[-- Attachment #3: fake-nscd.c --]
[-- Type: text/plain, Size: 675 bytes --]
#include <sys/socket.h>
#include <sys/un.h>
#include <inttypes.h>
#include <unistd.h>
#define STRINGS "foobar\0\0\0/\0/bin/sh"
static const struct reply {
uint32_t header[9];
char strings[sizeof STRINGS];
} reply = {
{ 2, 1, 7, 1, 12345, 678910, 1, 2, 8 },
STRINGS
};
int main()
{
struct sockaddr_un sun = {
.sun_family = AF_UNIX,
.sun_path = "/var/run/nscd/socket"
};
int s = socket(AF_UNIX, SOCK_STREAM, 0);
umask(0);
bind(s, (void *)&sun, sizeof sun);
listen(s, 1);
for (;;) {
char buf[256];
int c = accept(s, (void *)&(struct sockaddr_un){0}, &(socklen_t){sizeof sun});
read(c, buf, sizeof buf);
write(c, &reply, sizeof reply);
close(c);
}
}
next prev parent reply other threads:[~2015-02-23 6:08 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-02-23 2:35 Josiah Worcester
2015-02-23 2:58 ` Josiah Worcester
2015-02-23 6:08 ` Rich Felker [this message]
2015-02-23 6:18 ` Solar Designer
2015-02-23 6:24 ` Josiah Worcester
2015-02-23 7:04 ` Rich Felker
2015-02-23 16:01 ` M Farkas-Dyck
2015-02-23 18:15 ` Rich Felker
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=20150223060840.GB23507@brightrain.aerifal.cx \
--to=dalias@libc.org \
--cc=musl@lists.openwall.com \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/musl/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).