nss-systemd: resolve root/nobody statically
Let's extend nss-systemd to also synthesize user/group entries for the UIDs/GIDs 0 and 65534 which have special kernel meaning. Given that nss-systemd is listed in /etc/nsswitch.conf only very late any explicit listing in /etc/passwd or /etc/group takes precedence. This functionality is useful in minimal container-like setups that lack /etc/passwd files (or only have incompletely populated ones).
This commit is contained in:
parent
136dc4c435
commit
2129011e92
22
configure.ac
22
configure.ac
|
@ -556,12 +556,30 @@ AC_SUBST(CERTIFICATEROOT)
|
||||||
|
|
||||||
AC_ARG_WITH([support-url],
|
AC_ARG_WITH([support-url],
|
||||||
AS_HELP_STRING([--with-support-url=URL],
|
AS_HELP_STRING([--with-support-url=URL],
|
||||||
[Specify the supoport URL to show in catalog entries included in systemd]),
|
[Specify the support URL to show in catalog entries included in systemd]),
|
||||||
[SUPPORT_URL="$withval"],
|
[SUPPORT_URL="$withval"],
|
||||||
[SUPPORT_URL=http://lists.freedesktop.org/mailman/listinfo/systemd-devel])
|
[SUPPORT_URL=http://lists.freedesktop.org/mailman/listinfo/systemd-devel])
|
||||||
|
|
||||||
AC_SUBST(SUPPORT_URL)
|
AC_SUBST(SUPPORT_URL)
|
||||||
|
|
||||||
|
AC_ARG_WITH([nobody-user],
|
||||||
|
AS_HELP_STRING([--with-nobody-user=NAME],
|
||||||
|
[Specify the name of the nobody user (the one with UID 65534)]),
|
||||||
|
[NOBODY_USER_NAME="$withval"],
|
||||||
|
[NOBODY_USER_NAME=nobody])
|
||||||
|
|
||||||
|
AC_SUBST(NOBODY_USER_NAME)
|
||||||
|
AC_DEFINE_UNQUOTED(NOBODY_USER_NAME, ["$NOBODY_USER_NAME"], [The name of the nobody user (the one with UID 65534)])
|
||||||
|
|
||||||
|
AC_ARG_WITH([nobody-group],
|
||||||
|
AS_HELP_STRING([--with-nobody-group=NAME],
|
||||||
|
[Specify the name of the nobody group (the one with GID 65534)]),
|
||||||
|
[NOBODY_GROUP_NAME="$withval"],
|
||||||
|
[NOBODY_GROUP_NAME=nobody])
|
||||||
|
|
||||||
|
AC_SUBST(NOBODY_GROUP_NAME)
|
||||||
|
AC_DEFINE_UNQUOTED(NOBODY_GROUP_NAME, ["$NOBODY_GROUP_NAME"], [The name of the nobody group (the one with GID 65534)])
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
have_xz=no
|
have_xz=no
|
||||||
AC_ARG_ENABLE(xz, AS_HELP_STRING([--disable-xz], [Disable optional XZ support]))
|
AC_ARG_ENABLE(xz, AS_HELP_STRING([--disable-xz], [Disable optional XZ support]))
|
||||||
|
@ -1677,6 +1695,8 @@ AC_MSG_RESULT([
|
||||||
Maximum System GID: ${SYSTEM_GID_MAX}
|
Maximum System GID: ${SYSTEM_GID_MAX}
|
||||||
Certificate root: ${CERTIFICATEROOT}
|
Certificate root: ${CERTIFICATEROOT}
|
||||||
Support URL: ${SUPPORT_URL}
|
Support URL: ${SUPPORT_URL}
|
||||||
|
Nobody User Name: ${NOBODY_USER_NAME}
|
||||||
|
Nobody Group Name: ${NOBODY_GROUP_NAME}
|
||||||
|
|
||||||
CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
|
CFLAGS: ${OUR_CFLAGS} ${CFLAGS}
|
||||||
CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
|
CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS}
|
||||||
|
|
|
@ -61,6 +61,10 @@
|
||||||
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details on
|
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details on
|
||||||
this option.</para>
|
this option.</para>
|
||||||
|
|
||||||
|
<para>This module also ensures that the root and nobody users and groups (i.e. the users/groups with the UIDs/GIDs
|
||||||
|
0 and 65534) remain resolvable at all times, even if they aren't listed in <filename>/etc/passwd</filename> or
|
||||||
|
<filename>/etc/group</filename>, or if these files are missing.</para>
|
||||||
|
|
||||||
<para>To activate the NSS module, add <literal>systemd</literal> to the lines starting with
|
<para>To activate the NSS module, add <literal>systemd</literal> to the lines starting with
|
||||||
<literal>passwd:</literal> and <literal>group:</literal> in <filename>/etc/nsswitch.conf</filename>.</para>
|
<literal>passwd:</literal> and <literal>group:</literal> in <filename>/etc/nsswitch.conf</filename>.</para>
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,52 @@
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "nss-util.h"
|
#include "nss-util.h"
|
||||||
#include "signal-util.h"
|
#include "signal-util.h"
|
||||||
|
#include "string-util.h"
|
||||||
#include "user-util.h"
|
#include "user-util.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#ifndef NOBODY_USER_NAME
|
||||||
|
#define NOBODY_USER_NAME "nobody"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef NOBODY_GROUP_NAME
|
||||||
|
#define NOBODY_GROUP_NAME "nobody"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct passwd root_passwd = {
|
||||||
|
.pw_name = (char*) "root",
|
||||||
|
.pw_passwd = (char*) "x", /* see shadow file */
|
||||||
|
.pw_uid = 0,
|
||||||
|
.pw_gid = 0,
|
||||||
|
.pw_gecos = (char*) "Super User",
|
||||||
|
.pw_dir = (char*) "/root",
|
||||||
|
.pw_shell = (char*) "/bin/sh",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct passwd nobody_passwd = {
|
||||||
|
.pw_name = (char*) NOBODY_USER_NAME,
|
||||||
|
.pw_passwd = (char*) "*", /* locked */
|
||||||
|
.pw_uid = 65534,
|
||||||
|
.pw_gid = 65534,
|
||||||
|
.pw_gecos = (char*) "User Nobody",
|
||||||
|
.pw_dir = (char*) "/",
|
||||||
|
.pw_shell = (char*) "/sbin/nologin",
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct group root_group = {
|
||||||
|
.gr_name = (char*) "root",
|
||||||
|
.gr_gid = 0,
|
||||||
|
.gr_passwd = (char*) "x", /* see shadow file */
|
||||||
|
.gr_mem = (char*[]) { NULL },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct group nobody_group = {
|
||||||
|
.gr_name = (char*) NOBODY_GROUP_NAME,
|
||||||
|
.gr_gid = 65534,
|
||||||
|
.gr_passwd = (char*) "*", /* locked */
|
||||||
|
.gr_mem = (char*[]) { NULL },
|
||||||
|
};
|
||||||
|
|
||||||
NSS_GETPW_PROTOTYPES(systemd);
|
NSS_GETPW_PROTOTYPES(systemd);
|
||||||
NSS_GETGR_PROTOTYPES(systemd);
|
NSS_GETGR_PROTOTYPES(systemd);
|
||||||
|
|
||||||
|
@ -50,6 +93,23 @@ enum nss_status _nss_systemd_getpwnam_r(
|
||||||
assert(name);
|
assert(name);
|
||||||
assert(pwd);
|
assert(pwd);
|
||||||
|
|
||||||
|
if (!valid_user_group_name(name)) {
|
||||||
|
r = -EINVAL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */
|
||||||
|
if (streq(name, root_passwd.pw_name)) {
|
||||||
|
*pwd = root_passwd;
|
||||||
|
*errnop = 0;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
if (streq(name, nobody_passwd.pw_name)) {
|
||||||
|
*pwd = nobody_passwd;
|
||||||
|
*errnop = 0;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure that we don't go in circles when allocating a dynamic UID by checking our own database */
|
/* Make sure that we don't go in circles when allocating a dynamic UID by checking our own database */
|
||||||
if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
|
if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
|
@ -126,6 +186,18 @@ enum nss_status _nss_systemd_getpwuid_r(
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Synthesize data for the root user and for nobody in case they are missing from /etc/passwd */
|
||||||
|
if (uid == root_passwd.pw_uid) {
|
||||||
|
*pwd = root_passwd;
|
||||||
|
*errnop = 0;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
if (uid == nobody_passwd.pw_uid) {
|
||||||
|
*pwd = nobody_passwd;
|
||||||
|
*errnop = 0;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (uid <= SYSTEM_UID_MAX)
|
if (uid <= SYSTEM_UID_MAX)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
|
|
||||||
|
@ -202,6 +274,23 @@ enum nss_status _nss_systemd_getgrnam_r(
|
||||||
assert(name);
|
assert(name);
|
||||||
assert(gr);
|
assert(gr);
|
||||||
|
|
||||||
|
if (!valid_user_group_name(name)) {
|
||||||
|
r = -EINVAL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Synthesize records for root and nobody, in case they are missing form /etc/group */
|
||||||
|
if (streq(name, root_group.gr_name)) {
|
||||||
|
*gr = root_group;
|
||||||
|
*errnop = 0;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
if (streq(name, nobody_group.gr_name)) {
|
||||||
|
*gr = nobody_group;
|
||||||
|
*errnop = 0;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
|
if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
|
|
||||||
|
@ -275,6 +364,18 @@ enum nss_status _nss_systemd_getgrgid_r(
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Synthesize records for root and nobody, in case they are missing from /etc/group */
|
||||||
|
if (gid == root_group.gr_gid) {
|
||||||
|
*gr = root_group;
|
||||||
|
*errnop = 0;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
if (gid == nobody_group.gr_gid) {
|
||||||
|
*gr = nobody_group;
|
||||||
|
*errnop = 0;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
if (gid <= SYSTEM_GID_MAX)
|
if (gid <= SYSTEM_GID_MAX)
|
||||||
goto not_found;
|
goto not_found;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue