userdb: suppress userdb queries for backends indicating uid/gid/name range info via xattrs on entrypoint sockets (#42961)
Let's optimize userdb queries a bit: by encoding the covered UID/GID ranges and user/group name patterns on the varlink entrypoint sockets for userdb backends we can make them wake up less and reduce the work triggered by queries.
This commit is contained in:
@@ -327,6 +327,37 @@ Services which are asked for enumeration may return the `EnumerationNotSupported
|
||||
|
||||
And that's really all there is to it.
|
||||
|
||||
## Reducing IPC Requests
|
||||
|
||||
In many cases backends are only interested in responding to certain UID/GID
|
||||
ranges, or only to user/group names matching a specific pattern. To optimize
|
||||
look-ups in this case it is possible to indicate on the Varlink entrypoint
|
||||
socket inode of the service which ranges or patterns these are: if the kernel
|
||||
supports extended attributes on socket inodes (Linux >= 7.1), the following
|
||||
extended attributes may be set:
|
||||
|
||||
* `user.userdb.uid` takes a comma separated list of UIDs or dash-separated UID
|
||||
range pairs. If set, then the service will not be contacted for any UID
|
||||
look-ups outside of this range. Example: setting the extended attribute to
|
||||
`61184-65519,524288-1879048191,4711` will have the effect that a lookup for
|
||||
UID 1051 will not be attempted against this service, but one for 62334 will be.
|
||||
|
||||
* `user.userdb.gid` is similar, but for GIDs and GID ranges.
|
||||
|
||||
* `user.userdb.username` takes a NUL separated list of `fnmatch()` style glob
|
||||
expressions. If set only look-ups for user names matching at least one of
|
||||
these expressions will be routed to this service. Example: setting the
|
||||
extended attribute to `foo-*\0www*h?` (where `\0` shall indicate the NUL
|
||||
byte) will route only look-ups for `foo-bar` and `wwwooosh7` to this service,
|
||||
but not `waldo`.
|
||||
|
||||
* `user.userdb.groupname` is similar, but for group names.
|
||||
|
||||
Note that these extended attributes are intended for optimization only: any
|
||||
backend *must* be prepared to answer look-ups for any UID, GID, user and group
|
||||
name, and respond with `NoRecordFound` for requests outside of the
|
||||
ranges/patterns defined this way.
|
||||
|
||||
## Command Line Access
|
||||
|
||||
For command line access you can use the
|
||||
|
||||
+17
-4
@@ -4,12 +4,14 @@
|
||||
|
||||
#include "constants.h"
|
||||
#include "errno-util.h"
|
||||
#include "format-util.h"
|
||||
#include "job.h"
|
||||
#include "json-util.h"
|
||||
#include "manager.h"
|
||||
#include "metrics.h"
|
||||
#include "path-util.h"
|
||||
#include "pidref.h"
|
||||
#include "stdio-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "unit.h"
|
||||
@@ -27,6 +29,7 @@
|
||||
#include "varlink-serialize.h"
|
||||
#include "varlink-unit.h"
|
||||
#include "varlink-util.h"
|
||||
#include "xattr-util.h"
|
||||
|
||||
static const char* const managed_oom_mode_properties[] = {
|
||||
"ManagedOOMSwap",
|
||||
@@ -481,10 +484,14 @@ int manager_setup_varlink_metrics_server(Manager *m) {
|
||||
if (MANAGER_IS_SYSTEM(m))
|
||||
flags |= SD_VARLINK_SERVER_ACCOUNT_UID;
|
||||
|
||||
return metrics_setup_varlink_server(&m->metrics_varlink_server, flags,
|
||||
m->event, EVENT_PRIORITY_IPC,
|
||||
vl_method_list_metrics, vl_method_describe_metrics,
|
||||
m);
|
||||
return metrics_setup_varlink_server(
|
||||
&m->metrics_varlink_server,
|
||||
flags,
|
||||
m->event,
|
||||
EVENT_PRIORITY_IPC,
|
||||
vl_method_list_metrics,
|
||||
vl_method_describe_metrics,
|
||||
m);
|
||||
}
|
||||
|
||||
static int varlink_server_listen_many_idempotent_sentinel(
|
||||
@@ -549,6 +556,12 @@ static int manager_varlink_init_system_api(Manager *m) {
|
||||
VARLINK_PATH_MANAGED_OOM_SYSTEM);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Reduce the noise routed to us: advertise that only look-ups for the dynamic UID range should go to us */
|
||||
char text[DECIMAL_STR_MAX(uid_t) + 1 + DECIMAL_STR_MAX(gid_t) + 1];
|
||||
xsprintf(text, UID_FMT "-" UID_FMT, (uid_t) DYNAMIC_UID_MIN, (uid_t) DYNAMIC_UID_MAX);
|
||||
FOREACH_STRING(xattr, "user.userdb.uid", "user.userdb.gid")
|
||||
(void) xsetxattr(AT_FDCWD, "/run/systemd/userdb/io.systemd.DynamicUser", /* at_flags= */ 0, xattr, text);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -65,6 +65,7 @@
|
||||
#include "varlink-io.systemd.UserDatabase.h"
|
||||
#include "varlink-io.systemd.service.h"
|
||||
#include "varlink-util.h"
|
||||
#include "xattr-util.h"
|
||||
|
||||
/* Where to look for private/public keys that are used to sign the user records. We are not using
|
||||
* CONF_PATHS_NULSTR() here since we want to insert /var/lib/systemd/home/ in the middle. And we insert that
|
||||
@@ -1102,6 +1103,13 @@ static int manager_bind_varlink(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind to varlink socket '%s': %m", socket_path);
|
||||
|
||||
/* Reduce the noise routed to us: advertise that only look-ups for non-system users in the 16bit
|
||||
* range are routed to us (excluding 'nobody', i.e. 0xfffe) */
|
||||
char text[DECIMAL_STR_MAX(uid_t) + 1 + DECIMAL_STR_MAX(gid_t) + 1];
|
||||
xsprintf(text, UID_FMT "-" UID_FMT, (uid_t) (SYSTEM_UID_MAX + 1), UID_NOBODY - 1);
|
||||
FOREACH_STRING(xattr, "user.userdb.uid", "user.userdb.gid")
|
||||
(void) xsetxattr(AT_FDCWD, socket_path, /* at_flags= */ 0, xattr, text);
|
||||
|
||||
r = sd_varlink_server_attach_event(m->varlink_server, m->event, SD_EVENT_PRIORITY_NORMAL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "varlink-io.systemd.Resolve.Hook.h"
|
||||
#include "varlink-io.systemd.service.h"
|
||||
#include "varlink-util.h"
|
||||
#include "xattr-util.h"
|
||||
|
||||
typedef struct LookupParameters {
|
||||
const char *user_name;
|
||||
@@ -774,6 +775,14 @@ static int manager_varlink_init_userdb(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind to varlink socket %s: %m", VARLINK_PATH_MACHINED_USERDB);
|
||||
|
||||
/* Reduce the noise routed to us: advertise that only look-ups for the higher UID range */
|
||||
char text[DECIMAL_STR_MAX(uid_t) + 1 + DECIMAL_STR_MAX(gid_t) + 1];
|
||||
xsprintf(text, UID_FMT "-" UID_FMT, (uid_t) 0x10000U, (uid_t) UINT32_C(0xfffffffe));
|
||||
FOREACH_STRING(xattr, "user.userdb.uid", "user.userdb.gid")
|
||||
(void) xsetxattr(AT_FDCWD, VARLINK_PATH_MACHINED_USERDB, /* at_flags= */ 0, xattr, text);
|
||||
(void) xsetxattr(AT_FDCWD, VARLINK_PATH_MACHINED_USERDB, /* at_flags= */ 0, "user.userdb.username", "vu-*");
|
||||
(void) xsetxattr(AT_FDCWD, VARLINK_PATH_MACHINED_USERDB, /* at_flags= */ 0, "user.userdb.groupname", "vg-*");
|
||||
|
||||
r = sd_varlink_server_attach_event(s, m->event, SD_EVENT_PRIORITY_NORMAL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to attach varlink connection to event loop: %m");
|
||||
|
||||
@@ -33,10 +33,12 @@
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "time-util.h"
|
||||
#include "uid-classification.h"
|
||||
#include "umask-util.h"
|
||||
#include "unaligned.h"
|
||||
#include "userns-registry.h"
|
||||
#include "userns-restrict.h"
|
||||
#include "xattr-util.h"
|
||||
|
||||
#define LISTEN_TIMEOUT_USEC (25 * USEC_PER_SEC)
|
||||
|
||||
@@ -450,6 +452,16 @@ static int manager_make_listen_socket(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to symlink userdb socket: %m");
|
||||
|
||||
/* Reduce the noise routed to us: advertise that only look-ups for the higher UID range */
|
||||
char text[2 * (DECIMAL_STR_MAX(uid_t) + 1 + DECIMAL_STR_MAX(uid_t) + 1)];
|
||||
xsprintf(text, UID_FMT "-" UID_FMT "," UID_FMT "-" UID_FMT,
|
||||
CONTAINER_UID_MIN, CONTAINER_UID_MAX,
|
||||
(uid_t) DYNAMIC_UID_MIN, (uid_t) DYNAMIC_UID_MAX);
|
||||
FOREACH_STRING(xattr, "user.userdb.uid", "user.userdb.gid")
|
||||
(void) xsetxattr(AT_FDCWD, sockaddr.un.sun_path, /* at_flags= */ 0, xattr, text);
|
||||
(void) xsetxattr(AT_FDCWD, sockaddr.un.sun_path, /* at_flags= */ 0, "user.userdb.username", "ns-*");
|
||||
(void) xsetxattr(AT_FDCWD, sockaddr.un.sun_path, /* at_flags= */ 0, "user.userdb.groupname", "ns-*");
|
||||
|
||||
if (listen(m->listen_fd, SOMAXCONN) < 0)
|
||||
return log_error_errno(errno, "Failed to listen on socket: %m");
|
||||
|
||||
|
||||
+231
-11
@@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <fnmatch.h>
|
||||
#include <gshadow.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@@ -18,6 +19,7 @@
|
||||
#include "log.h"
|
||||
#include "parse-util.h"
|
||||
#include "set.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "uid-classification.h"
|
||||
@@ -25,6 +27,7 @@
|
||||
#include "user-util.h"
|
||||
#include "userdb.h"
|
||||
#include "userdb-dropin.h"
|
||||
#include "xattr-util.h"
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(link_hash_ops, void, trivial_hash_func, trivial_compare_func, sd_varlink, sd_varlink_unref);
|
||||
|
||||
@@ -35,6 +38,14 @@ typedef enum LookupWhat {
|
||||
_LOOKUP_WHAT_MAX,
|
||||
} LookupWhat;
|
||||
|
||||
typedef struct SocketFilter {
|
||||
/* Restricts the sockets to connect to */
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
const char *username;
|
||||
const char *groupname;
|
||||
} SocketFilter;
|
||||
|
||||
struct UserDBIterator {
|
||||
LookupWhat what;
|
||||
UserDBFlags flags;
|
||||
@@ -505,11 +516,138 @@ static int userdb_connect(
|
||||
return r;
|
||||
}
|
||||
|
||||
static int socket_filter_id_test(
|
||||
id_t id,
|
||||
const char *xattr,
|
||||
int dir_fd,
|
||||
const char *fname,
|
||||
const char *full_path /* for logging only */) {
|
||||
|
||||
int r;
|
||||
|
||||
assert(xattr);
|
||||
assert(dir_fd >= 0);
|
||||
assert(fname);
|
||||
assert(full_path);
|
||||
|
||||
/* Generic implementation for both UIDs and GIDs */
|
||||
|
||||
if (!uid_is_valid(id))
|
||||
return true;
|
||||
|
||||
/* Looks for an xattr of the specified name on the referenced socket entrypoint inode. Parses this
|
||||
* as a pair of start UID/end UID. Matches the specified UID against it. If it matches yay. If it
|
||||
* doesn't nay. If no UID is specified or no xattr set, also yay. */
|
||||
|
||||
_cleanup_free_ char *t = NULL;
|
||||
r = getxattr_at_malloc(dir_fd, fname, xattr, AT_SYMLINK_FOLLOW, &t, /* ret_size= */ NULL);
|
||||
if (r == -ENODATA)
|
||||
return true; /* no such xattr? match! */
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) {
|
||||
log_debug_errno(r, "Extended attributes on sockets not supported after all, ignoring: %m");
|
||||
return true; /* if sockets don't support xattrs here, then this is a match */
|
||||
}
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Unexpected error while reading extended attribute '%s' of '%s', ignoring: %m", xattr, full_path);
|
||||
|
||||
_cleanup_strv_free_ char **l = strv_split(t, ",");
|
||||
if (!l)
|
||||
return log_oom_debug();
|
||||
|
||||
STRV_FOREACH(i, l) {
|
||||
/* Single UID or UID range */
|
||||
uid_t x, y;
|
||||
r = parse_uid_range(*i, &x, &y);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Malformed extended attribute '%s' on '%s', ignoring.", xattr, full_path);
|
||||
|
||||
if (id >= x && id <= y)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int socket_filter_name_test(
|
||||
const char *name,
|
||||
const char *xattr,
|
||||
int dir_fd,
|
||||
const char *fname,
|
||||
const char *full_path /* for logging only */) {
|
||||
|
||||
int r;
|
||||
|
||||
assert(xattr);
|
||||
assert(dir_fd >= 0);
|
||||
assert(fname);
|
||||
assert(full_path);
|
||||
|
||||
/* Looks for an xattr of the specified name on the referenced socket entrypoint inode. Parses this
|
||||
* as a NUL terminated string list. Matches the specified name against it via fnmatch(). If it matches
|
||||
* yay. If it doesn't nay. If no name is specified or no xattr set, also yay. */
|
||||
|
||||
if (!name)
|
||||
return true;
|
||||
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
r = getxattr_at_strv(dir_fd, fname, xattr, AT_SYMLINK_FOLLOW, &l);
|
||||
if (r == -ENODATA)
|
||||
return true; /* no such xattr? match! */
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) {
|
||||
log_debug_errno(r, "Extended attributes on sockets not supported after all, ignoring: %m");
|
||||
return true; /* if sockets don't support xattrs here, then this is a match */
|
||||
}
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Unexpected error while reading extended attribute '%s' of '%s', ignoring: %m", xattr, full_path);
|
||||
|
||||
return strv_fnmatch_full(l, name, FNM_NOESCAPE, /* ret_matched_pos= */ NULL);
|
||||
}
|
||||
|
||||
static int socket_filter_test(
|
||||
const SocketFilter *sfilter,
|
||||
int dir_fd,
|
||||
const char *fname,
|
||||
const char *full_path /* for logging only */) {
|
||||
|
||||
assert(dir_fd >= 0);
|
||||
assert(fname);
|
||||
assert(full_path);
|
||||
|
||||
/* Before we contact a Varlink service, let's see if there's any chance it might answer our questions
|
||||
* at all. For such pre-filtering a userdb backend can install xattrs on their entrypoint inode to
|
||||
* indicate that it's never going to answer outside of a certain UID/GID range or username/groupname
|
||||
* pattern */
|
||||
|
||||
/* No filter means all sockets match */
|
||||
if (!sfilter)
|
||||
return 1;
|
||||
|
||||
/* No xattr support? then all sockets match. This check mostly exists to take benefit of the internal caching
|
||||
* of the test. Either way we'll check below again. */
|
||||
if (socket_xattr_supported() == 0)
|
||||
return 1;
|
||||
|
||||
if (socket_filter_id_test(sfilter->uid, "user.userdb.uid", dir_fd, fname, full_path) == 0)
|
||||
return 0;
|
||||
|
||||
if (socket_filter_id_test(sfilter->gid, "user.userdb.gid", dir_fd, fname, full_path) == 0)
|
||||
return 0;
|
||||
|
||||
if (socket_filter_name_test(sfilter->username, "user.userdb.username", dir_fd, fname, full_path) == 0)
|
||||
return 0;
|
||||
|
||||
if (socket_filter_name_test(sfilter->groupname, "user.userdb.groupname", dir_fd, fname, full_path) == 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int userdb_start_query(
|
||||
UserDBIterator *iterator,
|
||||
const char *method, /* must be a static string, we are not going to copy this here! */
|
||||
bool more,
|
||||
sd_json_variant *query,
|
||||
const SocketFilter *sfilter,
|
||||
UserDBFlags flags) {
|
||||
|
||||
_cleanup_strv_free_ char **except = NULL, **only = NULL;
|
||||
@@ -601,6 +739,12 @@ static int userdb_start_query(
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
r = socket_filter_test(sfilter, dirfd(d), de->d_name, p);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to filter sockets, ignoring: %m");
|
||||
else if (r == 0)
|
||||
continue;
|
||||
|
||||
r = userdb_connect(iterator, p, method, more, query);
|
||||
if (is_nss && r >= 0) /* Turn off fallback NSS + dropin if we found the NSS/dropin service
|
||||
* and could connect to it */
|
||||
@@ -928,8 +1072,20 @@ int userdb_by_name(const char *name, const UserDBMatch *match, UserDBFlags flags
|
||||
if (!iterator)
|
||||
return -ENOMEM;
|
||||
|
||||
SocketFilter sfilter = {
|
||||
.uid = UID_INVALID,
|
||||
.gid = GID_INVALID,
|
||||
.username = name,
|
||||
};
|
||||
|
||||
_cleanup_(user_record_unrefp) UserRecord *ur = NULL;
|
||||
r = userdb_start_query(iterator, "io.systemd.UserDatabase.GetUserRecord", /* more= */ false, query, flags);
|
||||
r = userdb_start_query(
|
||||
iterator,
|
||||
"io.systemd.UserDatabase.GetUserRecord",
|
||||
/* more= */ false,
|
||||
query,
|
||||
&sfilter,
|
||||
flags);
|
||||
if (r >= 0) {
|
||||
r = userdb_process(iterator, &ur, /* ret_group_record= */ NULL, /* ret_user_name= */ NULL, /* ret_group_name= */ NULL);
|
||||
if (r == -ENOEXEC) /* Found a user matching UID or name, but not filter. In this case the
|
||||
@@ -1018,8 +1174,19 @@ int userdb_by_uid(uid_t uid, const UserDBMatch *match, UserDBFlags flags, UserRe
|
||||
if (!iterator)
|
||||
return -ENOMEM;
|
||||
|
||||
SocketFilter sfilter = {
|
||||
.uid = uid,
|
||||
.gid = GID_INVALID,
|
||||
};
|
||||
|
||||
_cleanup_(user_record_unrefp) UserRecord *ur = NULL;
|
||||
r = userdb_start_query(iterator, "io.systemd.UserDatabase.GetUserRecord", /* more= */ false, query, flags);
|
||||
r = userdb_start_query(
|
||||
iterator,
|
||||
"io.systemd.UserDatabase.GetUserRecord",
|
||||
/* more= */ false,
|
||||
query,
|
||||
&sfilter,
|
||||
flags);
|
||||
if (r >= 0) {
|
||||
r = userdb_process(iterator, &ur, /* ret_group_record= */ NULL, /* ret_user_name= */ NULL, /* ret_group_name= */ NULL);
|
||||
if (r == -ENOEXEC)
|
||||
@@ -1055,7 +1222,13 @@ int userdb_all(const UserDBMatch *match, UserDBFlags flags, UserDBIterator **ret
|
||||
if (!iterator)
|
||||
return -ENOMEM;
|
||||
|
||||
qr = userdb_start_query(iterator, "io.systemd.UserDatabase.GetUserRecord", /* more= */ true, query, flags);
|
||||
qr = userdb_start_query(
|
||||
iterator,
|
||||
"io.systemd.UserDatabase.GetUserRecord",
|
||||
/* more= */ true,
|
||||
query,
|
||||
/* sfilter= */ NULL,
|
||||
flags);
|
||||
|
||||
if (!FLAGS_SET(flags, USERDB_EXCLUDE_NSS) && (qr < 0 || !iterator->nss_covered)) {
|
||||
r = userdb_iterator_block_nss_systemd(iterator);
|
||||
@@ -1384,8 +1557,20 @@ int groupdb_by_name(const char *name, const UserDBMatch *match, UserDBFlags flag
|
||||
if (!iterator)
|
||||
return -ENOMEM;
|
||||
|
||||
SocketFilter sfilter = {
|
||||
.uid = UID_INVALID,
|
||||
.gid = GID_INVALID,
|
||||
.groupname = name,
|
||||
};
|
||||
|
||||
_cleanup_(group_record_unrefp) GroupRecord *gr = NULL;
|
||||
r = userdb_start_query(iterator, "io.systemd.UserDatabase.GetGroupRecord", /* more= */ false, query, flags);
|
||||
r = userdb_start_query(
|
||||
iterator,
|
||||
"io.systemd.UserDatabase.GetGroupRecord",
|
||||
/* more= */ false,
|
||||
query,
|
||||
&sfilter,
|
||||
flags);
|
||||
if (r >= 0) {
|
||||
r = userdb_process(iterator, /* ret_user_record= */ NULL, &gr, /* ret_user_name= */ NULL, /* ret_group_name= */ NULL);
|
||||
if (r == -ENOEXEC)
|
||||
@@ -1418,13 +1603,13 @@ static int groupdb_by_gid_fallbacks(
|
||||
assert(iterator);
|
||||
assert(ret);
|
||||
|
||||
if (!FLAGS_SET(flags, USERDB_EXCLUDE_DROPIN) && !(iterator && iterator->dropin_covered)) {
|
||||
if (!FLAGS_SET(flags, USERDB_EXCLUDE_DROPIN) && !iterator->dropin_covered) {
|
||||
r = dropin_group_record_by_gid(gid, NULL, flags, ret);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!FLAGS_SET(flags, USERDB_EXCLUDE_NSS) && !(iterator && iterator->nss_covered)) {
|
||||
if (!FLAGS_SET(flags, USERDB_EXCLUDE_NSS) && !iterator->nss_covered) {
|
||||
r = userdb_iterator_block_nss_systemd(iterator);
|
||||
if (r >= 0) {
|
||||
r = nss_group_record_by_gid(gid, !FLAGS_SET(flags, USERDB_SUPPRESS_SHADOW), ret);
|
||||
@@ -1470,8 +1655,19 @@ int groupdb_by_gid(gid_t gid, const UserDBMatch *match, UserDBFlags flags, Group
|
||||
if (!iterator)
|
||||
return -ENOMEM;
|
||||
|
||||
SocketFilter sfilter = {
|
||||
.uid = UID_INVALID,
|
||||
.gid = gid,
|
||||
};
|
||||
|
||||
_cleanup_(group_record_unrefp) GroupRecord *gr = NULL;
|
||||
r = userdb_start_query(iterator, "io.systemd.UserDatabase.GetGroupRecord", /* more= */ false, query, flags);
|
||||
r = userdb_start_query(
|
||||
iterator,
|
||||
"io.systemd.UserDatabase.GetGroupRecord",
|
||||
/* more= */ false,
|
||||
query,
|
||||
&sfilter,
|
||||
flags);
|
||||
if (r >= 0) {
|
||||
r = userdb_process(iterator, /* ret_user_record= */ NULL, &gr, /* ret_user_name= */ NULL, /* ret_group_name= */ NULL);
|
||||
if (r == -ENOEXEC)
|
||||
@@ -1507,7 +1703,13 @@ int groupdb_all(const UserDBMatch *match, UserDBFlags flags, UserDBIterator **re
|
||||
if (!iterator)
|
||||
return -ENOMEM;
|
||||
|
||||
qr = userdb_start_query(iterator, "io.systemd.UserDatabase.GetGroupRecord", /* more= */ true, query, flags);
|
||||
qr = userdb_start_query(
|
||||
iterator,
|
||||
"io.systemd.UserDatabase.GetGroupRecord",
|
||||
/* more= */ true,
|
||||
query,
|
||||
/* sfilter= */ NULL,
|
||||
flags);
|
||||
|
||||
if (!FLAGS_SET(flags, USERDB_EXCLUDE_NSS) && (qr < 0 || !iterator->nss_covered)) {
|
||||
r = userdb_iterator_block_nss_systemd(iterator);
|
||||
@@ -1698,7 +1900,13 @@ int membershipdb_by_user(const char *name, UserDBFlags flags, UserDBIterator **r
|
||||
if (!iterator->filter_user_name)
|
||||
return -ENOMEM;
|
||||
|
||||
qr = userdb_start_query(iterator, "io.systemd.UserDatabase.GetMemberships", true, query, flags);
|
||||
qr = userdb_start_query(
|
||||
iterator,
|
||||
"io.systemd.UserDatabase.GetMemberships",
|
||||
/* more= */ true,
|
||||
query,
|
||||
/* sfilter= */ NULL,
|
||||
flags);
|
||||
|
||||
if (!FLAGS_SET(flags, USERDB_EXCLUDE_NSS) && (qr < 0 || !iterator->nss_covered)) {
|
||||
r = userdb_iterator_block_nss_systemd(iterator);
|
||||
@@ -1743,7 +1951,13 @@ int membershipdb_by_group(const char *name, UserDBFlags flags, UserDBIterator **
|
||||
if (!iterator->filter_group_name)
|
||||
return -ENOMEM;
|
||||
|
||||
qr = userdb_start_query(iterator, "io.systemd.UserDatabase.GetMemberships", true, query, flags);
|
||||
qr = userdb_start_query(
|
||||
iterator,
|
||||
"io.systemd.UserDatabase.GetMemberships",
|
||||
/* more= */ true,
|
||||
query,
|
||||
/* sfilter= */ NULL,
|
||||
flags);
|
||||
|
||||
if (!FLAGS_SET(flags, USERDB_EXCLUDE_NSS) && (qr < 0 || !iterator->nss_covered)) {
|
||||
_cleanup_(group_record_unrefp) GroupRecord *gr = NULL;
|
||||
@@ -1789,7 +2003,13 @@ int membershipdb_all(UserDBFlags flags, UserDBIterator **ret) {
|
||||
if (!iterator)
|
||||
return -ENOMEM;
|
||||
|
||||
qr = userdb_start_query(iterator, "io.systemd.UserDatabase.GetMemberships", true, NULL, flags);
|
||||
qr = userdb_start_query(
|
||||
iterator,
|
||||
"io.systemd.UserDatabase.GetMemberships",
|
||||
/* more= */ true,
|
||||
/* query= */ NULL,
|
||||
/* sfilter= */ NULL,
|
||||
flags);
|
||||
|
||||
if (!FLAGS_SET(flags, USERDB_EXCLUDE_NSS) && (qr < 0 || !iterator->nss_covered)) {
|
||||
r = userdb_iterator_block_nss_systemd(iterator);
|
||||
|
||||
+1
-1
@@ -1040,7 +1040,7 @@ units = [
|
||||
'conditions' : ['ENABLE_NSRESOURCED'],
|
||||
},
|
||||
{
|
||||
'file' : 'systemd-nsresourced.socket',
|
||||
'file' : 'systemd-nsresourced.socket.in',
|
||||
'conditions' : ['ENABLE_NSRESOURCED'],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -22,6 +22,10 @@ FileDescriptorName=varlink
|
||||
SocketMode=0666
|
||||
XAttrEntryPoint=user.varlink=entrypoint
|
||||
XAttrListen=user.varlink=listen
|
||||
XAttrEntryPoint=user.userdb.uid={{DYNAMIC_UID_MIN}}-{{DYNAMIC_UID_MAX}},{{CONTAINER_UID_BASE_MIN}}-{{CONTAINER_UID_BASE_MAX+65535}}
|
||||
XAttrEntryPoint=user.userdb.gid={{DYNAMIC_UID_MIN}}-{{DYNAMIC_UID_MAX}},{{CONTAINER_UID_BASE_MIN}}-{{CONTAINER_UID_BASE_MAX+65535}}
|
||||
XAttrEntryPoint=user.userdb.username=ns-*
|
||||
XAttrEntryPoint=user.userdb.groupname=ns-*
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target
|
||||
Reference in New Issue
Block a user