mirror of
https://github.com/systemd/systemd
synced 2026-03-14 17:14:49 +01:00
Compare commits
8 Commits
63225fe159
...
ee3713b71d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee3713b71d | ||
|
|
c362a432af | ||
|
|
2c324dd161 | ||
|
|
67f7244928 | ||
|
|
2baec39665 | ||
|
|
f43a19ecd6 | ||
|
|
09001dbdc8 | ||
|
|
9137c03c04 |
@ -2,7 +2,8 @@
|
|||||||
|
|
||||||
passwd: compat systemd
|
passwd: compat systemd
|
||||||
group: compat [SUCCESS=merge] systemd
|
group: compat [SUCCESS=merge] systemd
|
||||||
shadow: compat
|
shadow: compat systemd
|
||||||
|
gshadow: files systemd
|
||||||
|
|
||||||
hosts: mymachines resolve [!UNAVAIL=return] files myhostname dns
|
hosts: mymachines resolve [!UNAVAIL=return] files myhostname dns
|
||||||
networks: files
|
networks: files
|
||||||
|
|||||||
@ -150,6 +150,7 @@ sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LJ:*
|
|||||||
|
|
||||||
sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LAB:*
|
sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LAB:*
|
||||||
sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LB:*
|
sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP500LB:*
|
||||||
|
sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP550LA:*
|
||||||
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
|
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
|
||||||
|
|
||||||
sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LD:*
|
sensor:modalias:acpi:SMO8500*:dmi:*svn*ASUSTeK*:*pn*TP300LD:*
|
||||||
|
|||||||
@ -91,7 +91,9 @@
|
|||||||
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
|
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
|
||||||
<programlisting>passwd: compat systemd
|
<programlisting>passwd: compat systemd
|
||||||
group: compat [SUCCESS=merge] systemd
|
group: compat [SUCCESS=merge] systemd
|
||||||
shadow: compat
|
shadow: compat systemd
|
||||||
|
gshadow: files systemd
|
||||||
|
|
||||||
|
|
||||||
# Either (untrusted network, see above):
|
# Either (untrusted network, see above):
|
||||||
hosts: mymachines resolve [!UNAVAIL=return] files <command>myhostname</command> dns
|
hosts: mymachines resolve [!UNAVAIL=return] files <command>myhostname</command> dns
|
||||||
|
|||||||
@ -57,7 +57,8 @@
|
|||||||
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
|
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
|
||||||
<programlisting>passwd: compat systemd
|
<programlisting>passwd: compat systemd
|
||||||
group: compat [SUCCESS=merge] systemd
|
group: compat [SUCCESS=merge] systemd
|
||||||
shadow: compat
|
shadow: compat systemd
|
||||||
|
gshadow: files systemd
|
||||||
|
|
||||||
hosts: <command>mymachines</command> resolve [!UNAVAIL=return] files myhostname dns
|
hosts: <command>mymachines</command> resolve [!UNAVAIL=return] files myhostname dns
|
||||||
networks: files
|
networks: files
|
||||||
|
|||||||
@ -63,7 +63,8 @@
|
|||||||
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
|
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
|
||||||
<programlisting>passwd: compat systemd
|
<programlisting>passwd: compat systemd
|
||||||
group: compat [SUCCESS=merge] systemd
|
group: compat [SUCCESS=merge] systemd
|
||||||
shadow: compat
|
shadow: compat systemd
|
||||||
|
gshadow: files systemd
|
||||||
|
|
||||||
hosts: mymachines <command>resolve [!UNAVAIL=return]</command> files myhostname dns
|
hosts: mymachines <command>resolve [!UNAVAIL=return]</command> files myhostname dns
|
||||||
networks: files
|
networks: files
|
||||||
|
|||||||
@ -47,11 +47,13 @@
|
|||||||
for resolving users and groups, but also works without the service running.</para>
|
for resolving users and groups, but also works without the service running.</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>, <literal>group:</literal>, <literal>shadow:</literal> and
|
||||||
|
<literal>gshadow:</literal> in <filename>/etc/nsswitch.conf</filename>.</para>
|
||||||
|
|
||||||
<para>It is recommended to place <literal>systemd</literal> after the <literal>files</literal> or
|
<para>It is recommended to place <literal>systemd</literal> after the <literal>files</literal> or
|
||||||
<literal>compat</literal> entry of the <filename>/etc/nsswitch.conf</filename> lines so that
|
<literal>compat</literal> entry of the <filename>/etc/nsswitch.conf</filename> lines so that
|
||||||
<filename>/etc/passwd</filename> and <filename>/etc/group</filename> based mappings take precedence.</para>
|
<filename>/etc/passwd</filename>, <filename>/etc/group</filename>, <filename>/etc/shadow</filename> and
|
||||||
|
<filename>/etc/gshadow</filename> based mappings take precedence.</para>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
@ -63,7 +65,8 @@
|
|||||||
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
|
<!-- synchronize with other nss-* man pages and factory/etc/nsswitch.conf -->
|
||||||
<programlisting>passwd: compat <command>systemd</command>
|
<programlisting>passwd: compat <command>systemd</command>
|
||||||
group: compat [SUCCESS=merge] <command>systemd</command>
|
group: compat [SUCCESS=merge] <command>systemd</command>
|
||||||
shadow: compat
|
shadow: compat <command>systemd</command>
|
||||||
|
gshadow: files <command>systemd</command>
|
||||||
|
|
||||||
hosts: mymachines resolve [!UNAVAIL=return] files myhostname dns
|
hosts: mymachines resolve [!UNAVAIL=return] files myhostname dns
|
||||||
networks: files
|
networks: files
|
||||||
|
|||||||
@ -79,6 +79,30 @@
|
|||||||
certificate from. The certificate must be in PEM format.</para></listitem>
|
certificate from. The certificate must be in PEM format.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--system</option></term>
|
||||||
|
<term><option>--user</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Limit served entries to entries from system
|
||||||
|
services and the kernel, or to entries from services of
|
||||||
|
current user. This has the same meaning as
|
||||||
|
<option>--system</option> and <option>--user</option> options
|
||||||
|
for
|
||||||
|
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. If
|
||||||
|
neither is specified, all accessible entries are served.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>-m</option></term>
|
||||||
|
<term><option>--merge</option></term>
|
||||||
|
|
||||||
|
<listitem><para>Serve entries interleaved from all available
|
||||||
|
journals, including other machines. This has the same meaning
|
||||||
|
as <option>--merge</option> option for
|
||||||
|
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><option>-D <replaceable>DIR</replaceable></option></term>
|
<term><option>-D <replaceable>DIR</replaceable></option></term>
|
||||||
<term><option>--directory=<replaceable>DIR</replaceable></option></term>
|
<term><option>--directory=<replaceable>DIR</replaceable></option></term>
|
||||||
@ -89,6 +113,19 @@
|
|||||||
the default runtime and system journal paths.</para></listitem>
|
the default runtime and system journal paths.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--file=<replaceable>GLOB</replaceable></option></term>
|
||||||
|
|
||||||
|
<listitem><para>Takes a file glob as an argument. Serve
|
||||||
|
entries from the specified journal files matching
|
||||||
|
<replaceable>GLOB</replaceable> instead of the default runtime
|
||||||
|
and system journal paths. May be specified multiple times, in
|
||||||
|
which case files will be suitably interleaved. This has the same meaning as
|
||||||
|
<option>--file=</option> option for
|
||||||
|
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<xi:include href="standard-options.xml" xpointer="help" />
|
<xi:include href="standard-options.xml" xpointer="help" />
|
||||||
<xi:include href="standard-options.xml" xpointer="version" />
|
<xi:include href="standard-options.xml" xpointer="version" />
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|||||||
@ -370,6 +370,18 @@ option('efi-includedir', type : 'string', value : '/usr/include/efi',
|
|||||||
description : 'path to the EFI header directory')
|
description : 'path to the EFI header directory')
|
||||||
option('tpm-pcrindex', type : 'integer', value : 8,
|
option('tpm-pcrindex', type : 'integer', value : 8,
|
||||||
description : 'TPM PCR register number to use')
|
description : 'TPM PCR register number to use')
|
||||||
|
option('sbat-distro', type : 'string',
|
||||||
|
description : 'SBAT distribution ID, e.g. fedora, or auto for autodetection')
|
||||||
|
option('sbat-distro-generation', type : 'integer', value : 1,
|
||||||
|
description : 'SBAT distribution generation')
|
||||||
|
option('sbat-distro-summary', type : 'string',
|
||||||
|
description : 'SBAT distribution summary, e.g. Fedora')
|
||||||
|
option('sbat-distro-pkgname', type : 'string',
|
||||||
|
description : 'SBAT distribution package name, e.g. systemd')
|
||||||
|
option('sbat-distro-version', type : 'string',
|
||||||
|
description : 'SBAT distribution package version, e.g. 248-7.fc34')
|
||||||
|
option('sbat-distro-url', type : 'string',
|
||||||
|
description : 'SBAT distribution URL, e.g. https://src.fedoraproject.org/rpms/systemd')
|
||||||
|
|
||||||
option('bashcompletiondir', type : 'string',
|
option('bashcompletiondir', type : 'string',
|
||||||
description : 'directory for bash completion scripts ["no" disables]')
|
description : 'directory for bash completion scripts ["no" disables]')
|
||||||
|
|||||||
@ -18,8 +18,6 @@
|
|||||||
# define _alloc_(...) __attribute__((__alloc_size__(__VA_ARGS__)))
|
# define _alloc_(...) __attribute__((__alloc_size__(__VA_ARGS__)))
|
||||||
#endif
|
#endif
|
||||||
#define _sentinel_ __attribute__((__sentinel__))
|
#define _sentinel_ __attribute__((__sentinel__))
|
||||||
#define _section_(x) __attribute__((__section__(x)))
|
|
||||||
#define _used_ __attribute__((__used__))
|
|
||||||
#define _destructor_ __attribute__((__destructor__))
|
#define _destructor_ __attribute__((__destructor__))
|
||||||
#define _deprecated_ __attribute__((__deprecated__))
|
#define _deprecated_ __attribute__((__deprecated__))
|
||||||
#define _packed_ __attribute__((__packed__))
|
#define _packed_ __attribute__((__packed__))
|
||||||
@ -30,7 +28,6 @@
|
|||||||
#define _public_ __attribute__((__visibility__("default")))
|
#define _public_ __attribute__((__visibility__("default")))
|
||||||
#define _hidden_ __attribute__((__visibility__("hidden")))
|
#define _hidden_ __attribute__((__visibility__("hidden")))
|
||||||
#define _weakref_(x) __attribute__((__weakref__(#x)))
|
#define _weakref_(x) __attribute__((__weakref__(#x)))
|
||||||
#define _align_(x) __attribute__((__aligned__(x)))
|
|
||||||
#define _alignas_(x) __attribute__((__aligned__(__alignof(x))))
|
#define _alignas_(x) __attribute__((__aligned__(__alignof(x))))
|
||||||
#define _alignptr_ __attribute__((__aligned__(sizeof(void*))))
|
#define _alignptr_ __attribute__((__aligned__(sizeof(void*))))
|
||||||
#if __GNUC__ >= 7
|
#if __GNUC__ >= 7
|
||||||
@ -138,9 +135,6 @@
|
|||||||
/* automake test harness */
|
/* automake test harness */
|
||||||
#define EXIT_TEST_SKIP 77
|
#define EXIT_TEST_SKIP 77
|
||||||
|
|
||||||
#define XSTRINGIFY(x) #x
|
|
||||||
#define STRINGIFY(x) XSTRINGIFY(x)
|
|
||||||
|
|
||||||
/* builtins */
|
/* builtins */
|
||||||
#if __SIZEOF_INT__ == 4
|
#if __SIZEOF_INT__ == 4
|
||||||
#define BUILTIN_FFS_U32(x) __builtin_ffs(x);
|
#define BUILTIN_FFS_U32(x) __builtin_ffs(x);
|
||||||
|
|||||||
@ -127,6 +127,20 @@ enum nss_status _nss_##module##_getpwuid_r( \
|
|||||||
char *buffer, size_t buflen, \
|
char *buffer, size_t buflen, \
|
||||||
int *errnop) _public_
|
int *errnop) _public_
|
||||||
|
|
||||||
|
#define NSS_GETSP_PROTOTYPES(module) \
|
||||||
|
enum nss_status _nss_##module##_getspnam_r( \
|
||||||
|
const char *name, \
|
||||||
|
struct spwd *spwd, \
|
||||||
|
char *buffer, size_t buflen, \
|
||||||
|
int *errnop) _public_
|
||||||
|
|
||||||
|
#define NSS_GETSG_PROTOTYPES(module) \
|
||||||
|
enum nss_status _nss_##module##_getsgnam_r( \
|
||||||
|
const char *name, \
|
||||||
|
struct sgrp *sgrp, \
|
||||||
|
char *buffer, size_t buflen, \
|
||||||
|
int *errnop) _public_
|
||||||
|
|
||||||
#define NSS_GETGR_PROTOTYPES(module) \
|
#define NSS_GETGR_PROTOTYPES(module) \
|
||||||
enum nss_status _nss_##module##_getgrnam_r( \
|
enum nss_status _nss_##module##_getgrnam_r( \
|
||||||
const char *name, \
|
const char *name, \
|
||||||
@ -150,6 +164,17 @@ enum nss_status _nss_##module##_getpwent_r( \
|
|||||||
size_t buflen, \
|
size_t buflen, \
|
||||||
int *errnop) _public_;
|
int *errnop) _public_;
|
||||||
|
|
||||||
|
#define NSS_SPENT_PROTOTYPES(module) \
|
||||||
|
enum nss_status _nss_##module##_endspent( \
|
||||||
|
void) _public_; \
|
||||||
|
enum nss_status _nss_##module##_setspent( \
|
||||||
|
int stayopen) _public_; \
|
||||||
|
enum nss_status _nss_##module##_getspent_r( \
|
||||||
|
struct spwd *spwd, \
|
||||||
|
char *buffer, \
|
||||||
|
size_t buflen, \
|
||||||
|
int *errnop) _public_;
|
||||||
|
|
||||||
#define NSS_GRENT_PROTOTYPES(module) \
|
#define NSS_GRENT_PROTOTYPES(module) \
|
||||||
enum nss_status _nss_##module##_endgrent( \
|
enum nss_status _nss_##module##_endgrent( \
|
||||||
void) _public_; \
|
void) _public_; \
|
||||||
@ -161,6 +186,17 @@ enum nss_status _nss_##module##_getgrent_r( \
|
|||||||
size_t buflen, \
|
size_t buflen, \
|
||||||
int *errnop) _public_;
|
int *errnop) _public_;
|
||||||
|
|
||||||
|
#define NSS_SGENT_PROTOTYPES(module) \
|
||||||
|
enum nss_status _nss_##module##_endsgent( \
|
||||||
|
void) _public_; \
|
||||||
|
enum nss_status _nss_##module##_setsgent( \
|
||||||
|
int stayopen) _public_; \
|
||||||
|
enum nss_status _nss_##module##_getsgent_r( \
|
||||||
|
struct sgrp *sgrp, \
|
||||||
|
char *buffer, \
|
||||||
|
size_t buflen, \
|
||||||
|
int *errnop) _public_;
|
||||||
|
|
||||||
#define NSS_INITGROUPS_PROTOTYPE(module) \
|
#define NSS_INITGROUPS_PROTOTYPE(module) \
|
||||||
enum nss_status _nss_##module##_initgroups_dyn( \
|
enum nss_status _nss_##module##_initgroups_dyn( \
|
||||||
const char *user, \
|
const char *user, \
|
||||||
|
|||||||
@ -102,6 +102,42 @@ if have_gnu_efi
|
|||||||
efi_conf.set10('ENABLE_TPM', get_option('tpm'))
|
efi_conf.set10('ENABLE_TPM', get_option('tpm'))
|
||||||
efi_conf.set('SD_TPM_PCR', get_option('tpm-pcrindex'))
|
efi_conf.set('SD_TPM_PCR', get_option('tpm-pcrindex'))
|
||||||
|
|
||||||
|
if get_option('sbat-distro') != ''
|
||||||
|
efi_conf.set_quoted('SBAT_PROJECT', meson.project_name())
|
||||||
|
efi_conf.set_quoted('PROJECT_VERSION', substs.get('PROJECT_VERSION'))
|
||||||
|
efi_conf.set_quoted('PROJECT_URL', substs.get('PROJECT_URL'))
|
||||||
|
if get_option('sbat-distro-generation') < 1
|
||||||
|
error('SBAT Distro Generation must be a positive integer')
|
||||||
|
endif
|
||||||
|
efi_conf.set('SBAT_DISTRO_GENERATION', get_option('sbat-distro-generation'))
|
||||||
|
sbatvars = [['sbat-distro', 'ID'],
|
||||||
|
['sbat-distro-summary', 'NAME'],
|
||||||
|
['sbat-distro-url', 'BUG_REPORT_URL']]
|
||||||
|
foreach sbatvar : sbatvars
|
||||||
|
value = get_option(sbatvar[0])
|
||||||
|
if value == '' or value == 'auto'
|
||||||
|
value = run_command('sh', '-c', 'if [ -e /etc/os-release ]; then . /etc/os-release; else . /usr/lib/os-release; fi; echo $' + sbatvar[1]).stdout().strip()
|
||||||
|
endif
|
||||||
|
if value == ''
|
||||||
|
error('Required @0@ option not set and autodetection failed'.format(sbatvar[0]))
|
||||||
|
endif
|
||||||
|
efi_conf.set_quoted(sbatvar[0].underscorify().to_upper(), value)
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
pkgname = get_option('sbat-distro-pkgname')
|
||||||
|
if pkgname == ''
|
||||||
|
pkgname = meson.project_name()
|
||||||
|
endif
|
||||||
|
efi_conf.set_quoted('SBAT_DISTRO_PKGNAME', pkgname)
|
||||||
|
|
||||||
|
pkgver = get_option('sbat-distro-version')
|
||||||
|
if pkgver == ''
|
||||||
|
efi_conf.set('SBAT_DISTRO_VERSION', 'GIT_VERSION')
|
||||||
|
else
|
||||||
|
efi_conf.set_quoted('SBAT_DISTRO_VERSION', pkgver)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
efi_config_h = configure_file(
|
efi_config_h = configure_file(
|
||||||
output : 'efi_config.h',
|
output : 'efi_config.h',
|
||||||
configuration : efi_conf)
|
configuration : efi_conf)
|
||||||
@ -244,6 +280,7 @@ if have_gnu_efi
|
|||||||
command : [objcopy,
|
command : [objcopy,
|
||||||
'-j', '.text',
|
'-j', '.text',
|
||||||
'-j', '.sdata',
|
'-j', '.sdata',
|
||||||
|
'-j', '.sbat',
|
||||||
'-j', '.data',
|
'-j', '.data',
|
||||||
'-j', '.dynamic',
|
'-j', '.dynamic',
|
||||||
'-j', '.dynsym',
|
'-j', '.dynsym',
|
||||||
|
|||||||
@ -11,3 +11,10 @@ BOOLEAN secure_boot_enabled(void) {
|
|||||||
|
|
||||||
return !EFI_ERROR(err) && secure;
|
return !EFI_ERROR(err) && secure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SBAT_DISTRO
|
||||||
|
static const char sbat[] _used_ _section_ (".sbat") _align_ (512) =
|
||||||
|
"sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md\n"
|
||||||
|
SBAT_PROJECT ",1,The systemd Developers," SBAT_PROJECT "," PROJECT_VERSION "," PROJECT_URL "\n"
|
||||||
|
SBAT_PROJECT "." SBAT_DISTRO "," STRINGIFY(SBAT_DISTRO_GENERATION) "," SBAT_DISTRO_SUMMARY "," SBAT_DISTRO_PKGNAME "," SBAT_DISTRO_VERSION "," SBAT_DISTRO_URL "\n";
|
||||||
|
#endif
|
||||||
|
|||||||
@ -7,11 +7,17 @@
|
|||||||
|
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
|
||||||
|
#define _align_(x) __attribute__((__aligned__(x)))
|
||||||
#define _const_ __attribute__((__const__))
|
#define _const_ __attribute__((__const__))
|
||||||
#define _pure_ __attribute__((__pure__))
|
#define _pure_ __attribute__((__pure__))
|
||||||
|
#define _section_(x) __attribute__((__section__(x)))
|
||||||
|
#define _used_ __attribute__((__used__))
|
||||||
#define _unused_ __attribute__((__unused__))
|
#define _unused_ __attribute__((__unused__))
|
||||||
#define _cleanup_(x) __attribute__((__cleanup__(x)))
|
#define _cleanup_(x) __attribute__((__cleanup__(x)))
|
||||||
|
|
||||||
|
#define XSTRINGIFY(x) #x
|
||||||
|
#define STRINGIFY(x) XSTRINGIFY(x)
|
||||||
|
|
||||||
#ifndef __COVERITY__
|
#ifndef __COVERITY__
|
||||||
# define VOID_0 ((void)0)
|
# define VOID_0 ((void)0)
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
|
#include "glob-util.h"
|
||||||
#include "hostname-util.h"
|
#include "hostname-util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "logs-show.h"
|
#include "logs-show.h"
|
||||||
@ -36,7 +37,10 @@
|
|||||||
static char *arg_key_pem = NULL;
|
static char *arg_key_pem = NULL;
|
||||||
static char *arg_cert_pem = NULL;
|
static char *arg_cert_pem = NULL;
|
||||||
static char *arg_trust_pem = NULL;
|
static char *arg_trust_pem = NULL;
|
||||||
|
static bool arg_merge = false;
|
||||||
|
static int arg_journal_type = 0;
|
||||||
static const char *arg_directory = NULL;
|
static const char *arg_directory = NULL;
|
||||||
|
static char **arg_file = NULL;
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_key_pem, erase_and_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_key_pem, erase_and_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_cert_pem, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_cert_pem, freep);
|
||||||
@ -110,9 +114,11 @@ static int open_journal(RequestMeta *m) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (arg_directory)
|
if (arg_directory)
|
||||||
return sd_journal_open_directory(&m->journal, arg_directory, 0);
|
return sd_journal_open_directory(&m->journal, arg_directory, arg_journal_type);
|
||||||
|
else if (arg_file)
|
||||||
|
return sd_journal_open_files(&m->journal, (const char**) arg_file, 0);
|
||||||
else
|
else
|
||||||
return sd_journal_open(&m->journal, SD_JOURNAL_LOCAL_ONLY|SD_JOURNAL_SYSTEM);
|
return sd_journal_open(&m->journal, (arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY) | arg_journal_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int request_meta_ensure_tmp(RequestMeta *m) {
|
static int request_meta_ensure_tmp(RequestMeta *m) {
|
||||||
@ -860,7 +866,11 @@ static int help(void) {
|
|||||||
" --cert=CERT.PEM Server certificate in PEM format\n"
|
" --cert=CERT.PEM Server certificate in PEM format\n"
|
||||||
" --key=KEY.PEM Server key in PEM format\n"
|
" --key=KEY.PEM Server key in PEM format\n"
|
||||||
" --trust=CERT.PEM Certificate authority certificate in PEM format\n"
|
" --trust=CERT.PEM Certificate authority certificate in PEM format\n"
|
||||||
|
" --system Serve system journal\n"
|
||||||
|
" --user Serve the user journal for the current user\n"
|
||||||
|
" -m --merge Serve all available journals\n"
|
||||||
" -D --directory=PATH Serve journal files in directory\n"
|
" -D --directory=PATH Serve journal files in directory\n"
|
||||||
|
" --file=PATH Serve this journal file\n"
|
||||||
"\nSee the %s for details.\n",
|
"\nSee the %s for details.\n",
|
||||||
program_invocation_short_name,
|
program_invocation_short_name,
|
||||||
link);
|
link);
|
||||||
@ -874,6 +884,10 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_KEY,
|
ARG_KEY,
|
||||||
ARG_CERT,
|
ARG_CERT,
|
||||||
ARG_TRUST,
|
ARG_TRUST,
|
||||||
|
ARG_USER,
|
||||||
|
ARG_SYSTEM,
|
||||||
|
ARG_MERGE,
|
||||||
|
ARG_FILE,
|
||||||
};
|
};
|
||||||
|
|
||||||
int r, c;
|
int r, c;
|
||||||
@ -884,7 +898,11 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "key", required_argument, NULL, ARG_KEY },
|
{ "key", required_argument, NULL, ARG_KEY },
|
||||||
{ "cert", required_argument, NULL, ARG_CERT },
|
{ "cert", required_argument, NULL, ARG_CERT },
|
||||||
{ "trust", required_argument, NULL, ARG_TRUST },
|
{ "trust", required_argument, NULL, ARG_TRUST },
|
||||||
|
{ "user", no_argument, NULL, ARG_USER },
|
||||||
|
{ "system", no_argument, NULL, ARG_SYSTEM },
|
||||||
|
{ "merge", no_argument, NULL, 'm' },
|
||||||
{ "directory", required_argument, NULL, 'D' },
|
{ "directory", required_argument, NULL, 'D' },
|
||||||
|
{ "file", required_argument, NULL, ARG_FILE },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -947,10 +965,29 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
"Option --trust= is not available.");
|
"Option --trust= is not available.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case ARG_SYSTEM:
|
||||||
|
arg_journal_type |= SD_JOURNAL_SYSTEM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARG_USER:
|
||||||
|
arg_journal_type |= SD_JOURNAL_CURRENT_USER;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
arg_merge = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
arg_directory = optarg;
|
arg_directory = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARG_FILE:
|
||||||
|
r = glob_extend(&arg_file, optarg, GLOB_NOCHECK);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to add paths: %m");
|
||||||
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
|||||||
@ -803,7 +803,7 @@ static int open_journal(sd_journal **j) {
|
|||||||
r = sd_journal_open_container(j, arg_machine, 0);
|
r = sd_journal_open_container(j, arg_machine, 0);
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
} else
|
} else
|
||||||
r = sd_journal_open(j, !arg_merge*SD_JOURNAL_LOCAL_ONLY + arg_journal_type);
|
r = sd_journal_open(j, (arg_merge ? 0 : SD_JOURNAL_LOCAL_ONLY) | arg_journal_type);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_error_errno(r, "Failed to open %s: %m",
|
log_error_errno(r, "Failed to open %s: %m",
|
||||||
arg_directory ? arg_directory : arg_file ? "files" : "journal");
|
arg_directory ? arg_directory : arg_file ? "files" : "journal");
|
||||||
|
|||||||
@ -28,6 +28,18 @@ static const struct passwd root_passwd = {
|
|||||||
.pw_shell = (char*) "/bin/sh",
|
.pw_shell = (char*) "/bin/sh",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct spwd root_spwd = {
|
||||||
|
.sp_namp = (char*) "root",
|
||||||
|
.sp_pwdp = (char*) PASSWORD_LOCKED_AND_INVALID,
|
||||||
|
.sp_lstchg = -1,
|
||||||
|
.sp_min = -1,
|
||||||
|
.sp_max = -1,
|
||||||
|
.sp_warn = -1,
|
||||||
|
.sp_inact = -1,
|
||||||
|
.sp_expire = -1,
|
||||||
|
.sp_flag = ULONG_MAX, /* this appears to be what everybody does ... */
|
||||||
|
};
|
||||||
|
|
||||||
static const struct passwd nobody_passwd = {
|
static const struct passwd nobody_passwd = {
|
||||||
.pw_name = (char*) NOBODY_USER_NAME,
|
.pw_name = (char*) NOBODY_USER_NAME,
|
||||||
.pw_passwd = (char*) PASSWORD_LOCKED_AND_INVALID,
|
.pw_passwd = (char*) PASSWORD_LOCKED_AND_INVALID,
|
||||||
@ -38,6 +50,18 @@ static const struct passwd nobody_passwd = {
|
|||||||
.pw_shell = (char*) NOLOGIN,
|
.pw_shell = (char*) NOLOGIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct spwd nobody_spwd = {
|
||||||
|
.sp_namp = (char*) NOBODY_USER_NAME,
|
||||||
|
.sp_pwdp = (char*) PASSWORD_LOCKED_AND_INVALID,
|
||||||
|
.sp_lstchg = -1,
|
||||||
|
.sp_min = -1,
|
||||||
|
.sp_max = -1,
|
||||||
|
.sp_warn = -1,
|
||||||
|
.sp_inact = -1,
|
||||||
|
.sp_expire = -1,
|
||||||
|
.sp_flag = ULONG_MAX, /* this appears to be what everybody does ... */
|
||||||
|
};
|
||||||
|
|
||||||
static const struct group root_group = {
|
static const struct group root_group = {
|
||||||
.gr_name = (char*) "root",
|
.gr_name = (char*) "root",
|
||||||
.gr_gid = 0,
|
.gr_gid = 0,
|
||||||
@ -45,6 +69,11 @@ static const struct group root_group = {
|
|||||||
.gr_mem = (char*[]) { NULL },
|
.gr_mem = (char*[]) { NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct sgrp root_sgrp = {
|
||||||
|
.sg_namp = (char*) "root",
|
||||||
|
.sg_passwd = (char*) PASSWORD_LOCKED_AND_INVALID,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct group nobody_group = {
|
static const struct group nobody_group = {
|
||||||
.gr_name = (char*) NOBODY_GROUP_NAME,
|
.gr_name = (char*) NOBODY_GROUP_NAME,
|
||||||
.gr_gid = GID_NOBODY,
|
.gr_gid = GID_NOBODY,
|
||||||
@ -52,6 +81,11 @@ static const struct group nobody_group = {
|
|||||||
.gr_mem = (char*[]) { NULL },
|
.gr_mem = (char*[]) { NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct sgrp nobody_sgrp = {
|
||||||
|
.sg_namp = (char*) NOBODY_GROUP_NAME,
|
||||||
|
.sg_passwd = (char*) PASSWORD_LOCKED_AND_INVALID,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct GetentData {
|
typedef struct GetentData {
|
||||||
/* As explained in NOTES section of getpwent_r(3) as 'getpwent_r() is not really reentrant since it
|
/* As explained in NOTES section of getpwent_r(3) as 'getpwent_r() is not really reentrant since it
|
||||||
* shares the reading position in the stream with all other threads', we need to protect the data in
|
* shares the reading position in the stream with all other threads', we need to protect the data in
|
||||||
@ -66,11 +100,19 @@ typedef struct GetentData {
|
|||||||
} GetentData;
|
} GetentData;
|
||||||
|
|
||||||
static GetentData getpwent_data = {
|
static GetentData getpwent_data = {
|
||||||
.mutex = PTHREAD_MUTEX_INITIALIZER
|
.mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||||
};
|
};
|
||||||
|
|
||||||
static GetentData getgrent_data = {
|
static GetentData getgrent_data = {
|
||||||
.mutex = PTHREAD_MUTEX_INITIALIZER
|
.mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||||
|
};
|
||||||
|
|
||||||
|
static GetentData getspent_data = {
|
||||||
|
.mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||||
|
};
|
||||||
|
|
||||||
|
static GetentData getsgent_data = {
|
||||||
|
.mutex = PTHREAD_MUTEX_INITIALIZER,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void setup_logging(void) {
|
static void setup_logging(void) {
|
||||||
@ -88,9 +130,13 @@ static void setup_logging_once(void) {
|
|||||||
setup_logging_once()
|
setup_logging_once()
|
||||||
|
|
||||||
NSS_GETPW_PROTOTYPES(systemd);
|
NSS_GETPW_PROTOTYPES(systemd);
|
||||||
|
NSS_GETSP_PROTOTYPES(systemd);
|
||||||
NSS_GETGR_PROTOTYPES(systemd);
|
NSS_GETGR_PROTOTYPES(systemd);
|
||||||
|
NSS_GETSG_PROTOTYPES(systemd);
|
||||||
NSS_PWENT_PROTOTYPES(systemd);
|
NSS_PWENT_PROTOTYPES(systemd);
|
||||||
|
NSS_SPENT_PROTOTYPES(systemd);
|
||||||
NSS_GRENT_PROTOTYPES(systemd);
|
NSS_GRENT_PROTOTYPES(systemd);
|
||||||
|
NSS_SGENT_PROTOTYPES(systemd);
|
||||||
NSS_INITGROUPS_PROTOTYPE(systemd);
|
NSS_INITGROUPS_PROTOTYPE(systemd);
|
||||||
|
|
||||||
enum nss_status _nss_systemd_getpwnam_r(
|
enum nss_status _nss_systemd_getpwnam_r(
|
||||||
@ -191,6 +237,54 @@ enum nss_status _nss_systemd_getpwuid_r(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum nss_status _nss_systemd_getspnam_r(
|
||||||
|
const char *name,
|
||||||
|
struct spwd *spwd,
|
||||||
|
char *buffer, size_t buflen,
|
||||||
|
int *errnop) {
|
||||||
|
|
||||||
|
enum nss_status status;
|
||||||
|
int e;
|
||||||
|
|
||||||
|
PROTECT_ERRNO;
|
||||||
|
NSS_ENTRYPOINT_BEGIN;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
assert(spwd);
|
||||||
|
assert(errnop);
|
||||||
|
|
||||||
|
if (!valid_user_group_name(name, VALID_USER_RELAX))
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
/* Synthesize entries for the root and nobody users, in case they are missing in /etc/passwd */
|
||||||
|
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
|
||||||
|
|
||||||
|
if (streq(name, root_spwd.sp_namp)) {
|
||||||
|
*spwd = root_spwd;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streq(name, nobody_spwd.sp_namp)) {
|
||||||
|
if (!synthesize_nobody())
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
*spwd = nobody_spwd;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (STR_IN_SET(name, root_spwd.sp_namp, nobody_spwd.sp_namp))
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
status = userdb_getspnam(name, spwd, buffer, buflen, &e);
|
||||||
|
if (IN_SET(status, NSS_STATUS_UNAVAIL, NSS_STATUS_TRYAGAIN)) {
|
||||||
|
UNPROTECT_ERRNO;
|
||||||
|
*errnop = e;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wsizeof-pointer-memaccess"
|
#pragma GCC diagnostic ignored "-Wsizeof-pointer-memaccess"
|
||||||
|
|
||||||
enum nss_status _nss_systemd_getgrnam_r(
|
enum nss_status _nss_systemd_getgrnam_r(
|
||||||
@ -288,6 +382,54 @@ enum nss_status _nss_systemd_getgrgid_r(
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum nss_status _nss_systemd_getsgnam_r(
|
||||||
|
const char *name,
|
||||||
|
struct sgrp *sgrp,
|
||||||
|
char *buffer, size_t buflen,
|
||||||
|
int *errnop) {
|
||||||
|
|
||||||
|
enum nss_status status;
|
||||||
|
int e;
|
||||||
|
|
||||||
|
PROTECT_ERRNO;
|
||||||
|
NSS_ENTRYPOINT_BEGIN;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
assert(sgrp);
|
||||||
|
assert(errnop);
|
||||||
|
|
||||||
|
if (!valid_user_group_name(name, VALID_USER_RELAX))
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
/* Synthesize records for root and nobody, in case they are missing from /etc/group */
|
||||||
|
if (getenv_bool_secure("SYSTEMD_NSS_BYPASS_SYNTHETIC") <= 0) {
|
||||||
|
|
||||||
|
if (streq(name, root_sgrp.sg_namp)) {
|
||||||
|
*sgrp = root_sgrp;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streq(name, nobody_sgrp.sg_namp)) {
|
||||||
|
if (!synthesize_nobody())
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
*sgrp = nobody_sgrp;
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (STR_IN_SET(name, root_sgrp.sg_namp, nobody_sgrp.sg_namp))
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
status = userdb_getsgnam(name, sgrp, buffer, buflen, &e);
|
||||||
|
if (IN_SET(status, NSS_STATUS_UNAVAIL, NSS_STATUS_TRYAGAIN)) {
|
||||||
|
UNPROTECT_ERRNO;
|
||||||
|
*errnop = e;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
static enum nss_status nss_systemd_endent(GetentData *p) {
|
static enum nss_status nss_systemd_endent(GetentData *p) {
|
||||||
PROTECT_ERRNO;
|
PROTECT_ERRNO;
|
||||||
NSS_ENTRYPOINT_BEGIN;
|
NSS_ENTRYPOINT_BEGIN;
|
||||||
@ -307,10 +449,18 @@ enum nss_status _nss_systemd_endpwent(void) {
|
|||||||
return nss_systemd_endent(&getpwent_data);
|
return nss_systemd_endent(&getpwent_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum nss_status _nss_systemd_endspent(void) {
|
||||||
|
return nss_systemd_endent(&getspent_data);
|
||||||
|
}
|
||||||
|
|
||||||
enum nss_status _nss_systemd_endgrent(void) {
|
enum nss_status _nss_systemd_endgrent(void) {
|
||||||
return nss_systemd_endent(&getgrent_data);
|
return nss_systemd_endent(&getgrent_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum nss_status _nss_systemd_endsgent(void) {
|
||||||
|
return nss_systemd_endent(&getsgent_data);
|
||||||
|
}
|
||||||
|
|
||||||
enum nss_status _nss_systemd_setpwent(int stayopen) {
|
enum nss_status _nss_systemd_setpwent(int stayopen) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -355,6 +505,46 @@ enum nss_status _nss_systemd_setgrent(int stayopen) {
|
|||||||
return r < 0 ? NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS;
|
return r < 0 ? NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum nss_status _nss_systemd_setspent(int stayopen) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
PROTECT_ERRNO;
|
||||||
|
NSS_ENTRYPOINT_BEGIN;
|
||||||
|
|
||||||
|
if (_nss_systemd_is_blocked())
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
_cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = pthread_mutex_lock_assert(&getspent_data.mutex);
|
||||||
|
(void) _l; /* make llvm shut up about _l not being used. */
|
||||||
|
|
||||||
|
getspent_data.iterator = userdb_iterator_free(getspent_data.iterator);
|
||||||
|
getspent_data.by_membership = false;
|
||||||
|
|
||||||
|
/* See _nss_systemd_setpwent() for an explanation why we use USERDB_DONT_SYNTHESIZE here */
|
||||||
|
r = userdb_all(nss_glue_userdb_flags() | USERDB_DONT_SYNTHESIZE, &getspent_data.iterator);
|
||||||
|
return r < 0 ? NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum nss_status _nss_systemd_setsgent(int stayopen) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
PROTECT_ERRNO;
|
||||||
|
NSS_ENTRYPOINT_BEGIN;
|
||||||
|
|
||||||
|
if (_nss_systemd_is_blocked())
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
_cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = pthread_mutex_lock_assert(&getsgent_data.mutex);
|
||||||
|
(void) _l; /* make llvm shut up about _l not being used. */
|
||||||
|
|
||||||
|
getsgent_data.iterator = userdb_iterator_free(getsgent_data.iterator);
|
||||||
|
getsgent_data.by_membership = false;
|
||||||
|
|
||||||
|
/* See _nss_systemd_setpwent() for an explanation why we use USERDB_DONT_SYNTHESIZE here */
|
||||||
|
r = groupdb_all(nss_glue_userdb_flags() | USERDB_DONT_SYNTHESIZE, &getsgent_data.iterator);
|
||||||
|
return r < 0 ? NSS_STATUS_UNAVAIL : NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
enum nss_status _nss_systemd_getpwent_r(
|
enum nss_status _nss_systemd_getpwent_r(
|
||||||
struct passwd *result,
|
struct passwd *result,
|
||||||
char *buffer, size_t buflen,
|
char *buffer, size_t buflen,
|
||||||
@ -527,6 +717,110 @@ enum nss_status _nss_systemd_getgrent_r(
|
|||||||
return NSS_STATUS_SUCCESS;
|
return NSS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum nss_status _nss_systemd_getspent_r(
|
||||||
|
struct spwd *result,
|
||||||
|
char *buffer, size_t buflen,
|
||||||
|
int *errnop) {
|
||||||
|
|
||||||
|
_cleanup_(user_record_unrefp) UserRecord *ur = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
PROTECT_ERRNO;
|
||||||
|
NSS_ENTRYPOINT_BEGIN;
|
||||||
|
|
||||||
|
assert(result);
|
||||||
|
assert(errnop);
|
||||||
|
|
||||||
|
if (_nss_systemd_is_blocked())
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
_cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = pthread_mutex_lock_assert(&getspent_data.mutex);
|
||||||
|
(void) _l; /* make llvm shut up about _l not being used. */
|
||||||
|
|
||||||
|
if (!getspent_data.iterator) {
|
||||||
|
UNPROTECT_ERRNO;
|
||||||
|
*errnop = EHOSTDOWN;
|
||||||
|
return NSS_STATUS_UNAVAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
r = userdb_iterator_get(getspent_data.iterator, &ur);
|
||||||
|
if (r == -ESRCH)
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
if (r < 0) {
|
||||||
|
UNPROTECT_ERRNO;
|
||||||
|
*errnop = -r;
|
||||||
|
return NSS_STATUS_UNAVAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ur->incomplete) /* don't synthesize shadow records for records where we couldn't read shadow data */
|
||||||
|
break;
|
||||||
|
|
||||||
|
ur = user_record_unref(ur);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = nss_pack_user_record_shadow(ur, result, buffer, buflen);
|
||||||
|
if (r < 0) {
|
||||||
|
UNPROTECT_ERRNO;
|
||||||
|
*errnop = -r;
|
||||||
|
return NSS_STATUS_TRYAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum nss_status _nss_systemd_getsgent_r(
|
||||||
|
struct sgrp *result,
|
||||||
|
char *buffer, size_t buflen,
|
||||||
|
int *errnop) {
|
||||||
|
|
||||||
|
_cleanup_(group_record_unrefp) GroupRecord *gr = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
PROTECT_ERRNO;
|
||||||
|
NSS_ENTRYPOINT_BEGIN;
|
||||||
|
|
||||||
|
assert(result);
|
||||||
|
assert(errnop);
|
||||||
|
|
||||||
|
if (_nss_systemd_is_blocked())
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
_cleanup_(pthread_mutex_unlock_assertp) pthread_mutex_t *_l = pthread_mutex_lock_assert(&getsgent_data.mutex);
|
||||||
|
(void) _l; /* make llvm shut up about _l not being used. */
|
||||||
|
|
||||||
|
if (!getsgent_data.iterator) {
|
||||||
|
UNPROTECT_ERRNO;
|
||||||
|
*errnop = EHOSTDOWN;
|
||||||
|
return NSS_STATUS_UNAVAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
r = groupdb_iterator_get(getsgent_data.iterator, &gr);
|
||||||
|
if (r == -ESRCH)
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
if (r < 0) {
|
||||||
|
UNPROTECT_ERRNO;
|
||||||
|
*errnop = -r;
|
||||||
|
return NSS_STATUS_UNAVAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gr->incomplete) /* don't synthesize shadow records for records where we couldn't read shadow data */
|
||||||
|
break;
|
||||||
|
|
||||||
|
gr = group_record_unref(gr);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = nss_pack_group_record_shadow(gr, result, buffer, buflen);
|
||||||
|
if (r < 0) {
|
||||||
|
UNPROTECT_ERRNO;
|
||||||
|
*errnop = -r;
|
||||||
|
return NSS_STATUS_TRYAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
enum nss_status _nss_systemd_initgroups_dyn(
|
enum nss_status _nss_systemd_initgroups_dyn(
|
||||||
const char *user_name,
|
const char *user_name,
|
||||||
gid_t gid,
|
gid_t gid,
|
||||||
|
|||||||
@ -10,15 +10,23 @@
|
|||||||
{
|
{
|
||||||
global:
|
global:
|
||||||
_nss_systemd_getpwnam_r;
|
_nss_systemd_getpwnam_r;
|
||||||
|
_nss_systemd_getspnam_r;
|
||||||
_nss_systemd_getpwuid_r;
|
_nss_systemd_getpwuid_r;
|
||||||
_nss_systemd_endpwent;
|
_nss_systemd_endpwent;
|
||||||
_nss_systemd_setpwent;
|
_nss_systemd_setpwent;
|
||||||
_nss_systemd_getpwent_r;
|
_nss_systemd_getpwent_r;
|
||||||
|
_nss_systemd_endspent;
|
||||||
|
_nss_systemd_setspent;
|
||||||
|
_nss_systemd_getspent_r;
|
||||||
_nss_systemd_getgrnam_r;
|
_nss_systemd_getgrnam_r;
|
||||||
|
_nss_systemd_getsgnam_r;
|
||||||
_nss_systemd_getgrgid_r;
|
_nss_systemd_getgrgid_r;
|
||||||
_nss_systemd_endgrent;
|
_nss_systemd_endgrent;
|
||||||
_nss_systemd_setgrent;
|
_nss_systemd_setgrent;
|
||||||
_nss_systemd_getgrent_r;
|
_nss_systemd_getgrent_r;
|
||||||
|
_nss_systemd_endsgent;
|
||||||
|
_nss_systemd_setsgent;
|
||||||
|
_nss_systemd_getsgent_r;
|
||||||
_nss_systemd_initgroups_dyn;
|
_nss_systemd_initgroups_dyn;
|
||||||
|
|
||||||
/* These two are not used by glibc, but can be used by apps to explicitly disable nss-systemd for the calling thread. */
|
/* These two are not used by glibc, but can be used by apps to explicitly disable nss-systemd for the calling thread. */
|
||||||
|
|||||||
@ -32,7 +32,7 @@ int nss_pack_user_record(
|
|||||||
assert(hr);
|
assert(hr);
|
||||||
assert(pwd);
|
assert(pwd);
|
||||||
|
|
||||||
assert_se(hr->user_name);
|
assert(hr->user_name);
|
||||||
required = strlen(hr->user_name) + 1;
|
required = strlen(hr->user_name) + 1;
|
||||||
|
|
||||||
assert_se(rn = user_record_real_name(hr));
|
assert_se(rn = user_record_real_name(hr));
|
||||||
@ -79,7 +79,7 @@ enum nss_status userdb_getpwnam(
|
|||||||
if (_nss_systemd_is_blocked())
|
if (_nss_systemd_is_blocked())
|
||||||
return NSS_STATUS_NOTFOUND;
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
r = userdb_by_name(name, nss_glue_userdb_flags(), &hr);
|
r = userdb_by_name(name, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &hr);
|
||||||
if (r == -ESRCH)
|
if (r == -ESRCH)
|
||||||
return NSS_STATUS_NOTFOUND;
|
return NSS_STATUS_NOTFOUND;
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@ -112,7 +112,7 @@ enum nss_status userdb_getpwuid(
|
|||||||
if (_nss_systemd_is_blocked())
|
if (_nss_systemd_is_blocked())
|
||||||
return NSS_STATUS_NOTFOUND;
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
r = userdb_by_uid(uid, nss_glue_userdb_flags(), &hr);
|
r = userdb_by_uid(uid, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &hr);
|
||||||
if (r == -ESRCH)
|
if (r == -ESRCH)
|
||||||
return NSS_STATUS_NOTFOUND;
|
return NSS_STATUS_NOTFOUND;
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
@ -129,6 +129,85 @@ enum nss_status userdb_getpwuid(
|
|||||||
return NSS_STATUS_SUCCESS;
|
return NSS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nss_pack_user_record_shadow(
|
||||||
|
UserRecord *hr,
|
||||||
|
struct spwd *spwd,
|
||||||
|
char *buffer,
|
||||||
|
size_t buflen) {
|
||||||
|
|
||||||
|
const char *hashed;
|
||||||
|
size_t required;
|
||||||
|
|
||||||
|
assert(hr);
|
||||||
|
assert(spwd);
|
||||||
|
|
||||||
|
assert(hr->user_name);
|
||||||
|
required = strlen(hr->user_name) + 1;
|
||||||
|
|
||||||
|
assert_se(hashed = strv_isempty(hr->hashed_password) ? PASSWORD_LOCKED_AND_INVALID : hr->hashed_password[0]);
|
||||||
|
required += strlen(hashed) + 1;
|
||||||
|
|
||||||
|
if (buflen < required)
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
*spwd = (struct spwd) {
|
||||||
|
.sp_namp = buffer,
|
||||||
|
.sp_lstchg = hr->last_password_change_usec == 0 ? 1 : /* map 0 to 1, since 0 means please change pasword on next login */
|
||||||
|
hr->last_password_change_usec == UINT64_MAX ? -1 :
|
||||||
|
(long int) (hr->last_password_change_usec / USEC_PER_DAY),
|
||||||
|
.sp_min = hr->password_change_min_usec != UINT64_MAX ? (long int) (hr->password_change_min_usec / USEC_PER_DAY) : -1,
|
||||||
|
.sp_max = hr->password_change_max_usec != UINT64_MAX ? (long int) (hr->password_change_max_usec / USEC_PER_DAY) : -1,
|
||||||
|
.sp_warn = hr->password_change_warn_usec != UINT64_MAX ? (long int) (hr->password_change_warn_usec / USEC_PER_DAY) : -1,
|
||||||
|
.sp_inact = hr->password_change_inactive_usec != UINT64_MAX ? (long int) (hr->password_change_inactive_usec / USEC_PER_DAY) : -1,
|
||||||
|
.sp_expire = hr->locked > 0 || hr->not_after_usec == 0 ? 1 : /* already expired/locked */
|
||||||
|
hr->not_after_usec == UINT64_MAX ? -1 :
|
||||||
|
(long int) (hr->not_after_usec / USEC_PER_DAY),
|
||||||
|
.sp_flag = ULONG_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(buffer);
|
||||||
|
|
||||||
|
spwd->sp_pwdp = stpcpy(spwd->sp_namp, hr->user_name) + 1;
|
||||||
|
strcpy(spwd->sp_pwdp, hashed);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum nss_status userdb_getspnam(
|
||||||
|
const char *name,
|
||||||
|
struct spwd *spwd,
|
||||||
|
char *buffer, size_t buflen,
|
||||||
|
int *errnop) {
|
||||||
|
|
||||||
|
_cleanup_(user_record_unrefp) UserRecord *hr = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(spwd);
|
||||||
|
assert(errnop);
|
||||||
|
|
||||||
|
if (_nss_systemd_is_blocked())
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
r = userdb_by_name(name, nss_glue_userdb_flags(), &hr);
|
||||||
|
if (r == -ESRCH)
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
if (r < 0) {
|
||||||
|
*errnop = -r;
|
||||||
|
return NSS_STATUS_UNAVAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hr->incomplete) /* protected records missing? */
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
r = nss_pack_user_record_shadow(hr, spwd, buffer, buflen);
|
||||||
|
if (r < 0) {
|
||||||
|
*errnop = -r;
|
||||||
|
return NSS_STATUS_TRYAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int nss_pack_group_record(
|
int nss_pack_group_record(
|
||||||
GroupRecord *g,
|
GroupRecord *g,
|
||||||
char **extra_members,
|
char **extra_members,
|
||||||
@ -142,7 +221,7 @@ int nss_pack_group_record(
|
|||||||
assert(g);
|
assert(g);
|
||||||
assert(gr);
|
assert(gr);
|
||||||
|
|
||||||
assert_se(g->group_name);
|
assert(g->group_name);
|
||||||
required = strlen(g->group_name) + 1;
|
required = strlen(g->group_name) + 1;
|
||||||
|
|
||||||
STRV_FOREACH(m, g->members) {
|
STRV_FOREACH(m, g->members) {
|
||||||
@ -209,13 +288,13 @@ enum nss_status userdb_getgrnam(
|
|||||||
if (_nss_systemd_is_blocked())
|
if (_nss_systemd_is_blocked())
|
||||||
return NSS_STATUS_NOTFOUND;
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
r = groupdb_by_name(name, nss_glue_userdb_flags(), &g);
|
r = groupdb_by_name(name, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &g);
|
||||||
if (r < 0 && r != -ESRCH) {
|
if (r < 0 && r != -ESRCH) {
|
||||||
*errnop = -r;
|
*errnop = -r;
|
||||||
return NSS_STATUS_UNAVAIL;
|
return NSS_STATUS_UNAVAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = membershipdb_by_group_strv(name, nss_glue_userdb_flags(), &members);
|
r = membershipdb_by_group_strv(name, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &members);
|
||||||
if (r < 0 && r != -ESRCH) {
|
if (r < 0 && r != -ESRCH) {
|
||||||
*errnop = -r;
|
*errnop = -r;
|
||||||
return NSS_STATUS_UNAVAIL;
|
return NSS_STATUS_UNAVAIL;
|
||||||
@ -277,7 +356,7 @@ enum nss_status userdb_getgrgid(
|
|||||||
if (_nss_systemd_is_blocked())
|
if (_nss_systemd_is_blocked())
|
||||||
return NSS_STATUS_NOTFOUND;
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
r = groupdb_by_gid(gid, nss_glue_userdb_flags(), &g);
|
r = groupdb_by_gid(gid, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &g);
|
||||||
if (r < 0 && r != -ESRCH) {
|
if (r < 0 && r != -ESRCH) {
|
||||||
*errnop = -r;
|
*errnop = -r;
|
||||||
return NSS_STATUS_UNAVAIL;
|
return NSS_STATUS_UNAVAIL;
|
||||||
@ -308,7 +387,7 @@ enum nss_status userdb_getgrgid(
|
|||||||
} else
|
} else
|
||||||
from_nss = false;
|
from_nss = false;
|
||||||
|
|
||||||
r = membershipdb_by_group_strv(g->group_name, nss_glue_userdb_flags(), &members);
|
r = membershipdb_by_group_strv(g->group_name, nss_glue_userdb_flags()|USERDB_SUPPRESS_SHADOW, &members);
|
||||||
if (r < 0 && r != -ESRCH) {
|
if (r < 0 && r != -ESRCH) {
|
||||||
*errnop = -r;
|
*errnop = -r;
|
||||||
return NSS_STATUS_UNAVAIL;
|
return NSS_STATUS_UNAVAIL;
|
||||||
@ -327,3 +406,71 @@ enum nss_status userdb_getgrgid(
|
|||||||
|
|
||||||
return NSS_STATUS_SUCCESS;
|
return NSS_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int nss_pack_group_record_shadow(
|
||||||
|
GroupRecord *hr,
|
||||||
|
struct sgrp *sgrp,
|
||||||
|
char *buffer,
|
||||||
|
size_t buflen) {
|
||||||
|
|
||||||
|
const char *hashed;
|
||||||
|
size_t required;
|
||||||
|
|
||||||
|
assert(hr);
|
||||||
|
assert(sgrp);
|
||||||
|
|
||||||
|
assert(hr->group_name);
|
||||||
|
required = strlen(hr->group_name) + 1;
|
||||||
|
|
||||||
|
assert_se(hashed = strv_isempty(hr->hashed_password) ? PASSWORD_LOCKED_AND_INVALID : hr->hashed_password[0]);
|
||||||
|
required += strlen(hashed) + 1;
|
||||||
|
|
||||||
|
if (buflen < required)
|
||||||
|
return -ERANGE;
|
||||||
|
|
||||||
|
*sgrp = (struct sgrp) {
|
||||||
|
.sg_namp = buffer,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert(buffer);
|
||||||
|
|
||||||
|
sgrp->sg_passwd = stpcpy(sgrp->sg_namp, hr->group_name) + 1;
|
||||||
|
strcpy(sgrp->sg_passwd, hashed);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum nss_status userdb_getsgnam(
|
||||||
|
const char *name,
|
||||||
|
struct sgrp *sgrp,
|
||||||
|
char *buffer, size_t buflen,
|
||||||
|
int *errnop) {
|
||||||
|
|
||||||
|
_cleanup_(group_record_unrefp) GroupRecord *hr = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(sgrp);
|
||||||
|
assert(errnop);
|
||||||
|
|
||||||
|
if (_nss_systemd_is_blocked())
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
r = groupdb_by_name(name, nss_glue_userdb_flags(), &hr);
|
||||||
|
if (r == -ESRCH)
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
if (r < 0) {
|
||||||
|
*errnop = -r;
|
||||||
|
return NSS_STATUS_UNAVAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hr->incomplete) /* protected records missing? */
|
||||||
|
return NSS_STATUS_NOTFOUND;
|
||||||
|
|
||||||
|
r = nss_pack_group_record_shadow(hr, sgrp, buffer, buflen);
|
||||||
|
if (r < 0) {
|
||||||
|
*errnop = -r;
|
||||||
|
return NSS_STATUS_TRYAGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NSS_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|||||||
@ -13,8 +13,15 @@ UserDBFlags nss_glue_userdb_flags(void);
|
|||||||
int nss_pack_user_record(UserRecord *hr, struct passwd *pwd, char *buffer, size_t buflen);
|
int nss_pack_user_record(UserRecord *hr, struct passwd *pwd, char *buffer, size_t buflen);
|
||||||
int nss_pack_group_record(GroupRecord *g, char **extra_members, struct group *gr, char *buffer, size_t buflen);
|
int nss_pack_group_record(GroupRecord *g, char **extra_members, struct group *gr, char *buffer, size_t buflen);
|
||||||
|
|
||||||
|
int nss_pack_user_record_shadow(UserRecord *hr, struct spwd *spwd, char *buffer, size_t buflen);
|
||||||
|
int nss_pack_group_record_shadow(GroupRecord *hr, struct sgrp *sgrp, char *buffer,size_t buflen);
|
||||||
|
|
||||||
enum nss_status userdb_getpwnam(const char *name, struct passwd *pwd, char *buffer, size_t buflen, int *errnop);
|
enum nss_status userdb_getpwnam(const char *name, struct passwd *pwd, char *buffer, size_t buflen, int *errnop);
|
||||||
enum nss_status userdb_getpwuid(uid_t uid, struct passwd *pwd, char *buffer, size_t buflen, int *errnop);
|
enum nss_status userdb_getpwuid(uid_t uid, struct passwd *pwd, char *buffer, size_t buflen, int *errnop);
|
||||||
|
|
||||||
|
enum nss_status userdb_getspnam(const char *name, struct spwd *spwd, char *buffer, size_t buflen, int *errnop);
|
||||||
|
|
||||||
enum nss_status userdb_getgrnam(const char *name, struct group *gr, char *buffer, size_t buflen, int *errnop);
|
enum nss_status userdb_getgrnam(const char *name, struct group *gr, char *buffer, size_t buflen, int *errnop);
|
||||||
enum nss_status userdb_getgrgid(gid_t gid, struct group *gr, char *buffer, size_t buflen, int *errnop);
|
enum nss_status userdb_getgrgid(gid_t gid, struct group *gr, char *buffer, size_t buflen, int *errnop);
|
||||||
|
|
||||||
|
enum nss_status userdb_getsgnam(const char *name, struct sgrp *sgrp, char *buffer, size_t buflen, int *errnop);
|
||||||
|
|||||||
@ -1141,15 +1141,16 @@ void manager_refresh_rrs(Manager *m) {
|
|||||||
m->mdns_host_ipv4_key = dns_resource_key_unref(m->mdns_host_ipv4_key);
|
m->mdns_host_ipv4_key = dns_resource_key_unref(m->mdns_host_ipv4_key);
|
||||||
m->mdns_host_ipv6_key = dns_resource_key_unref(m->mdns_host_ipv6_key);
|
m->mdns_host_ipv6_key = dns_resource_key_unref(m->mdns_host_ipv6_key);
|
||||||
|
|
||||||
|
HASHMAP_FOREACH(l, m->links)
|
||||||
|
link_add_rrs(l, true);
|
||||||
|
|
||||||
if (m->mdns_support == RESOLVE_SUPPORT_YES)
|
if (m->mdns_support == RESOLVE_SUPPORT_YES)
|
||||||
HASHMAP_FOREACH(s, m->dnssd_services)
|
HASHMAP_FOREACH(s, m->dnssd_services)
|
||||||
if (dnssd_update_rrs(s) < 0)
|
if (dnssd_update_rrs(s) < 0)
|
||||||
log_warning("Failed to refresh DNS-SD service '%s'", s->name);
|
log_warning("Failed to refresh DNS-SD service '%s'", s->name);
|
||||||
|
|
||||||
HASHMAP_FOREACH(l, m->links) {
|
HASHMAP_FOREACH(l, m->links)
|
||||||
link_add_rrs(l, true);
|
|
||||||
link_add_rrs(l, false);
|
link_add_rrs(l, false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int manager_next_random_name(const char *old, char **ret_new) {
|
static int manager_next_random_name(const char *old, char **ret_new) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user