diff options
| -rw-r--r-- | configure.ac | 22 | ||||
| -rw-r--r-- | man/nss-systemd.xml | 4 | ||||
| -rw-r--r-- | src/nss-systemd/nss-systemd.c | 101 | 
3 files changed, 126 insertions, 1 deletions
| diff --git a/configure.ac b/configure.ac index a86deca471..4d1c96606f 100644 --- a/configure.ac +++ b/configure.ac @@ -556,12 +556,30 @@ AC_SUBST(CERTIFICATEROOT)  AC_ARG_WITH([support-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=http://lists.freedesktop.org/mailman/listinfo/systemd-devel])  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  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}          Certificate root:                  ${CERTIFICATEROOT}          Support URL:                       ${SUPPORT_URL} +        Nobody User Name:                  ${NOBODY_USER_NAME} +        Nobody Group Name:                 ${NOBODY_GROUP_NAME}          CFLAGS:   ${OUR_CFLAGS} ${CFLAGS}          CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS} diff --git a/man/nss-systemd.xml b/man/nss-systemd.xml index 4228372e51..56d26e7d1f 100644 --- a/man/nss-systemd.xml +++ b/man/nss-systemd.xml @@ -61,6 +61,10 @@      <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details on      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      <literal>passwd:</literal> and <literal>group:</literal> in <filename>/etc/nsswitch.conf</filename>.</para> diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c index e7a4393bb0..7078c0c50c 100644 --- a/src/nss-systemd/nss-systemd.c +++ b/src/nss-systemd/nss-systemd.c @@ -26,9 +26,52 @@  #include "macro.h"  #include "nss-util.h"  #include "signal-util.h" +#include "string-util.h"  #include "user-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_GETGR_PROTOTYPES(systemd); @@ -50,6 +93,23 @@ enum nss_status _nss_systemd_getpwnam_r(          assert(name);          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 */          if (getenv_bool("SYSTEMD_NSS_DYNAMIC_BYPASS") > 0)                  goto not_found; @@ -126,6 +186,18 @@ enum nss_status _nss_systemd_getpwuid_r(                  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)                  goto not_found; @@ -202,6 +274,23 @@ enum nss_status _nss_systemd_getgrnam_r(          assert(name);          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)                  goto not_found; @@ -275,6 +364,18 @@ enum nss_status _nss_systemd_getgrgid_r(                  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)                  goto not_found; | 
