summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2017-03-09 17:54:56 -0500
committerLuke Shumaker <lukeshu@lukeshu.com>2017-03-09 17:54:56 -0500
commita74b11b62df32286944372e14f60e2d113f7a2a8 (patch)
treed011b20105e677b229a35dfd8f0a486763fc9918 /src
parentf0d4fc49880c7c99ee895a43a4c8a9e7e073a6da (diff)
nspawn: Use fgetpwent() instead of rolling our own parser.
There isn't a strong reason to do this, other than that it simplifies the code quite a bit. This means that the -errno return codes might be a bit different.
Diffstat (limited to 'src')
-rw-r--r--src/systemd-nspawn/nspawn-setuid.c71
1 files changed, 10 insertions, 61 deletions
diff --git a/src/systemd-nspawn/nspawn-setuid.c b/src/systemd-nspawn/nspawn-setuid.c
index 129d3acc5f..7d0d47c5b1 100644
--- a/src/systemd-nspawn/nspawn-setuid.c
+++ b/src/systemd-nspawn/nspawn-setuid.c
@@ -18,6 +18,8 @@
***/
#include <grp.h>
+#include <pwd.h>
+#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
@@ -88,7 +90,8 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
}
int change_uid_gid(const char *user, char **_home) {
- char line[LINE_MAX], *x, *u, *g, *h;
+ char line[LINE_MAX], *x;
+ struct passwd *pw;
const char *word, *state;
_cleanup_free_ uid_t *uids = NULL;
_cleanup_free_ char *home = NULL;
@@ -124,8 +127,9 @@ int change_uid_gid(const char *user, char **_home) {
return log_oom();
fd = -1;
- if (!fgets(line, sizeof(line), f)) {
- if (!ferror(f)) {
+ errno = 0;
+ if (!(pw = fgetpwent(f))) {
+ if (!errno) {
log_error("Failed to resolve user %s.", user);
return -ESRCH;
}
@@ -133,66 +137,11 @@ int change_uid_gid(const char *user, char **_home) {
return log_error_errno(errno, "Failed to read from getent: %m");
}
- truncate_nl(line);
-
wait_for_terminate_and_warn("getent passwd", pid, true);
- x = strchr(line, ':');
- if (!x) {
- log_error("/etc/passwd entry has invalid user field.");
- return -EIO;
- }
-
- u = strchr(x+1, ':');
- if (!u) {
- log_error("/etc/passwd entry has invalid password field.");
- return -EIO;
- }
-
- u++;
- g = strchr(u, ':');
- if (!g) {
- log_error("/etc/passwd entry has invalid UID field.");
- return -EIO;
- }
-
- *g = 0;
- g++;
- x = strchr(g, ':');
- if (!x) {
- log_error("/etc/passwd entry has invalid GID field.");
- return -EIO;
- }
-
- *x = 0;
- h = strchr(x+1, ':');
- if (!h) {
- log_error("/etc/passwd entry has invalid GECOS field.");
- return -EIO;
- }
-
- h++;
- x = strchr(h, ':');
- if (!x) {
- log_error("/etc/passwd entry has invalid home directory field.");
- return -EIO;
- }
-
- *x = 0;
-
- r = parse_uid(u, &uid);
- if (r < 0) {
- log_error("Failed to parse UID of user.");
- return -EIO;
- }
-
- r = parse_gid(g, &gid);
- if (r < 0) {
- log_error("Failed to parse GID of user.");
- return -EIO;
- }
-
- home = strdup(h);
+ uid = pw->pw_uid;
+ gid = pw->pw_gid;
+ home = strdup(pw->pw_dir);
if (!home)
return log_oom();