mirror of
https://github.com/systemd/systemd
synced 2025-09-20 12:24:44 +02:00
Compare commits
No commits in common. "bdd8728c91be3a344d879157ba49738e75ba4356" and "b6c8f0ec9198c872659b167f6b1ae95d104a9ffb" have entirely different histories.
bdd8728c91
...
b6c8f0ec91
@ -52,12 +52,6 @@ predicate potentiallyDangerousFunction(Function f, string message) {
|
|||||||
) or (
|
) or (
|
||||||
f.getQualifiedName() = "basename" and
|
f.getQualifiedName() = "basename" and
|
||||||
message = "Call basename() is icky. Use path_extract_filename() instead."
|
message = "Call basename() is icky. Use path_extract_filename() instead."
|
||||||
) or (
|
|
||||||
f.getQualifiedName() = "setmntent" and
|
|
||||||
message = "Libmount parser is used instead, specifically libmount_parse_fstab()."
|
|
||||||
) or (
|
|
||||||
f.getQualifiedName() = "getmntent" and
|
|
||||||
message = "Libmount parser is used instead, specifically mnt_table_next_fs()."
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
TODO
5
TODO
@ -522,6 +522,11 @@ Features:
|
|||||||
|
|
||||||
* port copy.c over to use LabelOps for all labelling.
|
* port copy.c over to use LabelOps for all labelling.
|
||||||
|
|
||||||
|
* port remaining getmntent() users over to libmount. There are subtle
|
||||||
|
differences in the parsers (see #25371 for example), and it hence makes sense
|
||||||
|
if we stick to one set of parsers on this, not mix both. Specifically:
|
||||||
|
systemd-fstab-generator, cryptsetup, remount-fs.
|
||||||
|
|
||||||
* get rid of compat with libidn.so.11 (retain only for libidn.so.12)
|
* get rid of compat with libidn.so.11 (retain only for libidn.so.12)
|
||||||
|
|
||||||
* get rid of compat with libbpf.so.0 (retainly only for libbpf.so.1)
|
* get rid of compat with libbpf.so.0 (retainly only for libbpf.so.1)
|
||||||
|
@ -380,9 +380,6 @@ All tools:
|
|||||||
default keymap directories (/usr/share/keymaps/, /usr/share/kbd/keymaps/, and
|
default keymap directories (/usr/share/keymaps/, /usr/share/kbd/keymaps/, and
|
||||||
/usr/lib/kbd/keymaps/) will be used.
|
/usr/lib/kbd/keymaps/) will be used.
|
||||||
|
|
||||||
* `$SYSTEMD_XKB_DIRECTORY=` — The directory must be absolute and normalized.
|
|
||||||
If unset, the default XKB directory (/usr/share/X11/xkb) will be used.
|
|
||||||
|
|
||||||
`systemd-resolved`:
|
`systemd-resolved`:
|
||||||
|
|
||||||
* `$SYSTEMD_RESOLVED_SYNTHESIZE_HOSTNAME` — if set to "0", `systemd-resolved`
|
* `$SYSTEMD_RESOLVED_SYNTHESIZE_HOSTNAME` — if set to "0", `systemd-resolved`
|
||||||
|
@ -3915,13 +3915,6 @@ StandardInputData=V2XigLJyZSBubyBzdHJhbmdlcnMgdG8gbG92ZQpZb3Uga25vdyB0aGUgcnVsZX
|
|||||||
<varname>LoadCredential=</varname> and <varname>LoadCredentialEncrypted=</varname> take priority over
|
<varname>LoadCredential=</varname> and <varname>LoadCredentialEncrypted=</varname> take priority over
|
||||||
credentials found by <varname>ImportCredential=</varname>.</para>
|
credentials found by <varname>ImportCredential=</varname>.</para>
|
||||||
|
|
||||||
<para>Note that if decryption or authentication of a credential picked up as result of
|
|
||||||
<varname>ImportCredential=</varname> fails it will be skipped gracefully (a warning is generated, but
|
|
||||||
the credential will not be made available to the invoked service). This is different for those
|
|
||||||
configured via
|
|
||||||
<varname>SetCredentialEncrypted=</varname>/<varname>LoadCredentialEncrypted=</varname>, where failed
|
|
||||||
decryption/authentication will result in service failure.</para>
|
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
<xi:include href="version-info.xml" xpointer="v254"/></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
@ -789,20 +789,14 @@ int chase_and_open(
|
|||||||
|
|
||||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
|
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
|
||||||
|
|
||||||
XOpenFlags xopen_flags = 0;
|
|
||||||
if (FLAGS_SET(chase_flags, CHASE_MUST_BE_DIRECTORY))
|
|
||||||
open_flags |= O_DIRECTORY;
|
|
||||||
if (FLAGS_SET(chase_flags, CHASE_MUST_BE_REGULAR))
|
|
||||||
xopen_flags |= XO_REGULAR;
|
|
||||||
|
|
||||||
if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0)
|
if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0)
|
||||||
/* Shortcut this call if none of the special features of this call are requested */
|
/* Shortcut this call if none of the special features of this call are requested */
|
||||||
return xopenat_full(AT_FDCWD, path,
|
return xopenat_full(AT_FDCWD, path,
|
||||||
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
|
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
|
||||||
xopen_flags,
|
/* xopen_flags = */ 0,
|
||||||
MODE_INVALID);
|
MODE_INVALID);
|
||||||
|
|
||||||
r = chase(path, root, (CHASE_PARENT|chase_flags)&~CHASE_MUST_BE_REGULAR, &p, &path_fd);
|
r = chase(path, root, CHASE_PARENT|chase_flags, &p, &path_fd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
assert(path_fd >= 0);
|
assert(path_fd >= 0);
|
||||||
@ -814,7 +808,7 @@ int chase_and_open(
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = xopenat_full(path_fd, strempty(fname), open_flags|O_NOFOLLOW, xopen_flags, MODE_INVALID);
|
r = xopenat_full(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags = */ 0, MODE_INVALID);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -830,7 +824,7 @@ int chase_and_opendir(const char *path, const char *root, ChaseFlags chase_flags
|
|||||||
DIR *d;
|
DIR *d;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR)));
|
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
|
||||||
assert(ret_dir);
|
assert(ret_dir);
|
||||||
|
|
||||||
if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) {
|
if (empty_or_root(root) && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) {
|
||||||
@ -843,12 +837,12 @@ int chase_and_opendir(const char *path, const char *root, ChaseFlags chase_flags
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = chase(path, root, chase_flags|CHASE_MUST_BE_DIRECTORY, ret_path ? &p : NULL, &path_fd);
|
r = chase(path, root, chase_flags, ret_path ? &p : NULL, &path_fd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
assert(path_fd >= 0);
|
assert(path_fd >= 0);
|
||||||
|
|
||||||
d = xopendirat(path_fd, /* path= */ NULL, /* flags= */ 0);
|
d = xopendirat(path_fd, ".", O_NOFOLLOW);
|
||||||
if (!d)
|
if (!d)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
@ -928,7 +922,7 @@ int chase_and_fopen_unlocked(
|
|||||||
int mode_flags, r;
|
int mode_flags, r;
|
||||||
|
|
||||||
assert(path);
|
assert(path);
|
||||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT|CHASE_MUST_BE_DIRECTORY)));
|
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_PARENT)));
|
||||||
assert(open_flags);
|
assert(open_flags);
|
||||||
assert(ret_file);
|
assert(ret_file);
|
||||||
|
|
||||||
@ -1000,20 +994,14 @@ int chase_and_openat(
|
|||||||
|
|
||||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
|
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
|
||||||
|
|
||||||
XOpenFlags xopen_flags = 0;
|
|
||||||
if (FLAGS_SET(chase_flags, CHASE_MUST_BE_DIRECTORY))
|
|
||||||
open_flags |= O_DIRECTORY;
|
|
||||||
if (FLAGS_SET(chase_flags, CHASE_MUST_BE_REGULAR))
|
|
||||||
xopen_flags |= XO_REGULAR;
|
|
||||||
|
|
||||||
if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0)
|
if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0)
|
||||||
/* Shortcut this call if none of the special features of this call are requested */
|
/* Shortcut this call if none of the special features of this call are requested */
|
||||||
return xopenat_full(dir_fd, path,
|
return xopenat_full(dir_fd, path,
|
||||||
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
|
open_flags | (FLAGS_SET(chase_flags, CHASE_NOFOLLOW) ? O_NOFOLLOW : 0),
|
||||||
xopen_flags,
|
/* xopen_flags = */ 0,
|
||||||
MODE_INVALID);
|
MODE_INVALID);
|
||||||
|
|
||||||
r = chaseat(dir_fd, path, (chase_flags|CHASE_PARENT)&~CHASE_MUST_BE_REGULAR, &p, &path_fd);
|
r = chaseat(dir_fd, path, chase_flags|CHASE_PARENT, &p, &path_fd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1023,12 +1011,7 @@ int chase_and_openat(
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = xopenat_full(
|
r = xopenat_full(path_fd, strempty(fname), open_flags|O_NOFOLLOW, /* xopen_flags= */ 0, MODE_INVALID);
|
||||||
path_fd,
|
|
||||||
strempty(fname),
|
|
||||||
open_flags|O_NOFOLLOW,
|
|
||||||
xopen_flags,
|
|
||||||
MODE_INVALID);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1044,7 +1027,7 @@ int chase_and_opendirat(int dir_fd, const char *path, ChaseFlags chase_flags, ch
|
|||||||
DIR *d;
|
DIR *d;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP|CHASE_MUST_BE_REGULAR)));
|
assert(!(chase_flags & (CHASE_NONEXISTENT|CHASE_STEP)));
|
||||||
assert(ret_dir);
|
assert(ret_dir);
|
||||||
|
|
||||||
if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) {
|
if (dir_fd == AT_FDCWD && !ret_path && (chase_flags & CHASE_NO_SHORTCUT_MASK) == 0) {
|
||||||
@ -1062,7 +1045,7 @@ int chase_and_opendirat(int dir_fd, const char *path, ChaseFlags chase_flags, ch
|
|||||||
return r;
|
return r;
|
||||||
assert(path_fd >= 0);
|
assert(path_fd >= 0);
|
||||||
|
|
||||||
d = xopendirat(path_fd, /* path= */ NULL, /* flags= */ 0);
|
d = xopendirat(path_fd, ".", O_NOFOLLOW);
|
||||||
if (!d)
|
if (!d)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ int chattr_full(
|
|||||||
* drivers, where the ioctl might have different effects. Notably, DRM is using the same
|
* drivers, where the ioctl might have different effects. Notably, DRM is using the same
|
||||||
* ioctl() number. */
|
* ioctl() number. */
|
||||||
|
|
||||||
if (!inode_type_can_chattr(st.st_mode))
|
if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
|
||||||
if (mask == 0 && !ret_previous && !ret_final)
|
if (mask == 0 && !ret_previous && !ret_final)
|
||||||
@ -140,7 +140,7 @@ int read_attr_fd(int fd, unsigned *ret) {
|
|||||||
if (fstat(fd, &st) < 0)
|
if (fstat(fd, &st) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (!inode_type_can_chattr(st.st_mode))
|
if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
|
||||||
return -ENOTTY;
|
return -ENOTTY;
|
||||||
|
|
||||||
_cleanup_close_ int fd_close = -EBADF;
|
_cleanup_close_ int fd_close = -EBADF;
|
||||||
@ -248,7 +248,3 @@ int set_proj_id_recursive(int fd, uint32_t proj_id) {
|
|||||||
set_proj_id_cb,
|
set_proj_id_cb,
|
||||||
UINT32_TO_PTR(proj_id));
|
UINT32_TO_PTR(proj_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inode_type_can_chattr(mode_t mode) {
|
|
||||||
return IN_SET(mode & S_IFMT, S_IFREG, S_IFDIR);
|
|
||||||
}
|
|
||||||
|
@ -63,5 +63,3 @@ int set_proj_id_recursive(int fd, uint32_t proj_id);
|
|||||||
static inline int chattr_secret(int fd, ChattrApplyFlags flags) {
|
static inline int chattr_secret(int fd, ChattrApplyFlags flags) {
|
||||||
return chattr_full(fd, NULL, CHATTR_SECRET_FLAGS, CHATTR_SECRET_FLAGS, NULL, NULL, flags|CHATTR_FALLBACK_BITWISE);
|
return chattr_full(fd, NULL, CHATTR_SECRET_FLAGS, CHATTR_SECRET_FLAGS, NULL, NULL, flags|CHATTR_FALLBACK_BITWISE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool inode_type_can_chattr(mode_t mode);
|
|
||||||
|
@ -928,22 +928,17 @@ int get_proc_field(const char *path, const char *key, char **ret) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DIR* xopendirat(int dir_fd, const char *path, int flags) {
|
DIR* xopendirat(int dir_fd, const char *name, int flags) {
|
||||||
_cleanup_close_ int fd = -EBADF;
|
_cleanup_close_ int fd = -EBADF;
|
||||||
|
|
||||||
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
assert(dir_fd >= 0 || dir_fd == AT_FDCWD);
|
||||||
|
assert(name);
|
||||||
assert(!(flags & (O_CREAT|O_TMPFILE)));
|
assert(!(flags & (O_CREAT|O_TMPFILE)));
|
||||||
|
|
||||||
if ((dir_fd == AT_FDCWD || path_is_absolute(path)) &&
|
if (dir_fd == AT_FDCWD && flags == 0)
|
||||||
(flags &~ O_DIRECTORY) == 0)
|
return opendir(name);
|
||||||
return opendir(path);
|
|
||||||
|
|
||||||
if (isempty(path)) {
|
fd = openat(dir_fd, name, O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags);
|
||||||
path = ".";
|
|
||||||
flags |= O_NOFOLLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
fd = openat(dir_fd, path, O_NONBLOCK|O_DIRECTORY|O_CLOEXEC|flags);
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -92,7 +92,7 @@ int script_get_shebang_interpreter(const char *path, char **ret);
|
|||||||
|
|
||||||
int get_proc_field(const char *path, const char *key, char **ret);
|
int get_proc_field(const char *path, const char *key, char **ret);
|
||||||
|
|
||||||
DIR* xopendirat(int dir_fd, const char *path, int flags);
|
DIR* xopendirat(int dir_fd, const char *name, int flags);
|
||||||
|
|
||||||
typedef enum XfopenFlags {
|
typedef enum XfopenFlags {
|
||||||
XFOPEN_UNLOCKED = 1 << 0, /* call __fsetlocking(FSETLOCKING_BYCALLER) after opened */
|
XFOPEN_UNLOCKED = 1 << 0, /* call __fsetlocking(FSETLOCKING_BYCALLER) after opened */
|
||||||
|
@ -463,8 +463,7 @@ static int maybe_decrypt_and_write_credential(
|
|||||||
struct load_cred_args *args,
|
struct load_cred_args *args,
|
||||||
const char *id,
|
const char *id,
|
||||||
const char *data,
|
const char *data,
|
||||||
size_t size,
|
size_t size) {
|
||||||
bool graceful) {
|
|
||||||
|
|
||||||
_cleanup_(iovec_done_erase) struct iovec plaintext = {};
|
_cleanup_(iovec_done_erase) struct iovec plaintext = {};
|
||||||
size_t add;
|
size_t add;
|
||||||
@ -518,14 +517,8 @@ static int maybe_decrypt_and_write_credential(
|
|||||||
default:
|
default:
|
||||||
assert_not_reached();
|
assert_not_reached();
|
||||||
}
|
}
|
||||||
if (r < 0) {
|
if (r < 0)
|
||||||
if (graceful) {
|
|
||||||
log_warning_errno(r, "Unable to decrypt credential '%s', skipping.", id);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
|
||||||
|
|
||||||
data = plaintext.iov_base;
|
data = plaintext.iov_base;
|
||||||
size = plaintext.iov_len;
|
size = plaintext.iov_len;
|
||||||
@ -614,7 +607,7 @@ static int load_credential_glob(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to read credential '%s': %m", *p);
|
return log_debug_errno(r, "Failed to read credential '%s': %m", *p);
|
||||||
|
|
||||||
r = maybe_decrypt_and_write_credential(args, fn, data, size, /* graceful= */ true);
|
r = maybe_decrypt_and_write_credential(args, fn, data, size);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -739,7 +732,7 @@ static int load_credential(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to read credential '%s': %m", path);
|
return log_debug_errno(r, "Failed to read credential '%s': %m", path);
|
||||||
|
|
||||||
return maybe_decrypt_and_write_credential(args, id, data, size, /* graceful= */ true);
|
return maybe_decrypt_and_write_credential(args, id, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int load_cred_recurse_dir_cb(
|
static int load_cred_recurse_dir_cb(
|
||||||
@ -876,8 +869,7 @@ static int acquire_credentials(
|
|||||||
|
|
||||||
args.encrypted = false;
|
args.encrypted = false;
|
||||||
|
|
||||||
r = load_credential_glob(
|
r = load_credential_glob(&args,
|
||||||
&args,
|
|
||||||
ic,
|
ic,
|
||||||
search_path,
|
search_path,
|
||||||
READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER);
|
READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER);
|
||||||
@ -892,8 +884,7 @@ static int acquire_credentials(
|
|||||||
|
|
||||||
args.encrypted = true;
|
args.encrypted = true;
|
||||||
|
|
||||||
r = load_credential_glob(
|
r = load_credential_glob(&args,
|
||||||
&args,
|
|
||||||
ic,
|
ic,
|
||||||
search_path,
|
search_path,
|
||||||
READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER|READ_FULL_FILE_UNBASE64);
|
READ_FULL_FILE_SECURE|READ_FULL_FILE_FAIL_WHEN_LARGER|READ_FULL_FILE_UNBASE64);
|
||||||
@ -914,7 +905,7 @@ static int acquire_credentials(
|
|||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
return log_debug_errno(errno, "Failed to test if credential %s exists: %m", sc->id);
|
return log_debug_errno(errno, "Failed to test if credential %s exists: %m", sc->id);
|
||||||
|
|
||||||
r = maybe_decrypt_and_write_credential(&args, sc->id, sc->data, sc->size, /* graceful= */ false);
|
r = maybe_decrypt_and_write_credential(&args, sc->id, sc->data, sc->size);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -1411,7 +1411,7 @@ static int vl_method_decrypt(sd_varlink *link, sd_json_variant *parameters, sd_v
|
|||||||
|
|
||||||
if (r == -EBADMSG)
|
if (r == -EBADMSG)
|
||||||
return sd_varlink_error(link, "io.systemd.Credentials.BadFormat", NULL);
|
return sd_varlink_error(link, "io.systemd.Credentials.BadFormat", NULL);
|
||||||
if (r == -EDESTADDRREQ)
|
if (r == -EREMOTE)
|
||||||
return sd_varlink_error(link, "io.systemd.Credentials.NameMismatch", NULL);
|
return sd_varlink_error(link, "io.systemd.Credentials.NameMismatch", NULL);
|
||||||
if (r == -ESTALE)
|
if (r == -ESTALE)
|
||||||
return sd_varlink_error(link, "io.systemd.Credentials.TimeMismatch", NULL);
|
return sd_varlink_error(link, "io.systemd.Credentials.TimeMismatch", NULL);
|
||||||
@ -1419,16 +1419,6 @@ static int vl_method_decrypt(sd_varlink *link, sd_json_variant *parameters, sd_v
|
|||||||
return sd_varlink_error(link, "io.systemd.Credentials.NoSuchUser", NULL);
|
return sd_varlink_error(link, "io.systemd.Credentials.NoSuchUser", NULL);
|
||||||
if (r == -EMEDIUMTYPE)
|
if (r == -EMEDIUMTYPE)
|
||||||
return sd_varlink_error(link, "io.systemd.Credentials.BadScope", NULL);
|
return sd_varlink_error(link, "io.systemd.Credentials.BadScope", NULL);
|
||||||
if (r == -EHOSTDOWN)
|
|
||||||
return sd_varlink_error(link, "io.systemd.Credentials.CantFindPCRSignature", NULL);
|
|
||||||
if (r == -EHWPOISON)
|
|
||||||
return sd_varlink_error(link, "io.systemd.Credentials.NullKeyNotAllowed", NULL);
|
|
||||||
if (r == -EREMOTE)
|
|
||||||
return sd_varlink_error(link, "io.systemd.Credentials.KeyBelongsToOtherTPM", NULL);
|
|
||||||
if (r == -ENOLCK)
|
|
||||||
return sd_varlink_error(link, "io.systemd.Credentials.TPMInDictionaryLockout", NULL);
|
|
||||||
if (IN_SET(r, -EREMCHG, -ENOANO, -EUCLEAN, -EPERM))
|
|
||||||
return sd_varlink_error(link, "io.systemd.Credentials.UnexpectedPCRState", NULL);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1443,17 +1433,25 @@ static int vl_method_decrypt(sd_varlink *link, sd_json_variant *parameters, sd_v
|
|||||||
return sd_varlink_reply(link, reply);
|
return sd_varlink_reply(link, reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vl_server(void) {
|
static int run(int argc, char *argv[]) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
log_setup();
|
||||||
|
|
||||||
|
r = parse_argv(argc, argv);
|
||||||
|
if (r <= 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (arg_varlink) {
|
||||||
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *varlink_server = NULL;
|
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *varlink_server = NULL;
|
||||||
_cleanup_hashmap_free_ Hashmap *polkit_registry = NULL;
|
_cleanup_hashmap_free_ Hashmap *polkit_registry = NULL;
|
||||||
int r;
|
|
||||||
|
|
||||||
/* Invocation as Varlink service */
|
/* Invocation as Varlink service */
|
||||||
|
|
||||||
r = varlink_server_new(
|
r = varlink_server_new(
|
||||||
&varlink_server,
|
&varlink_server,
|
||||||
SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA|SD_VARLINK_SERVER_INPUT_SENSITIVE,
|
SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA|SD_VARLINK_SERVER_INPUT_SENSITIVE,
|
||||||
&polkit_registry);
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to allocate Varlink server: %m");
|
return log_error_errno(r, "Failed to allocate Varlink server: %m");
|
||||||
|
|
||||||
@ -1468,6 +1466,8 @@ static int vl_server(void) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to bind Varlink methods: %m");
|
return log_error_errno(r, "Failed to bind Varlink methods: %m");
|
||||||
|
|
||||||
|
sd_varlink_server_set_userdata(varlink_server, &polkit_registry);
|
||||||
|
|
||||||
r = sd_varlink_server_loop_auto(varlink_server);
|
r = sd_varlink_server_loop_auto(varlink_server);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to run Varlink event loop: %m");
|
return log_error_errno(r, "Failed to run Varlink event loop: %m");
|
||||||
@ -1475,18 +1475,6 @@ static int vl_server(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int run(int argc, char *argv[]) {
|
|
||||||
int r;
|
|
||||||
|
|
||||||
log_setup();
|
|
||||||
|
|
||||||
r = parse_argv(argc, argv);
|
|
||||||
if (r <= 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (arg_varlink)
|
|
||||||
return vl_server();
|
|
||||||
|
|
||||||
return creds_main(argc, argv);
|
return creds_main(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <mntent.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -32,7 +33,6 @@
|
|||||||
#include "hexdecoct.h"
|
#include "hexdecoct.h"
|
||||||
#include "json-util.h"
|
#include "json-util.h"
|
||||||
#include "libfido2-util.h"
|
#include "libfido2-util.h"
|
||||||
#include "libmount-util.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
@ -733,36 +733,25 @@ static char* disk_description(const char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *disk_mount_point(const char *label) {
|
static char *disk_mount_point(const char *label) {
|
||||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
|
||||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
|
||||||
_cleanup_free_ char *device = NULL;
|
_cleanup_free_ char *device = NULL;
|
||||||
int r;
|
_cleanup_endmntent_ FILE *f = NULL;
|
||||||
|
struct mntent *m;
|
||||||
|
|
||||||
/* Yeah, we don't support native systemd unit files here for now */
|
/* Yeah, we don't support native systemd unit files here for now */
|
||||||
|
|
||||||
assert(label);
|
|
||||||
|
|
||||||
device = strjoin("/dev/mapper/", label);
|
device = strjoin("/dev/mapper/", label);
|
||||||
if (!device)
|
if (!device)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
r = libmount_parse_fstab(&table, &iter);
|
f = setmntent(fstab_path(), "re");
|
||||||
if (r < 0)
|
if (!f)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (;;) {
|
while ((m = getmntent(f)))
|
||||||
struct libmnt_fs *fs;
|
if (path_equal(m->mnt_fsname, device))
|
||||||
|
return strdup(m->mnt_dir);
|
||||||
|
|
||||||
r = mnt_table_next_fs(table, iter, &fs);
|
|
||||||
if (r != 0)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (path_equal(mnt_fs_get_source(fs), device)) {
|
|
||||||
const char *target = mnt_fs_get_target(fs);
|
|
||||||
if (target)
|
|
||||||
return strdup(target);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *friendly_disk_name(const char *src, const char *vol) {
|
static char *friendly_disk_name(const char *src, const char *vol) {
|
||||||
|
@ -19,7 +19,6 @@ executables += [
|
|||||||
'sources' : systemd_cryptsetup_sources,
|
'sources' : systemd_cryptsetup_sources,
|
||||||
'dependencies' : [
|
'dependencies' : [
|
||||||
libcryptsetup,
|
libcryptsetup,
|
||||||
libmount,
|
|
||||||
libopenssl,
|
libopenssl,
|
||||||
libp11kit_cflags,
|
libp11kit_cflags,
|
||||||
],
|
],
|
||||||
|
@ -24,10 +24,10 @@
|
|||||||
#include "generator.h"
|
#include "generator.h"
|
||||||
#include "in-addr-util.h"
|
#include "in-addr-util.h"
|
||||||
#include "initrd-util.h"
|
#include "initrd-util.h"
|
||||||
#include "libmount-util.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
#include "mount-setup.h"
|
#include "mount-setup.h"
|
||||||
|
#include "mount-util.h"
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
@ -1025,9 +1025,9 @@ static int parse_fstab_one(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int parse_fstab(bool prefix_sysroot) {
|
static int parse_fstab(bool prefix_sysroot) {
|
||||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
_cleanup_endmntent_ FILE *f = NULL;
|
||||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
|
||||||
const char *fstab;
|
const char *fstab;
|
||||||
|
struct mntent *me;
|
||||||
int r, ret = 0;
|
int r, ret = 0;
|
||||||
|
|
||||||
if (prefix_sysroot)
|
if (prefix_sysroot)
|
||||||
@ -1039,31 +1039,27 @@ static int parse_fstab(bool prefix_sysroot) {
|
|||||||
|
|
||||||
log_debug("Parsing %s...", fstab);
|
log_debug("Parsing %s...", fstab);
|
||||||
|
|
||||||
r = libmount_parse_full(fstab, /* source = */ NULL, &table, &iter);
|
f = setmntent(fstab, "re");
|
||||||
if (r == -ENOENT)
|
if (!f) {
|
||||||
|
if (errno == ENOENT)
|
||||||
return 0;
|
return 0;
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to parse '%s': %m", fstab);
|
|
||||||
|
|
||||||
for (;;) {
|
return log_error_errno(errno, "Failed to open %s: %m", fstab);
|
||||||
struct libmnt_fs *fs;
|
}
|
||||||
|
|
||||||
r = mnt_table_next_fs(table, iter, &fs);
|
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to get next entry from '%s': %m", fstab);
|
|
||||||
if (r > 0) /* EOF */
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
|
while ((me = getmntent(f))) {
|
||||||
r = parse_fstab_one(fstab,
|
r = parse_fstab_one(fstab,
|
||||||
mnt_fs_get_source(fs), mnt_fs_get_target(fs),
|
me->mnt_fsname, me->mnt_dir, me->mnt_type, me->mnt_opts, me->mnt_passno,
|
||||||
mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
|
|
||||||
prefix_sysroot,
|
prefix_sysroot,
|
||||||
/* accept_root = */ false,
|
/* accept_root = */ false,
|
||||||
/* use_swap_enabled = */ true);
|
/* use_swap_enabled = */ true);
|
||||||
|
if (r < 0 && ret >= 0)
|
||||||
|
ret = r;
|
||||||
if (arg_sysroot_check && r > 0)
|
if (arg_sysroot_check && r > 0)
|
||||||
return true; /* We found a mount or swap that would be started… */
|
return true; /* We found a mount or swap that would be started… */
|
||||||
RET_GATHER(ret, r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mount_source_is_nfsroot(const char *what) {
|
static int mount_source_is_nfsroot(const char *what) {
|
||||||
@ -1418,15 +1414,15 @@ static int add_mounts_from_cmdline(void) {
|
|||||||
|
|
||||||
static int add_mounts_from_creds(bool prefix_sysroot) {
|
static int add_mounts_from_creds(bool prefix_sysroot) {
|
||||||
_cleanup_free_ void *b = NULL;
|
_cleanup_free_ void *b = NULL;
|
||||||
|
struct mntent *me;
|
||||||
size_t bs;
|
size_t bs;
|
||||||
const char *cred;
|
int r;
|
||||||
int r, ret = 0;
|
|
||||||
|
|
||||||
assert(in_initrd() || !prefix_sysroot);
|
assert(in_initrd() || !prefix_sysroot);
|
||||||
|
|
||||||
cred = in_initrd() && !prefix_sysroot ? "fstab.extra.initrd" : "fstab.extra";
|
r = read_credential_with_decryption(
|
||||||
|
in_initrd() && !prefix_sysroot ? "fstab.extra.initrd" : "fstab.extra",
|
||||||
r = read_credential_with_decryption(cred, &b, &bs);
|
&b, &bs);
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -1435,29 +1431,20 @@ static int add_mounts_from_creds(bool prefix_sysroot) {
|
|||||||
if (!f)
|
if (!f)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
r = 0;
|
||||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
|
||||||
|
|
||||||
r = libmount_parse_full(cred, f, &table, &iter);
|
while ((me = getmntent(f)))
|
||||||
if (r < 0)
|
RET_GATHER(r, parse_fstab_one("/run/credentials",
|
||||||
return log_error_errno(r, "Failed to parse credential '%s' (as fstab): %m", cred);
|
me->mnt_fsname,
|
||||||
|
me->mnt_dir,
|
||||||
for (;;) {
|
me->mnt_type,
|
||||||
struct libmnt_fs *fs;
|
me->mnt_opts,
|
||||||
|
me->mnt_passno,
|
||||||
r = mnt_table_next_fs(table, iter, &fs);
|
/* prefix_sysroot = */ prefix_sysroot,
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to get next fstab entry from credential '%s': %m", cred);
|
|
||||||
if (r > 0) /* EOF */
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
RET_GATHER(ret, parse_fstab_one("/run/credentials",
|
|
||||||
mnt_fs_get_source(fs), mnt_fs_get_target(fs),
|
|
||||||
mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
|
|
||||||
prefix_sysroot,
|
|
||||||
/* accept_root = */ true,
|
/* accept_root = */ true,
|
||||||
/* use_swap_enabled = */ true));
|
/* use_swap_enabled = */ true));
|
||||||
}
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
|
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
|
||||||
|
@ -4,7 +4,6 @@ executables += [
|
|||||||
generator_template + {
|
generator_template + {
|
||||||
'name' : 'systemd-fstab-generator',
|
'name' : 'systemd-fstab-generator',
|
||||||
'sources' : files('fstab-generator.c'),
|
'sources' : files('fstab-generator.c'),
|
||||||
'dependencies' : libmount,
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "format-util.h"
|
#include "format-util.h"
|
||||||
#include "fs-util.h"
|
#include "fs-util.h"
|
||||||
#include "import-common.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "pretty-print.h"
|
#include "pretty-print.h"
|
||||||
#include "ratelimit.h"
|
#include "ratelimit.h"
|
||||||
@ -21,6 +20,8 @@
|
|||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
#include "tmpfile-util.h"
|
#include "tmpfile-util.h"
|
||||||
|
|
||||||
|
#define COPY_BUFFER_SIZE (16*1024)
|
||||||
|
|
||||||
typedef struct RawExport {
|
typedef struct RawExport {
|
||||||
sd_event *event;
|
sd_event *event;
|
||||||
|
|
||||||
@ -160,7 +161,7 @@ static int raw_export_process(RawExport *e) {
|
|||||||
|
|
||||||
if (!e->tried_sendfile && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) {
|
if (!e->tried_sendfile && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) {
|
||||||
|
|
||||||
l = sendfile(e->output_fd, e->input_fd, NULL, IMPORT_BUFFER_SIZE);
|
l = sendfile(e->output_fd, e->input_fd, NULL, COPY_BUFFER_SIZE);
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
if (errno == EAGAIN)
|
if (errno == EAGAIN)
|
||||||
return 0;
|
return 0;
|
||||||
@ -180,7 +181,7 @@ static int raw_export_process(RawExport *e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (e->buffer_size <= 0) {
|
while (e->buffer_size <= 0) {
|
||||||
uint8_t input[IMPORT_BUFFER_SIZE];
|
uint8_t input[COPY_BUFFER_SIZE];
|
||||||
|
|
||||||
if (e->eof) {
|
if (e->eof) {
|
||||||
r = 0;
|
r = 0;
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include "format-util.h"
|
#include "format-util.h"
|
||||||
#include "import-common.h"
|
#include "import-common.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "pidref.h"
|
|
||||||
#include "pretty-print.h"
|
#include "pretty-print.h"
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
#include "ratelimit.h"
|
#include "ratelimit.h"
|
||||||
@ -21,6 +20,8 @@
|
|||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
#include "tmpfile-util.h"
|
#include "tmpfile-util.h"
|
||||||
|
|
||||||
|
#define COPY_BUFFER_SIZE (16*1024)
|
||||||
|
|
||||||
typedef struct TarExport {
|
typedef struct TarExport {
|
||||||
sd_event *event;
|
sd_event *event;
|
||||||
|
|
||||||
@ -44,7 +45,7 @@ typedef struct TarExport {
|
|||||||
uint64_t written_compressed;
|
uint64_t written_compressed;
|
||||||
uint64_t written_uncompressed;
|
uint64_t written_uncompressed;
|
||||||
|
|
||||||
PidRef tar_pid;
|
pid_t tar_pid;
|
||||||
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
uint64_t quota_referenced;
|
uint64_t quota_referenced;
|
||||||
@ -62,7 +63,8 @@ TarExport *tar_export_unref(TarExport *e) {
|
|||||||
|
|
||||||
sd_event_source_unref(e->output_event_source);
|
sd_event_source_unref(e->output_event_source);
|
||||||
|
|
||||||
pidref_done_sigkill_wait(&e->tar_pid);
|
if (e->tar_pid > 1)
|
||||||
|
sigkill_wait(e->tar_pid);
|
||||||
|
|
||||||
if (e->temp_path) {
|
if (e->temp_path) {
|
||||||
(void) btrfs_subvol_remove(e->temp_path, BTRFS_REMOVE_QUOTA);
|
(void) btrfs_subvol_remove(e->temp_path, BTRFS_REMOVE_QUOTA);
|
||||||
@ -103,7 +105,6 @@ int tar_export_new(
|
|||||||
.quota_referenced = UINT64_MAX,
|
.quota_referenced = UINT64_MAX,
|
||||||
.last_percent = UINT_MAX,
|
.last_percent = UINT_MAX,
|
||||||
.progress_ratelimit = { 100 * USEC_PER_MSEC, 1 },
|
.progress_ratelimit = { 100 * USEC_PER_MSEC, 1 },
|
||||||
.tar_pid = PIDREF_NULL,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
@ -159,13 +160,10 @@ static int tar_export_finish(TarExport *e) {
|
|||||||
assert(e);
|
assert(e);
|
||||||
assert(e->tar_fd >= 0);
|
assert(e->tar_fd >= 0);
|
||||||
|
|
||||||
if (pidref_is_set(&e->tar_pid)) {
|
if (e->tar_pid > 0) {
|
||||||
r = pidref_wait_for_terminate_and_check("tar", &e->tar_pid, WAIT_LOG);
|
r = wait_for_terminate_and_check("tar", TAKE_PID(e->tar_pid), WAIT_LOG);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
pidref_done(&e->tar_pid);
|
|
||||||
|
|
||||||
if (r != EXIT_SUCCESS)
|
if (r != EXIT_SUCCESS)
|
||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
}
|
}
|
||||||
@ -183,7 +181,7 @@ static int tar_export_process(TarExport *e) {
|
|||||||
|
|
||||||
if (!e->tried_splice && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) {
|
if (!e->tried_splice && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) {
|
||||||
|
|
||||||
l = splice(e->tar_fd, NULL, e->output_fd, NULL, IMPORT_BUFFER_SIZE, 0);
|
l = splice(e->tar_fd, NULL, e->output_fd, NULL, COPY_BUFFER_SIZE, 0);
|
||||||
if (l < 0) {
|
if (l < 0) {
|
||||||
if (errno == EAGAIN)
|
if (errno == EAGAIN)
|
||||||
return 0;
|
return 0;
|
||||||
@ -203,7 +201,7 @@ static int tar_export_process(TarExport *e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (e->buffer_size <= 0) {
|
while (e->buffer_size <= 0) {
|
||||||
uint8_t input[IMPORT_BUFFER_SIZE];
|
uint8_t input[COPY_BUFFER_SIZE];
|
||||||
|
|
||||||
if (e->eof) {
|
if (e->eof) {
|
||||||
r = tar_export_finish(e);
|
r = tar_export_finish(e);
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include "runtime-scope.h"
|
#include "runtime-scope.h"
|
||||||
#include "signal-util.h"
|
#include "signal-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "terminal-util.h"
|
|
||||||
#include "verbs.h"
|
#include "verbs.h"
|
||||||
|
|
||||||
static ImportCompressType arg_compress = IMPORT_COMPRESS_UNKNOWN;
|
static ImportCompressType arg_compress = IMPORT_COMPRESS_UNKNOWN;
|
||||||
@ -94,9 +93,6 @@ static int export_tar(int argc, char *argv[], void *userdata) {
|
|||||||
} else {
|
} else {
|
||||||
_cleanup_free_ char *pretty = NULL;
|
_cleanup_free_ char *pretty = NULL;
|
||||||
|
|
||||||
if (isatty_safe(STDOUT_FILENO))
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EBADF), "Refusing to write archive to TTY.");
|
|
||||||
|
|
||||||
fd = STDOUT_FILENO;
|
fd = STDOUT_FILENO;
|
||||||
|
|
||||||
(void) fd_get_path(fd, &pretty);
|
(void) fd_get_path(fd, &pretty);
|
||||||
|
@ -15,16 +15,15 @@
|
|||||||
#include "import-common.h"
|
#include "import-common.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "os-util.h"
|
#include "os-util.h"
|
||||||
#include "pidref.h"
|
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
#include "selinux-util.h"
|
#include "selinux-util.h"
|
||||||
#include "stat-util.h"
|
#include "stat-util.h"
|
||||||
#include "tmpfile-util.h"
|
#include "tmpfile-util.h"
|
||||||
|
|
||||||
int import_fork_tar_x(const char *path, PidRef *ret) {
|
int import_fork_tar_x(const char *path, pid_t *ret) {
|
||||||
_cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
|
|
||||||
_cleanup_close_pair_ int pipefd[2] = EBADF_PAIR;
|
_cleanup_close_pair_ int pipefd[2] = EBADF_PAIR;
|
||||||
bool use_selinux;
|
bool use_selinux;
|
||||||
|
pid_t pid;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(path);
|
assert(path);
|
||||||
@ -33,16 +32,12 @@ int import_fork_tar_x(const char *path, PidRef *ret) {
|
|||||||
if (pipe2(pipefd, O_CLOEXEC) < 0)
|
if (pipe2(pipefd, O_CLOEXEC) < 0)
|
||||||
return log_error_errno(errno, "Failed to create pipe for tar: %m");
|
return log_error_errno(errno, "Failed to create pipe for tar: %m");
|
||||||
|
|
||||||
(void) fcntl(pipefd[0], F_SETPIPE_SZ, IMPORT_BUFFER_SIZE);
|
|
||||||
|
|
||||||
use_selinux = mac_selinux_use();
|
use_selinux = mac_selinux_use();
|
||||||
|
|
||||||
r = pidref_safe_fork_full(
|
r = safe_fork_full("(tar)",
|
||||||
"(tar)",
|
|
||||||
(int[]) { pipefd[0], -EBADF, STDERR_FILENO },
|
(int[]) { pipefd[0], -EBADF, STDERR_FILENO },
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG,
|
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
|
||||||
&pid);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
@ -89,15 +84,15 @@ int import_fork_tar_x(const char *path, PidRef *ret) {
|
|||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret = TAKE_PIDREF(pid);
|
*ret = pid;
|
||||||
|
|
||||||
return TAKE_FD(pipefd[1]);
|
return TAKE_FD(pipefd[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int import_fork_tar_c(const char *path, PidRef *ret) {
|
int import_fork_tar_c(const char *path, pid_t *ret) {
|
||||||
_cleanup_close_pair_ int pipefd[2] = EBADF_PAIR;
|
_cleanup_close_pair_ int pipefd[2] = EBADF_PAIR;
|
||||||
_cleanup_(pidref_done) PidRef pid = PIDREF_NULL;
|
|
||||||
bool use_selinux;
|
bool use_selinux;
|
||||||
|
pid_t pid;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(path);
|
assert(path);
|
||||||
@ -106,16 +101,12 @@ int import_fork_tar_c(const char *path, PidRef *ret) {
|
|||||||
if (pipe2(pipefd, O_CLOEXEC) < 0)
|
if (pipe2(pipefd, O_CLOEXEC) < 0)
|
||||||
return log_error_errno(errno, "Failed to create pipe for tar: %m");
|
return log_error_errno(errno, "Failed to create pipe for tar: %m");
|
||||||
|
|
||||||
(void) fcntl(pipefd[0], F_SETPIPE_SZ, IMPORT_BUFFER_SIZE);
|
|
||||||
|
|
||||||
use_selinux = mac_selinux_use();
|
use_selinux = mac_selinux_use();
|
||||||
|
|
||||||
r = pidref_safe_fork_full(
|
r = safe_fork_full("(tar)",
|
||||||
"(tar)",
|
|
||||||
(int[]) { -EBADF, pipefd[1], STDERR_FILENO },
|
(int[]) { -EBADF, pipefd[1], STDERR_FILENO },
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG,
|
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
|
||||||
&pid);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
@ -148,7 +139,7 @@ int import_fork_tar_c(const char *path, PidRef *ret) {
|
|||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret = TAKE_PIDREF(pid);
|
*ret = pid;
|
||||||
|
|
||||||
return TAKE_FD(pipefd[0]);
|
return TAKE_FD(pipefd[0]);
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,11 @@ typedef enum ImportFlags {
|
|||||||
_IMPORT_FLAGS_INVALID = -EINVAL,
|
_IMPORT_FLAGS_INVALID = -EINVAL,
|
||||||
} ImportFlags;
|
} ImportFlags;
|
||||||
|
|
||||||
int import_fork_tar_c(const char *path, PidRef *ret);
|
int import_fork_tar_c(const char *path, pid_t *ret);
|
||||||
int import_fork_tar_x(const char *path, PidRef *ret);
|
int import_fork_tar_x(const char *path, pid_t *ret);
|
||||||
|
|
||||||
int import_mangle_os_tree(const char *path);
|
int import_mangle_os_tree(const char *path);
|
||||||
|
|
||||||
bool import_validate_local(const char *name, ImportFlags flags);
|
bool import_validate_local(const char *name, ImportFlags flags);
|
||||||
|
|
||||||
int import_allocate_event_with_signals(sd_event **ret);
|
int import_allocate_event_with_signals(sd_event **ret);
|
||||||
|
|
||||||
#define IMPORT_BUFFER_SIZE (128U*1024U)
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "import-common.h"
|
|
||||||
#include "import-compress.h"
|
#include "import-compress.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "string-table.h"
|
#include "string-table.h"
|
||||||
@ -149,7 +148,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo
|
|||||||
c->xz.avail_in = size;
|
c->xz.avail_in = size;
|
||||||
|
|
||||||
while (c->xz.avail_in > 0) {
|
while (c->xz.avail_in > 0) {
|
||||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
uint8_t buffer[16 * 1024];
|
||||||
lzma_ret lzr;
|
lzma_ret lzr;
|
||||||
|
|
||||||
c->xz.next_out = buffer;
|
c->xz.next_out = buffer;
|
||||||
@ -173,7 +172,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo
|
|||||||
c->gzip.avail_in = size;
|
c->gzip.avail_in = size;
|
||||||
|
|
||||||
while (c->gzip.avail_in > 0) {
|
while (c->gzip.avail_in > 0) {
|
||||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
uint8_t buffer[16 * 1024];
|
||||||
|
|
||||||
c->gzip.next_out = buffer;
|
c->gzip.next_out = buffer;
|
||||||
c->gzip.avail_out = sizeof(buffer);
|
c->gzip.avail_out = sizeof(buffer);
|
||||||
@ -197,7 +196,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo
|
|||||||
c->bzip2.avail_in = size;
|
c->bzip2.avail_in = size;
|
||||||
|
|
||||||
while (c->bzip2.avail_in > 0) {
|
while (c->bzip2.avail_in > 0) {
|
||||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
uint8_t buffer[16 * 1024];
|
||||||
|
|
||||||
c->bzip2.next_out = (char*) buffer;
|
c->bzip2.next_out = (char*) buffer;
|
||||||
c->bzip2.avail_out = sizeof(buffer);
|
c->bzip2.avail_out = sizeof(buffer);
|
||||||
@ -223,7 +222,7 @@ int import_uncompress(ImportCompress *c, const void *data, size_t size, ImportCo
|
|||||||
};
|
};
|
||||||
|
|
||||||
while (input.pos < input.size) {
|
while (input.pos < input.size) {
|
||||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
uint8_t buffer[16 * 1024];
|
||||||
ZSTD_outBuffer output = {
|
ZSTD_outBuffer output = {
|
||||||
.dst = buffer,
|
.dst = buffer,
|
||||||
.size = sizeof(buffer),
|
.size = sizeof(buffer),
|
||||||
@ -321,7 +320,7 @@ static int enlarge_buffer(void **buffer, size_t *buffer_size, size_t *buffer_all
|
|||||||
if (*buffer_allocated > *buffer_size)
|
if (*buffer_allocated > *buffer_size)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
l = MAX(IMPORT_BUFFER_SIZE, (*buffer_size * 2));
|
l = MAX(16*1024U, (*buffer_size * 2));
|
||||||
p = realloc(*buffer, l);
|
p = realloc(*buffer, l);
|
||||||
if (!p)
|
if (!p)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -47,7 +47,7 @@ typedef struct RawImport {
|
|||||||
|
|
||||||
sd_event_source *input_event_source;
|
sd_event_source *input_event_source;
|
||||||
|
|
||||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
uint8_t buffer[16*1024];
|
||||||
size_t buffer_size;
|
size_t buffer_size;
|
||||||
|
|
||||||
uint64_t written_compressed;
|
uint64_t written_compressed;
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "mkdir-label.h"
|
#include "mkdir-label.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "pidref.h"
|
|
||||||
#include "pretty-print.h"
|
#include "pretty-print.h"
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
#include "ratelimit.h"
|
#include "ratelimit.h"
|
||||||
@ -50,7 +49,7 @@ typedef struct TarImport {
|
|||||||
|
|
||||||
sd_event_source *input_event_source;
|
sd_event_source *input_event_source;
|
||||||
|
|
||||||
uint8_t buffer[IMPORT_BUFFER_SIZE];
|
uint8_t buffer[16*1024];
|
||||||
size_t buffer_size;
|
size_t buffer_size;
|
||||||
|
|
||||||
uint64_t written_compressed;
|
uint64_t written_compressed;
|
||||||
@ -58,7 +57,7 @@ typedef struct TarImport {
|
|||||||
|
|
||||||
struct stat input_stat;
|
struct stat input_stat;
|
||||||
|
|
||||||
PidRef tar_pid;
|
pid_t tar_pid;
|
||||||
|
|
||||||
unsigned last_percent;
|
unsigned last_percent;
|
||||||
RateLimit progress_ratelimit;
|
RateLimit progress_ratelimit;
|
||||||
@ -70,7 +69,8 @@ TarImport* tar_import_unref(TarImport *i) {
|
|||||||
|
|
||||||
sd_event_source_unref(i->input_event_source);
|
sd_event_source_unref(i->input_event_source);
|
||||||
|
|
||||||
pidref_done_sigkill_wait(&i->tar_pid);
|
if (i->tar_pid > 1)
|
||||||
|
sigkill_wait(i->tar_pid);
|
||||||
|
|
||||||
rm_rf_subvolume_and_free(i->temp_path);
|
rm_rf_subvolume_and_free(i->temp_path);
|
||||||
|
|
||||||
@ -116,7 +116,6 @@ int tar_import_new(
|
|||||||
.last_percent = UINT_MAX,
|
.last_percent = UINT_MAX,
|
||||||
.image_root = TAKE_PTR(root),
|
.image_root = TAKE_PTR(root),
|
||||||
.progress_ratelimit = { 100 * USEC_PER_MSEC, 1 },
|
.progress_ratelimit = { 100 * USEC_PER_MSEC, 1 },
|
||||||
.tar_pid = PIDREF_NULL,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
@ -175,13 +174,10 @@ static int tar_import_finish(TarImport *i) {
|
|||||||
|
|
||||||
i->tar_fd = safe_close(i->tar_fd);
|
i->tar_fd = safe_close(i->tar_fd);
|
||||||
|
|
||||||
if (pidref_is_set(&i->tar_pid)) {
|
if (i->tar_pid > 0) {
|
||||||
r = pidref_wait_for_terminate_and_check("tar", &i->tar_pid, WAIT_LOG);
|
r = wait_for_terminate_and_check("tar", TAKE_PID(i->tar_pid), WAIT_LOG);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
pidref_done(&i->tar_pid);
|
|
||||||
|
|
||||||
if (r != EXIT_SUCCESS)
|
if (r != EXIT_SUCCESS)
|
||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "mkdir-label.h"
|
#include "mkdir-label.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "pidref.h"
|
|
||||||
#include "process-util.h"
|
#include "process-util.h"
|
||||||
#include "pull-common.h"
|
#include "pull-common.h"
|
||||||
#include "pull-job.h"
|
#include "pull-job.h"
|
||||||
@ -52,7 +51,7 @@ typedef struct TarPull {
|
|||||||
|
|
||||||
char *local;
|
char *local;
|
||||||
|
|
||||||
PidRef tar_pid;
|
pid_t tar_pid;
|
||||||
|
|
||||||
char *final_path;
|
char *final_path;
|
||||||
char *temp_path;
|
char *temp_path;
|
||||||
@ -67,7 +66,8 @@ TarPull* tar_pull_unref(TarPull *i) {
|
|||||||
if (!i)
|
if (!i)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
pidref_done_sigkill_wait(&i->tar_pid);
|
if (i->tar_pid > 1)
|
||||||
|
sigkill_wait(i->tar_pid);
|
||||||
|
|
||||||
pull_job_unref(i->tar_job);
|
pull_job_unref(i->tar_job);
|
||||||
pull_job_unref(i->checksum_job);
|
pull_job_unref(i->checksum_job);
|
||||||
@ -131,7 +131,6 @@ int tar_pull_new(
|
|||||||
.image_root = TAKE_PTR(root),
|
.image_root = TAKE_PTR(root),
|
||||||
.event = TAKE_PTR(e),
|
.event = TAKE_PTR(e),
|
||||||
.glue = TAKE_PTR(g),
|
.glue = TAKE_PTR(g),
|
||||||
.tar_pid = PIDREF_NULL,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
i->glue->on_finished = pull_job_curl_on_finished;
|
i->glue->on_finished = pull_job_curl_on_finished;
|
||||||
@ -378,11 +377,10 @@ static void tar_pull_job_on_finished(PullJob *j) {
|
|||||||
pull_job_close_disk_fd(i->tar_job);
|
pull_job_close_disk_fd(i->tar_job);
|
||||||
pull_job_close_disk_fd(i->settings_job);
|
pull_job_close_disk_fd(i->settings_job);
|
||||||
|
|
||||||
if (pidref_is_set(&i->tar_pid)) {
|
if (i->tar_pid > 0) {
|
||||||
r = pidref_wait_for_terminate_and_check("tar", &i->tar_pid, WAIT_LOG);
|
r = wait_for_terminate_and_check("tar", TAKE_PID(i->tar_pid), WAIT_LOG);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
pidref_done(&i->tar_pid);
|
|
||||||
if (r != EXIT_SUCCESS) {
|
if (r != EXIT_SUCCESS) {
|
||||||
r = -EIO;
|
r = -EIO;
|
||||||
goto finish;
|
goto finish;
|
||||||
@ -511,7 +509,7 @@ static int tar_pull_job_on_open_disk_tar(PullJob *j) {
|
|||||||
|
|
||||||
i = j->userdata;
|
i = j->userdata;
|
||||||
assert(i->tar_job == j);
|
assert(i->tar_job == j);
|
||||||
assert(!pidref_is_set(&i->tar_pid));
|
assert(i->tar_pid <= 0);
|
||||||
|
|
||||||
if (i->flags & IMPORT_DIRECT)
|
if (i->flags & IMPORT_DIRECT)
|
||||||
where = i->local;
|
where = i->local;
|
||||||
|
@ -136,6 +136,7 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int id128_get_machine_at(int rfd, sd_id128_t *ret) {
|
int id128_get_machine_at(int rfd, sd_id128_t *ret) {
|
||||||
|
_cleanup_close_ int fd = -EBADF;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rfd >= 0 || rfd == AT_FDCWD);
|
assert(rfd >= 0 || rfd == AT_FDCWD);
|
||||||
@ -146,8 +147,7 @@ int id128_get_machine_at(int rfd, sd_id128_t *ret) {
|
|||||||
if (r > 0)
|
if (r > 0)
|
||||||
return sd_id128_get_machine(ret);
|
return sd_id128_get_machine(ret);
|
||||||
|
|
||||||
_cleanup_close_ int fd =
|
fd = chase_and_openat(rfd, "/etc/machine-id", CHASE_AT_RESOLVE_IN_ROOT, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
|
||||||
chase_and_openat(rfd, "/etc/machine-id", CHASE_AT_RESOLVE_IN_ROOT|CHASE_MUST_BE_REGULAR, O_RDONLY|O_CLOEXEC|O_NOCTTY, /* ret_path= */ NULL);
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
@ -155,11 +155,12 @@ int id128_get_machine_at(int rfd, sd_id128_t *ret) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int id128_get_machine(const char *root, sd_id128_t *ret) {
|
int id128_get_machine(const char *root, sd_id128_t *ret) {
|
||||||
|
_cleanup_close_ int fd = -EBADF;
|
||||||
|
|
||||||
if (empty_or_root(root))
|
if (empty_or_root(root))
|
||||||
return sd_id128_get_machine(ret);
|
return sd_id128_get_machine(ret);
|
||||||
|
|
||||||
_cleanup_close_ int fd =
|
fd = chase_and_open("/etc/machine-id", root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL);
|
||||||
chase_and_open("/etc/machine-id", root, CHASE_PREFIX_ROOT|CHASE_MUST_BE_REGULAR, O_RDONLY|O_CLOEXEC|O_NOCTTY, /* ret_path= */ NULL);
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
|
@ -19,7 +19,6 @@
|
|||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "pager.h"
|
#include "pager.h"
|
||||||
#include "parse-argument.h"
|
#include "parse-argument.h"
|
||||||
#include "path-util.h"
|
|
||||||
#include "polkit-agent.h"
|
#include "polkit-agent.h"
|
||||||
#include "pretty-print.h"
|
#include "pretty-print.h"
|
||||||
#include "runtime-scope.h"
|
#include "runtime-scope.h"
|
||||||
@ -291,14 +290,6 @@ static int set_x11_keymap(int argc, char **argv, void *userdata) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* xkb_directory(void) {
|
|
||||||
static const char *cached = NULL;
|
|
||||||
|
|
||||||
if (!cached)
|
|
||||||
cached = secure_getenv("SYSTEMD_XKB_DIRECTORY") ?: "/usr/share/X11/xkb";
|
|
||||||
return cached;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int list_x11_keymaps(int argc, char **argv, void *userdata) {
|
static int list_x11_keymaps(int argc, char **argv, void *userdata) {
|
||||||
_cleanup_fclose_ FILE *f = NULL;
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
_cleanup_strv_free_ char **list = NULL;
|
_cleanup_strv_free_ char **list = NULL;
|
||||||
@ -311,15 +302,9 @@ static int list_x11_keymaps(int argc, char **argv, void *userdata) {
|
|||||||
} state = NONE, look_for;
|
} state = NONE, look_for;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
_cleanup_free_ char *xkb_base = path_join(xkb_directory(), "rules/base.lst");
|
f = fopen("/usr/share/X11/xkb/rules/base.lst", "re");
|
||||||
if (!xkb_base)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
f = fopen(xkb_base, "re");
|
|
||||||
if (!f)
|
if (!f)
|
||||||
return log_error_errno(errno,
|
return log_error_errno(errno, "Failed to open keyboard mapping list: %m");
|
||||||
"Failed to open keyboard mapping list %s: %m",
|
|
||||||
xkb_base);
|
|
||||||
|
|
||||||
if (streq(argv[0], "list-x11-keymap-models"))
|
if (streq(argv[0], "list-x11-keymap-models"))
|
||||||
look_for = MODELS;
|
look_for = MODELS;
|
||||||
@ -338,9 +323,7 @@ static int list_x11_keymaps(int argc, char **argv, void *userdata) {
|
|||||||
|
|
||||||
r = read_stripped_line(f, LONG_LINE_MAX, &line);
|
r = read_stripped_line(f, LONG_LINE_MAX, &line);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r,
|
return log_error_errno(r, "Failed to read keyboard mapping list: %m");
|
||||||
"Failed to read keyboard mapping list %s: %m",
|
|
||||||
xkb_base);
|
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -394,8 +377,7 @@ static int list_x11_keymaps(int argc, char **argv, void *userdata) {
|
|||||||
|
|
||||||
if (strv_isempty(list))
|
if (strv_isempty(list))
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
return log_error_errno(SYNTHETIC_ERRNO(ENOENT),
|
||||||
"Couldn't find any entries in keyboard mapping list %s.",
|
"Couldn't find any entries.");
|
||||||
xkb_base);
|
|
||||||
|
|
||||||
strv_sort_uniq(list);
|
strv_sort_uniq(list);
|
||||||
|
|
||||||
|
@ -4,6 +4,5 @@ executables += [
|
|||||||
libexec_template + {
|
libexec_template + {
|
||||||
'name' : 'systemd-remount-fs',
|
'name' : 'systemd-remount-fs',
|
||||||
'sources' : files('remount-fs.c'),
|
'sources' : files('remount-fs.c'),
|
||||||
'dependencies' : libmount,
|
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
|
#include <mntent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -10,7 +11,6 @@
|
|||||||
#include "format-util.h"
|
#include "format-util.h"
|
||||||
#include "fstab-util.h"
|
#include "fstab-util.h"
|
||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
#include "libmount-util.h"
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
#include "mount-setup.h"
|
#include "mount-setup.h"
|
||||||
@ -35,8 +35,10 @@ static int track_pid(Hashmap **h, const char *path, pid_t pid) {
|
|||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = hashmap_ensure_put(h, &trivial_hash_ops_value_free, PID_TO_PTR(pid), c);
|
r = hashmap_ensure_put(h, &trivial_hash_ops_value_free, PID_TO_PTR(pid), c);
|
||||||
|
if (r == -ENOMEM)
|
||||||
|
return log_oom();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to store pid " PID_FMT " for mount '%s': %m", pid, path);
|
return log_error_errno(r, "Failed to store pid " PID_FMT, pid);
|
||||||
|
|
||||||
TAKE_PTR(c);
|
TAKE_PTR(c);
|
||||||
return 0;
|
return 0;
|
||||||
@ -46,8 +48,6 @@ static int do_remount(const char *path, bool force_rw, Hashmap **pids) {
|
|||||||
pid_t pid;
|
pid_t pid;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(path);
|
|
||||||
|
|
||||||
log_debug("Remounting %s...", path);
|
log_debug("Remounting %s...", path);
|
||||||
|
|
||||||
r = safe_fork(force_rw ? "(remount-rw)" : "(remount)",
|
r = safe_fork(force_rw ? "(remount-rw)" : "(remount)",
|
||||||
@ -70,10 +70,10 @@ static int do_remount(const char *path, bool force_rw, Hashmap **pids) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int remount_by_fstab(Hashmap **ret_pids) {
|
static int remount_by_fstab(Hashmap **ret_pids) {
|
||||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
|
||||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
|
||||||
_cleanup_hashmap_free_ Hashmap *pids = NULL;
|
_cleanup_hashmap_free_ Hashmap *pids = NULL;
|
||||||
|
_cleanup_endmntent_ FILE *f = NULL;
|
||||||
bool has_root = false;
|
bool has_root = false;
|
||||||
|
struct mntent* me;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(ret_pids);
|
assert(ret_pids);
|
||||||
@ -81,33 +81,24 @@ static int remount_by_fstab(Hashmap **ret_pids) {
|
|||||||
if (!fstab_enabled())
|
if (!fstab_enabled())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = libmount_parse_fstab(&table, &iter);
|
f = setmntent(fstab_path(), "re");
|
||||||
if (r == -ENOENT)
|
if (!f) {
|
||||||
|
if (errno != ENOENT)
|
||||||
|
return log_error_errno(errno, "Failed to open %s: %m", fstab_path());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
if (r < 0)
|
}
|
||||||
return log_error_errno(r, "Failed to parse fstab: %m");
|
|
||||||
|
|
||||||
for (;;) {
|
while ((me = getmntent(f))) {
|
||||||
struct libmnt_fs *fs;
|
/* Remount the root fs, /usr, and all API VFSs */
|
||||||
|
if (!mount_point_is_api(me->mnt_dir) &&
|
||||||
r = mnt_table_next_fs(table, iter, &fs);
|
!PATH_IN_SET(me->mnt_dir, "/", "/usr"))
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Failed to get next entry from fstab: %m");
|
|
||||||
if (r > 0) /* EOF */
|
|
||||||
break;
|
|
||||||
|
|
||||||
const char *target = mnt_fs_get_target(fs);
|
|
||||||
if (!target)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Remount the root fs, /usr/, and all API VFSs */
|
if (path_equal(me->mnt_dir, "/"))
|
||||||
|
|
||||||
if (path_equal(target, "/"))
|
|
||||||
has_root = true;
|
has_root = true;
|
||||||
else if (!path_equal(target, "/usr") && !mount_point_is_api(target))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
r = do_remount(target, /* force_rw = */ false, &pids);
|
r = do_remount(me->mnt_dir, false, &pids);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -141,7 +132,7 @@ static int run(int argc, char *argv[]) {
|
|||||||
log_warning_errno(r, "Failed to parse $SYSTEMD_REMOUNT_ROOT_RW, ignoring: %m");
|
log_warning_errno(r, "Failed to parse $SYSTEMD_REMOUNT_ROOT_RW, ignoring: %m");
|
||||||
|
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
r = do_remount("/", /* force_rw = */ true, &pids);
|
r = do_remount("/", true, &pids);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -648,7 +648,3 @@ int fd_acl_make_writable_fallback(int fd) {
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int inode_type_can_acl(mode_t mode) {
|
|
||||||
return IN_SET(mode & S_IFMT, S_IFSOCK, S_IFREG, S_IFBLK, S_IFCHR, S_IFDIR, S_IFIFO);
|
|
||||||
}
|
|
||||||
|
@ -53,5 +53,3 @@ static inline int fd_acl_make_writable(int fd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int inode_type_can_acl(mode_t mode);
|
|
||||||
|
@ -1201,19 +1201,6 @@ int decrypt_credential_and_warn(
|
|||||||
assert(iovec_is_valid(input));
|
assert(iovec_is_valid(input));
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
/* Relevant error codes:
|
|
||||||
*
|
|
||||||
* -EBADMSG → Corrupted file
|
|
||||||
* -EOPNOTSUPP → Unsupported file type (could be: requires TPM but we have no TPM)
|
|
||||||
* -EHOSTDOWN → Need PCR signature file, but couldn't find it
|
|
||||||
* -EHWPOISON → Attempt to decode NULL key (and CREDENTIAL_ALLOW_NULL is off), but the system has a TPM and SecureBoot is on
|
|
||||||
* -EMEDIUMTYPE → File has unexpected scope, i.e. user-scoped credential is attempted to be unlocked in system scope, or vice versa
|
|
||||||
* -EDESTADDRREQ → Credential is incorrectly named (i.e. the authenticated name does not match the actual name)
|
|
||||||
* -ESTALE → Credential's valdity has passed
|
|
||||||
* -ESRCH → User specified for scope does not exist on this system
|
|
||||||
*
|
|
||||||
* (plus the various error codes tpm2_unseal() returns) */
|
|
||||||
|
|
||||||
h = (struct encrypted_credential_header*) input->iov_base;
|
h = (struct encrypted_credential_header*) input->iov_base;
|
||||||
|
|
||||||
/* The ID must fit in, for the current and all future formats */
|
/* The ID must fit in, for the current and all future formats */
|
||||||
@ -1231,10 +1218,8 @@ int decrypt_credential_and_warn(
|
|||||||
|
|
||||||
if (with_tpm2_pk) {
|
if (with_tpm2_pk) {
|
||||||
r = tpm2_load_pcr_signature(tpm2_signature_path, &signature_json);
|
r = tpm2_load_pcr_signature(tpm2_signature_path, &signature_json);
|
||||||
if (r == -ENOENT)
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EHOSTDOWN), "Couldn't find PCR signature file: %m");
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to load PCR signature: %m");
|
return log_error_errno(r, "Failed to load pcr signature: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (with_null && !FLAGS_SET(flags, CREDENTIAL_ALLOW_NULL)) {
|
if (with_null && !FLAGS_SET(flags, CREDENTIAL_ALLOW_NULL)) {
|
||||||
@ -1249,7 +1234,7 @@ int decrypt_credential_and_warn(
|
|||||||
|
|
||||||
if (efi_has_tpm2()) {
|
if (efi_has_tpm2()) {
|
||||||
if (is_efi_secure_boot())
|
if (is_efi_secure_boot())
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EHWPOISON),
|
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG),
|
||||||
"Credential uses fixed key for fallback use when TPM2 is absent — but TPM2 is present, and SecureBoot is enabled, refusing.");
|
"Credential uses fixed key for fallback use when TPM2 is absent — but TPM2 is present, and SecureBoot is enabled, refusing.");
|
||||||
|
|
||||||
log_warning("Credential uses fixed key for use when TPM2 is absent, but TPM2 is present! Accepting anyway, since SecureBoot is disabled.");
|
log_warning("Credential uses fixed key for use when TPM2 is absent, but TPM2 is present! Accepting anyway, since SecureBoot is disabled.");
|
||||||
@ -1369,7 +1354,7 @@ int decrypt_credential_and_warn(
|
|||||||
/* srk= */ NULL,
|
/* srk= */ NULL,
|
||||||
&tpm2_key);
|
&tpm2_key);
|
||||||
if (r == -EREMOTE)
|
if (r == -EREMOTE)
|
||||||
return log_error_errno(r, "TPM key integrity check failed. Key most likely does not belong to this TPM.");
|
return log_error_errno(r, "TPM key integrity check failed. Key enrolled in superblock most likely does not belong to this TPM.");
|
||||||
if (ERRNO_IS_NEG_TPM2_UNSEAL_BAD_PCR(r))
|
if (ERRNO_IS_NEG_TPM2_UNSEAL_BAD_PCR(r))
|
||||||
return log_error_errno(r, "TPM policy does not match current system state. Either system has been tempered with or policy out-of-date: %m");
|
return log_error_errno(r, "TPM policy does not match current system state. Either system has been tempered with or policy out-of-date: %m");
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -1501,7 +1486,7 @@ int decrypt_credential_and_warn(
|
|||||||
if (r < 0 && r != -ENXIO)
|
if (r < 0 && r != -ENXIO)
|
||||||
log_debug_errno(r, "Failed to parse $SYSTEMD_CREDENTIAL_VALIDATE_NAME: %m");
|
log_debug_errno(r, "Failed to parse $SYSTEMD_CREDENTIAL_VALIDATE_NAME: %m");
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EDESTADDRREQ), "Embedded credential name '%s' does not match filename '%s', refusing.", embedded_name, validate_name);
|
return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), "Embedded credential name '%s' does not match filename '%s', refusing.", embedded_name, validate_name);
|
||||||
|
|
||||||
log_debug("Embedded credential name '%s' does not match expected name '%s', but configured to use credential anyway.", embedded_name, validate_name);
|
log_debug("Embedded credential name '%s' does not match expected name '%s', but configured to use credential anyway.", embedded_name, validate_name);
|
||||||
}
|
}
|
||||||
@ -1652,26 +1637,16 @@ int ipc_decrypt_credential(const char *validate_name, usec_t validate_timestamp,
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to call Decrypt() varlink call.");
|
return log_error_errno(r, "Failed to call Decrypt() varlink call.");
|
||||||
if (!isempty(error_id)) {
|
if (!isempty(error_id)) {
|
||||||
static struct {
|
if (streq(error_id, "io.systemd.Credentials.BadFormat"))
|
||||||
const char *id;
|
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Bad credential format.");
|
||||||
int errnum;
|
if (streq(error_id, "io.systemd.Credentials.NameMismatch"))
|
||||||
const char *msg;
|
return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), "Name in credential doesn't match expectations.");
|
||||||
} table[] = {
|
if (streq(error_id, "io.systemd.Credentials.TimeMismatch"))
|
||||||
{ "io.systemd.Credentials.BadFormat", EBADMSG, "Bad credential format." },
|
return log_error_errno(SYNTHETIC_ERRNO(ESTALE), "Outside of credential validity time window.");
|
||||||
{ "io.systemd.Credentials.NameMismatch", EDESTADDRREQ, "Name in credential doesn't match expectations." },
|
if (streq(error_id, "io.systemd.Credentials.NoSuchUser"))
|
||||||
{ "io.systemd.Credentials.TimeMismatch", ESTALE, "Outside of credential validity time window." },
|
return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "No such user.");
|
||||||
{ "io.systemd.Credentials.NoSuchUser", ESRCH, "No such user." },
|
if (streq(error_id, "io.systemd.Credentials.BadScope"))
|
||||||
{ "io.systemd.Credentials.BadScope", EMEDIUMTYPE, "Scope mismatch." },
|
return log_error_errno(SYNTHETIC_ERRNO(EMEDIUMTYPE), "Scope mismtach.");
|
||||||
{ "io.systemd.Credentials.CantFindPCRSignature", EHOSTDOWN, "PCR signature required for decryption, but could not be found." },
|
|
||||||
{ "io.systemd.Credentials.NullKeyNotAllowed", EHWPOISON, "The key was encrypted with a null key, but that's now allowed during decryption." },
|
|
||||||
{ "io.systemd.Credentials.KeyBelongsToOtherTPM", EREMOTE, "The TPM integrity check for this key failed, key probably belongs to another TPM, or was corrupted." },
|
|
||||||
{ "io.systemd.Credentials.TPMInDictionaryLockout", ENOLCK, "The TPM is in dictionary lockout mode, cannot operate." },
|
|
||||||
{ "io.systemd.Credentials.UnexpectedPCRState" , EUCLEAN, "Unexpected TPM PCR state of the system." },
|
|
||||||
};
|
|
||||||
|
|
||||||
FOREACH_ELEMENT(i, table)
|
|
||||||
if (streq(i->id, error_id))
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(i->errnum), "%s", i->msg);
|
|
||||||
|
|
||||||
return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to decrypt: %s", error_id);
|
return log_error_errno(sd_varlink_error_to_errno(error_id, reply), "Failed to decrypt: %s", error_id);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <mntent.h>
|
||||||
|
|
||||||
#include "forward.h"
|
#include "forward.h"
|
||||||
|
|
||||||
typedef struct SubMount {
|
typedef struct SubMount {
|
||||||
@ -35,6 +37,9 @@ static inline int mount_switch_root(const char *path, unsigned long mount_propag
|
|||||||
return mount_switch_root_full(path, mount_propagation_flag, false);
|
return mount_switch_root_full(path, mount_propagation_flag, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(FILE*, endmntent, NULL);
|
||||||
|
#define _cleanup_endmntent_ _cleanup_(endmntentp)
|
||||||
|
|
||||||
int mount_verbose_full(
|
int mount_verbose_full(
|
||||||
int error_log_level,
|
int error_log_level,
|
||||||
const char *what,
|
const char *what,
|
||||||
|
@ -161,7 +161,7 @@ static int patch_acls(int fd, const char *name, const struct stat *st, uid_t shi
|
|||||||
assert(st);
|
assert(st);
|
||||||
|
|
||||||
/* ACLs are not supported on symlinks, there's no point in trying */
|
/* ACLs are not supported on symlinks, there's no point in trying */
|
||||||
if (!inode_type_can_acl(st->st_mode))
|
if (S_ISLNK(st->st_mode))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = get_acl(fd, name, ACL_TYPE_ACCESS, &acl);
|
r = get_acl(fd, name, ACL_TYPE_ACCESS, &acl);
|
||||||
|
@ -44,11 +44,6 @@ static SD_VARLINK_DEFINE_ERROR(NameMismatch);
|
|||||||
static SD_VARLINK_DEFINE_ERROR(TimeMismatch);
|
static SD_VARLINK_DEFINE_ERROR(TimeMismatch);
|
||||||
static SD_VARLINK_DEFINE_ERROR(NoSuchUser);
|
static SD_VARLINK_DEFINE_ERROR(NoSuchUser);
|
||||||
static SD_VARLINK_DEFINE_ERROR(BadScope);
|
static SD_VARLINK_DEFINE_ERROR(BadScope);
|
||||||
static SD_VARLINK_DEFINE_ERROR(CantFindPCRSignature);
|
|
||||||
static SD_VARLINK_DEFINE_ERROR(NullKeyNotAllowed);
|
|
||||||
static SD_VARLINK_DEFINE_ERROR(KeyBelongsToOtherTPM);
|
|
||||||
static SD_VARLINK_DEFINE_ERROR(TPMInDictionaryLockout);
|
|
||||||
static SD_VARLINK_DEFINE_ERROR(UnexpectedPCRState);
|
|
||||||
|
|
||||||
SD_VARLINK_DEFINE_INTERFACE(
|
SD_VARLINK_DEFINE_INTERFACE(
|
||||||
io_systemd_Credentials,
|
io_systemd_Credentials,
|
||||||
@ -67,14 +62,4 @@ SD_VARLINK_DEFINE_INTERFACE(
|
|||||||
SD_VARLINK_SYMBOL_COMMENT("The specified user does not exist."),
|
SD_VARLINK_SYMBOL_COMMENT("The specified user does not exist."),
|
||||||
&vl_error_NoSuchUser,
|
&vl_error_NoSuchUser,
|
||||||
SD_VARLINK_SYMBOL_COMMENT("The credential does not match the selected scope."),
|
SD_VARLINK_SYMBOL_COMMENT("The credential does not match the selected scope."),
|
||||||
&vl_error_BadScope,
|
&vl_error_BadScope);
|
||||||
SD_VARLINK_SYMBOL_COMMENT("PCR signature required for decryption, but not found."),
|
|
||||||
&vl_error_CantFindPCRSignature,
|
|
||||||
SD_VARLINK_SYMBOL_COMMENT("The key was encrypted with a null key, but that's now allowed during decryption."),
|
|
||||||
&vl_error_NullKeyNotAllowed,
|
|
||||||
SD_VARLINK_SYMBOL_COMMENT("The TPM integrity check for this key failed, key probably belongs to another TPM, or was corrupted."),
|
|
||||||
&vl_error_KeyBelongsToOtherTPM,
|
|
||||||
SD_VARLINK_SYMBOL_COMMENT("The TPM is in dictionary lockout mode, cannot operate."),
|
|
||||||
&vl_error_TPMInDictionaryLockout,
|
|
||||||
SD_VARLINK_SYMBOL_COMMENT("Unexpected TPM PCR state of the system."),
|
|
||||||
&vl_error_UnexpectedPCRState);
|
|
||||||
|
@ -164,7 +164,7 @@ static void test_encrypt_decrypt_with(sd_id128_t mode, uid_t uid) {
|
|||||||
&encrypted,
|
&encrypted,
|
||||||
CREDENTIAL_ALLOW_NULL,
|
CREDENTIAL_ALLOW_NULL,
|
||||||
&decrypted);
|
&decrypted);
|
||||||
ASSERT_ERROR(r, EDESTADDRREQ); /* name didn't match */
|
ASSERT_ERROR(r, EREMOTE); /* name didn't match */
|
||||||
|
|
||||||
r = decrypt_credential_and_warn(
|
r = decrypt_credential_and_warn(
|
||||||
"foo",
|
"foo",
|
||||||
|
@ -1459,8 +1459,8 @@ static int fd_set_acls(
|
|||||||
"Refusing to set ACLs on hardlinked file %s while the fs.protected_hardlinks sysctl is turned off.",
|
"Refusing to set ACLs on hardlinked file %s while the fs.protected_hardlinks sysctl is turned off.",
|
||||||
path);
|
path);
|
||||||
|
|
||||||
if (!inode_type_can_acl(st->st_mode)) {
|
if (S_ISLNK(st->st_mode)) {
|
||||||
log_debug("Skipping ACL fix for '%s' (inode type does not support ACLs).", path);
|
log_debug("Skipping ACL fix for symlink %s.", path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ static int stack_directory_find_prioritized_devnode(sd_device *dev, int dirfd, b
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
dir = xopendirat(dirfd, /* path= */ NULL, /* flags= */ 0);
|
dir = xopendirat(dirfd, ".", O_NOFOLLOW);
|
||||||
if (!dir)
|
if (!dir)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
|
@ -49,9 +49,10 @@ FSTAB_GENERAL=(
|
|||||||
"/dev/test25 /x-systemd.validatefs xfs x-systemd.validatefs 0 0"
|
"/dev/test25 /x-systemd.validatefs xfs x-systemd.validatefs 0 0"
|
||||||
|
|
||||||
# Incomplete, but valid entries
|
# Incomplete, but valid entries
|
||||||
"/dev/incomplete1 /incomplete1 ext4"
|
"/dev/incomplete1 /incomplete1"
|
||||||
"/dev/incomplete2 /incomplete2 ext4 defaults"
|
"/dev/incomplete2 /incomplete2 ext4"
|
||||||
"/dev/incomplete3 /incomplete3 ext4 defaults 0"
|
"/dev/incomplete3 /incomplete3 ext4 defaults"
|
||||||
|
"/dev/incomplete4 /incomplete4 ext4 defaults 0"
|
||||||
|
|
||||||
# Remote filesystems
|
# Remote filesystems
|
||||||
"/dev/remote1 /nfs nfs bg 0 0"
|
"/dev/remote1 /nfs nfs bg 0 0"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user