mirror of
https://github.com/systemd/systemd.git
synced 2025-03-19 22:50:17 +03:00
logind: implement ACL management
This commit is contained in:
parent
90821c935e
commit
5eda94dda2
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
systemd-uaccess
|
||||
systemd-logind
|
||||
systemd-hostnamed
|
||||
systemd-binfmt
|
||||
|
24
Makefile.am
24
Makefile.am
@ -159,7 +159,8 @@ rootlibexec_PROGRAMS = \
|
||||
systemd-detect-virt \
|
||||
systemd-sysctl \
|
||||
systemd-hostnamed \
|
||||
systemd-logind
|
||||
systemd-logind \
|
||||
systemd-uaccess
|
||||
|
||||
if ENABLE_BINFMT
|
||||
rootlibexec_PROGRAMS += \
|
||||
@ -813,6 +814,7 @@ systemd_logind_SOURCES = \
|
||||
src/logind-seat.c \
|
||||
src/logind-session.c \
|
||||
src/logind-user.c \
|
||||
src/logind-acl.c \
|
||||
src/dbus-common.c \
|
||||
src/dbus-loop.c \
|
||||
src/cgroup-util.c
|
||||
@ -820,13 +822,29 @@ systemd_logind_SOURCES = \
|
||||
systemd_logind_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
$(DBUS_CFLAGS) \
|
||||
$(UDEV_CFLAGS)
|
||||
$(UDEV_CFLAGS) \
|
||||
$(ACL_CFLAGS)
|
||||
|
||||
systemd_logind_LDADD = \
|
||||
libsystemd-basic.la \
|
||||
libsystemd-daemon.la \
|
||||
$(DBUS_LIBS) \
|
||||
$(UDEV_LIBS)
|
||||
$(UDEV_LIBS) \
|
||||
$(ACL_LIBS)
|
||||
|
||||
systemd_uaccess_SOURCES = \
|
||||
src/uaccess.c \
|
||||
src/logind-acl.c
|
||||
|
||||
systemd_uaccess_CFLAGS = \
|
||||
$(AM_CFLAGS) \
|
||||
$(UDEV_CFLAGS) \
|
||||
$(ACL_CFLAGS)
|
||||
|
||||
systemd_uaccess_LDADD = \
|
||||
libsystemd-basic.la \
|
||||
$(UDEV_LIBS) \
|
||||
$(ACL_LIBS)
|
||||
|
||||
systemd_shutdown_SOURCES = \
|
||||
src/mount-setup.c \
|
||||
|
38
configure.ac
38
configure.ac
@ -193,6 +193,43 @@ fi
|
||||
AC_SUBST(PAM_LIBS)
|
||||
AM_CONDITIONAL([HAVE_PAM], [test "x$have_pam" != xno])
|
||||
|
||||
AC_ARG_ENABLE([acl],
|
||||
AS_HELP_STRING([--disable-acl],[Disable optional ACL support]),
|
||||
[case "${enableval}" in
|
||||
yes) have_acl=yes ;;
|
||||
no) have_acl=no ;;
|
||||
*) AC_MSG_ERROR(bad value ${enableval} for --disable-acl) ;;
|
||||
esac],
|
||||
[have_acl=auto])
|
||||
|
||||
if test "x${have_acl}" != xno ; then
|
||||
AC_CHECK_HEADERS(
|
||||
[sys/acl.h acl/libacl.h],
|
||||
[have_acl=yes],
|
||||
[if test "x$have_acl" = xyes ; then
|
||||
AC_MSG_ERROR([*** ACL headers not found.])
|
||||
fi])
|
||||
|
||||
AC_CHECK_LIB(
|
||||
[acl],
|
||||
[acl_get_file],
|
||||
[have_acl=yes],
|
||||
[if test "x$have_acl" = xyes ; then
|
||||
AC_MSG_ERROR([*** libacl not found.])
|
||||
fi])
|
||||
|
||||
if test "x$have_acl" = xyes ; then
|
||||
ACL_LIBS="-lacl"
|
||||
AC_DEFINE(HAVE_ACL, 1, [ACL available])
|
||||
else
|
||||
have_acl=no
|
||||
fi
|
||||
else
|
||||
ACL_LIBS=
|
||||
fi
|
||||
AC_SUBST(ACL_LIBS)
|
||||
AM_CONDITIONAL([HAVE_ACL], [test "x$have_acl" != xno])
|
||||
|
||||
AC_ARG_ENABLE([audit],
|
||||
AS_HELP_STRING([--disable-audit],[Disable optional AUDIT support]),
|
||||
[case "${enableval}" in
|
||||
@ -496,6 +533,7 @@ echo "
|
||||
PAM: ${have_pam}
|
||||
AUDIT: ${have_audit}
|
||||
SELinux: ${have_selinux}
|
||||
ACL: ${have_acl}
|
||||
binfmt: ${have_binfmt}
|
||||
prefix: ${prefix}
|
||||
root dir: ${with_rootdir}
|
||||
|
282
src/logind-acl.c
Normal file
282
src/logind-acl.c
Normal file
@ -0,0 +1,282 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2011 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/acl.h>
|
||||
#include <acl/libacl.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "logind-acl.h"
|
||||
#include "util.h"
|
||||
|
||||
static int find_acl(acl_t acl, uid_t uid, acl_entry_t *entry) {
|
||||
acl_entry_t i;
|
||||
int found;
|
||||
|
||||
assert(acl);
|
||||
assert(entry);
|
||||
|
||||
for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
|
||||
found > 0;
|
||||
found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {
|
||||
|
||||
acl_tag_t tag;
|
||||
uid_t *u;
|
||||
bool b;
|
||||
|
||||
if (acl_get_tag_type(i, &tag) < 0)
|
||||
return -errno;
|
||||
|
||||
if (tag != ACL_USER)
|
||||
continue;
|
||||
|
||||
u = acl_get_qualifier(i);
|
||||
if (!u)
|
||||
return -errno;
|
||||
|
||||
b = *u == uid;
|
||||
free(u);
|
||||
|
||||
if (b) {
|
||||
*entry = i;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (found < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int flush_acl(acl_t acl) {
|
||||
acl_entry_t i;
|
||||
int found;
|
||||
bool changed = false;
|
||||
|
||||
assert(acl);
|
||||
|
||||
for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
|
||||
found > 0;
|
||||
found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {
|
||||
|
||||
acl_tag_t tag;
|
||||
|
||||
if (acl_get_tag_type(i, &tag) < 0)
|
||||
return -errno;
|
||||
|
||||
if (tag != ACL_USER)
|
||||
continue;
|
||||
|
||||
if (acl_delete_entry(acl, i) < 0)
|
||||
return -errno;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (found < 0)
|
||||
return -errno;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
int devnode_acl(const char *path,
|
||||
bool flush,
|
||||
bool del, uid_t old_uid,
|
||||
bool add, uid_t new_uid) {
|
||||
|
||||
acl_t acl;
|
||||
int r;
|
||||
bool changed = false;
|
||||
|
||||
assert(path);
|
||||
|
||||
acl = acl_get_file(path, ACL_TYPE_ACCESS);
|
||||
if (!acl)
|
||||
return -errno;
|
||||
|
||||
if (flush) {
|
||||
|
||||
r = flush_acl(acl);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
if (r > 0)
|
||||
changed = true;
|
||||
|
||||
} else if (del && old_uid > 0) {
|
||||
acl_entry_t entry;
|
||||
|
||||
r = find_acl(acl, old_uid, &entry);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
if (r > 0) {
|
||||
if (acl_delete_entry(acl, entry) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (add && new_uid > 0) {
|
||||
acl_entry_t entry;
|
||||
acl_permset_t permset;
|
||||
int rd, wt;
|
||||
|
||||
r = find_acl(acl, new_uid, &entry);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
if (r == 0) {
|
||||
if (acl_create_entry(&acl, &entry) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (acl_set_tag_type(entry, ACL_USER) < 0 ||
|
||||
acl_set_qualifier(entry, &new_uid) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
if (acl_get_permset(entry, &permset) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
rd = acl_get_perm(permset, ACL_READ);
|
||||
if (rd < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
wt = acl_get_perm(permset, ACL_WRITE);
|
||||
if (wt < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!rd || !wt) {
|
||||
|
||||
if (acl_add_perm(permset, ACL_READ|ACL_WRITE) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed)
|
||||
goto finish;
|
||||
|
||||
if (acl_calc_mask(&acl) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (acl_set_file(path, ACL_TYPE_ACCESS, acl) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
finish:
|
||||
acl_free(acl);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int devnode_acl_all(struct udev *udev,
|
||||
const char *seat,
|
||||
bool flush,
|
||||
bool del, uid_t old_uid,
|
||||
bool add, uid_t new_uid) {
|
||||
|
||||
struct udev_list_entry *item = NULL, *first = NULL;
|
||||
struct udev_enumerate *e;
|
||||
int r;
|
||||
|
||||
assert(udev);
|
||||
|
||||
if (!seat)
|
||||
seat = "seat0";
|
||||
|
||||
e = udev_enumerate_new(udev);
|
||||
if (!e)
|
||||
return -ENOMEM;
|
||||
|
||||
r = udev_enumerate_add_match_tag(e, "uaccess");
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = udev_enumerate_add_match_tag(e, seat);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = udev_enumerate_scan_devices(e);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
first = udev_enumerate_get_list_entry(e);
|
||||
udev_list_entry_foreach(item, first) {
|
||||
struct udev_device *d;
|
||||
const char *node, *sn;
|
||||
|
||||
d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item));
|
||||
if (!d) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
sn = udev_device_get_property_value(d, "SEAT");
|
||||
if (!sn)
|
||||
sn = "seat0";
|
||||
|
||||
if (!streq(seat, sn)) {
|
||||
udev_device_unref(d);
|
||||
continue;
|
||||
}
|
||||
|
||||
node = udev_device_get_devnode(d);
|
||||
udev_device_unref(d);
|
||||
|
||||
if (!node) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = devnode_acl(node, flush, del, old_uid, add, new_uid);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if (e)
|
||||
udev_enumerate_unref(e);
|
||||
|
||||
return r;
|
||||
}
|
40
src/logind-acl.h
Normal file
40
src/logind-acl.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
#ifndef foologindaclhfoo
|
||||
#define foologindaclhfoo
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2011 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdbool.h>
|
||||
#include <libudev.h>
|
||||
|
||||
int devnode_acl(const char *path,
|
||||
bool flush,
|
||||
bool del, uid_t old_uid,
|
||||
bool add, uid_t new_uid);
|
||||
|
||||
int devnode_acl_all(struct udev *udev,
|
||||
const char *seat,
|
||||
bool flush,
|
||||
bool del, uid_t old_uid,
|
||||
bool add, uid_t new_uid);
|
||||
|
||||
#endif
|
@ -25,8 +25,10 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/vt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "logind-seat.h"
|
||||
#include "logind-acl.h"
|
||||
#include "util.h"
|
||||
|
||||
Seat *seat_new(Manager *m, const char *id) {
|
||||
@ -179,40 +181,32 @@ int seat_preallocate_vts(Seat *s) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int seat_apply_acls(Seat *s) {
|
||||
int seat_apply_acls(Seat *s, Session *old_active) {
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
|
||||
r = devnode_acl_all(s->manager->udev,
|
||||
s->id,
|
||||
false,
|
||||
!!old_active, old_active ? old_active->user->uid : 0,
|
||||
!!s->active, s->active ? s->active->user->uid : 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vt_is_busy(int vtnr) {
|
||||
struct vt_stat vt_stat;
|
||||
int r = 0, fd;
|
||||
|
||||
assert(vtnr >= 1);
|
||||
|
||||
fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
|
||||
r = -errno;
|
||||
else
|
||||
r = !!(vt_stat.v_state & (1 << vtnr));
|
||||
|
||||
close_nointr_nofail(fd);
|
||||
if (r < 0)
|
||||
log_error("Failed to apply ACLs: %s", strerror(-r));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void seat_active_vt_changed(Seat *s, int vtnr) {
|
||||
int seat_active_vt_changed(Seat *s, int vtnr) {
|
||||
Session *i;
|
||||
Session *old_active;
|
||||
|
||||
assert(s);
|
||||
assert(vtnr >= 1);
|
||||
assert(s->manager->vtconsole == s);
|
||||
|
||||
old_active = s->active;
|
||||
s->active = NULL;
|
||||
|
||||
LIST_FOREACH(sessions_by_seat, i, s->sessions)
|
||||
@ -221,10 +215,13 @@ void seat_active_vt_changed(Seat *s, int vtnr) {
|
||||
break;
|
||||
}
|
||||
|
||||
seat_apply_acls(s);
|
||||
if (old_active == s->active)
|
||||
return 0;
|
||||
|
||||
if (vt_is_busy(vtnr) == 0)
|
||||
manager_spawn_autovt(s->manager, vtnr);
|
||||
seat_apply_acls(s, old_active);
|
||||
manager_spawn_autovt(s->manager, vtnr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int seat_stop(Seat *s) {
|
||||
|
@ -45,8 +45,8 @@ struct Seat {
|
||||
Seat *seat_new(Manager *m, const char *id);
|
||||
void seat_free(Seat *s);
|
||||
int seat_preallocate_vts(Seat *s);
|
||||
void seat_active_vt_changed(Seat *s, int vtnr);
|
||||
int seat_apply_acls(Seat *s);
|
||||
int seat_active_vt_changed(Seat *s, int vtnr);
|
||||
int seat_apply_acls(Seat *s, Session *old_active);
|
||||
int seat_stop(Seat *s);
|
||||
int seat_save(Seat *s);
|
||||
int seat_load(Seat *s);
|
||||
|
@ -174,6 +174,7 @@ int session_load(Session *s) {
|
||||
|
||||
int session_activate(Session *s) {
|
||||
int r;
|
||||
Session *old_active;
|
||||
|
||||
assert(s);
|
||||
|
||||
@ -192,9 +193,13 @@ int session_activate(Session *s) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
old_active = s->seat->active;
|
||||
s->seat->active = s;
|
||||
|
||||
return seat_apply_acls(s->seat);
|
||||
seat_apply_acls(s->seat, old_active);
|
||||
manager_spawn_autovt(s->manager, s->vtnr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool x11_display_is_local(const char *display) {
|
||||
|
34
src/logind.c
34
src/logind.c
@ -26,6 +26,8 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/vt.h>
|
||||
|
||||
#include "logind.h"
|
||||
#include "dbus-common.h"
|
||||
@ -290,7 +292,7 @@ int manager_enumerate_devices(Manager *m) {
|
||||
|
||||
e = udev_enumerate_new(m->udev);
|
||||
if (!e)
|
||||
return -ENOMEM;
|
||||
goto finish;
|
||||
|
||||
if (udev_enumerate_add_match_subsystem(e, "graphics") < 0)
|
||||
goto finish;
|
||||
@ -627,9 +629,37 @@ int manager_dispatch_console(Manager *m) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vt_is_busy(int vtnr) {
|
||||
struct vt_stat vt_stat;
|
||||
int r = 0, fd;
|
||||
|
||||
assert(vtnr >= 1);
|
||||
|
||||
fd = open_terminal("/dev/tty0", O_RDWR|O_NOCTTY|O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
if (ioctl(fd, VT_GETSTATE, &vt_stat) < 0)
|
||||
r = -errno;
|
||||
else
|
||||
r = !!(vt_stat.v_state & (1 << vtnr));
|
||||
|
||||
close_nointr_nofail(fd);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int manager_spawn_autovt(Manager *m, int vtnr) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
r = vt_is_busy(vtnr);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
/* ... */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -849,7 +879,7 @@ int manager_run(Manager *m) {
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
Manager *m = NULL;
|
||||
int r = 0;
|
||||
int r;
|
||||
|
||||
log_set_target(LOG_TARGET_AUTO);
|
||||
log_parse_environment();
|
||||
|
@ -36,11 +36,12 @@
|
||||
*
|
||||
* recreate VTs when disallocated
|
||||
* udev rules
|
||||
* spawn user systemd
|
||||
* non-local X11 server
|
||||
* udev-acl
|
||||
* reboot/shutdown halt management
|
||||
* PAM rewrite
|
||||
* spawn user systemd
|
||||
* dbus API
|
||||
*
|
||||
* non-local X11 server
|
||||
* reboot/shutdown halt management
|
||||
*/
|
||||
|
||||
typedef struct Manager Manager;
|
||||
|
87
src/uaccess.c
Normal file
87
src/uaccess.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2011 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "logind-acl.h"
|
||||
#include "util.h"
|
||||
#include "log.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int r;
|
||||
const char *path, *seat;
|
||||
char *p, *active_uid = NULL;
|
||||
unsigned long ul;
|
||||
|
||||
log_set_target(LOG_TARGET_AUTO);
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
|
||||
if (argc != 2) {
|
||||
log_error("This program expects two argument.");
|
||||
r = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
path = argv[1];
|
||||
seat = argv[2];
|
||||
|
||||
p = strappend("/run/systemd/seat/", seat);
|
||||
if (!p) {
|
||||
log_error("Out of memory.");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = parse_env_file(p, NEWLINE,
|
||||
"ACTIVE_UID", &active_uid,
|
||||
NULL);
|
||||
free(p);
|
||||
|
||||
if (r < 0) {
|
||||
if (errno == ENOENT) {
|
||||
r = 0;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
log_error("Failed to read seat data for %s: %s", seat, strerror(-r));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = safe_atolu(active_uid, &ul);
|
||||
if (r < 0) {
|
||||
log_error("Failed to parse active UID value %s: %s", active_uid, strerror(-r));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = devnode_acl(path, true, false, 0, true, (uid_t) ul);
|
||||
if (r < 0) {
|
||||
log_error("Failed to apply ACL on %s: %s", path, strerror(-r));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
finish:
|
||||
free(active_uid);
|
||||
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user