mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
bus: add new sd_bus_creds object to encapsulate process credentials
This way we can unify handling of credentials that are attached to messages, or can be queried for bus name owners or connection peers. This also adds the ability to extend incomplete credential information with data from /proc, Also, provide a convenience call that will automatically determine the most appropriate credential object for an incoming message, by using the the attached information if possible, the sending name information if available and otherwise the peer's credentials.
This commit is contained in:
parent
70f75a523b
commit
5b12334d35
1
.gitignore
vendored
1
.gitignore
vendored
@ -90,6 +90,7 @@
|
||||
/tags
|
||||
/test-boot-timestamp
|
||||
/test-bus-chat
|
||||
/test-bus-creds
|
||||
/test-bus-error
|
||||
/test-bus-introspect
|
||||
/test-bus-kernel
|
||||
|
31
Makefile.am
31
Makefile.am
@ -769,7 +769,9 @@ libsystemd_shared_la_SOURCES = \
|
||||
src/shared/errno-list.c \
|
||||
src/shared/errno-list.h \
|
||||
src/shared/syscall-list.c \
|
||||
src/shared/syscall-list.h
|
||||
src/shared/syscall-list.h \
|
||||
src/shared/audit.c \
|
||||
src/shared/audit.h
|
||||
|
||||
nodist_libsystemd_shared_la_SOURCES = \
|
||||
src/shared/errno-from-name.h \
|
||||
@ -842,14 +844,6 @@ libsystemd_capability_la_CFLAGS = \
|
||||
libsystemd_capability_la_LIBADD = \
|
||||
$(CAP_LIBS)
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
noinst_LTLIBRARIES += \
|
||||
libsystemd-audit.la
|
||||
|
||||
libsystemd_audit_la_SOURCES = \
|
||||
src/shared/audit.c \
|
||||
src/shared/audit.h
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
if HAVE_ACL
|
||||
noinst_LTLIBRARIES += \
|
||||
@ -1013,7 +1007,6 @@ libsystemd_core_la_LIBADD = \
|
||||
libsystemd-capability.la \
|
||||
libsystemd-units.la \
|
||||
libsystemd-label.la \
|
||||
libsystemd-audit.la \
|
||||
libsystemd-id128-internal.la \
|
||||
libsystemd-daemon-internal.la \
|
||||
libudev-internal.la \
|
||||
@ -1957,6 +1950,8 @@ libsystemd_bus_la_SOURCES = \
|
||||
src/libsystemd-bus/bus-container.h \
|
||||
src/libsystemd-bus/bus-message.c \
|
||||
src/libsystemd-bus/bus-message.h \
|
||||
src/libsystemd-bus/bus-creds.c \
|
||||
src/libsystemd-bus/bus-creds.h \
|
||||
src/libsystemd-bus/bus-signature.c \
|
||||
src/libsystemd-bus/bus-signature.h \
|
||||
src/libsystemd-bus/bus-type.c \
|
||||
@ -2035,6 +2030,7 @@ tests += \
|
||||
test-bus-introspect \
|
||||
test-bus-objects \
|
||||
test-bus-error \
|
||||
test-bus-creds \
|
||||
test-event
|
||||
|
||||
bin_PROGRAMS += \
|
||||
@ -2119,6 +2115,17 @@ test_bus_error_LDADD = \
|
||||
libsystemd-daemon-internal.la \
|
||||
libsystemd-shared.la
|
||||
|
||||
test_bus_creds_SOURCES = \
|
||||
src/libsystemd-bus/test-bus-creds.c
|
||||
|
||||
test_bus_creds_LDADD = \
|
||||
libsystemd-bus-internal.la \
|
||||
libsystemd-id128-internal.la \
|
||||
libsystemd-daemon-internal.la \
|
||||
libsystemd-shared.la \
|
||||
libsystemd-bus-dump.la \
|
||||
libsystemd-capability.la
|
||||
|
||||
test_bus_match_SOURCES = \
|
||||
src/libsystemd-bus/test-bus-match.c
|
||||
|
||||
@ -3086,7 +3093,6 @@ nodist_libsystemd_journal_core_la_SOURCES = \
|
||||
libsystemd_journal_core_la_LIBADD = \
|
||||
libsystemd-journal-internal.la \
|
||||
libudev-internal.la \
|
||||
libsystemd-audit.la \
|
||||
libsystemd-capability.la \
|
||||
libsystemd-label.la \
|
||||
libsystemd-daemon-internal.la \
|
||||
@ -3778,7 +3784,6 @@ libsystemd_machine_core_la_SOURCES = \
|
||||
|
||||
libsystemd_machine_core_la_LIBADD = \
|
||||
libsystemd-label.la \
|
||||
libsystemd-audit.la \
|
||||
libsystemd-daemon-internal.la \
|
||||
libsystemd-bus-internal.la \
|
||||
libsystemd-id128-internal.la \
|
||||
@ -3933,7 +3938,6 @@ libsystemd_logind_core_la_SOURCES = \
|
||||
libsystemd_logind_core_la_LIBADD = \
|
||||
libsystemd-label.la \
|
||||
libsystemd-capability.la \
|
||||
libsystemd-audit.la \
|
||||
libsystemd-daemon-internal.la \
|
||||
libsystemd-id128-internal.la \
|
||||
libsystemd-bus-internal.la \
|
||||
@ -4073,7 +4077,6 @@ pam_systemd_la_LDFLAGS = \
|
||||
|
||||
pam_systemd_la_LIBADD = \
|
||||
libsystemd-capability.la \
|
||||
libsystemd-audit.la \
|
||||
libsystemd-bus-internal.la \
|
||||
libsystemd-id128-internal.la \
|
||||
libsystemd-daemon-internal.la \
|
||||
|
@ -338,7 +338,13 @@ static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *us
|
||||
return r;
|
||||
|
||||
if (pid == 0) {
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -247,9 +247,14 @@ static int selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata,
|
||||
}
|
||||
|
||||
if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
pid_t pid;
|
||||
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
@ -300,6 +305,7 @@ static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_
|
||||
assert(path);
|
||||
|
||||
if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
sd_bus_message *message;
|
||||
pid_t pid;
|
||||
|
||||
@ -307,9 +313,13 @@ static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_
|
||||
if (!message)
|
||||
return 0;
|
||||
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
u = manager_get_unit_by_pid(m, pid);
|
||||
} else {
|
||||
|
@ -41,91 +41,16 @@
|
||||
#include "audit.h"
|
||||
#include "selinux-util.h"
|
||||
#include "audit-fd.h"
|
||||
#include "strv.h"
|
||||
|
||||
static bool initialized = false;
|
||||
|
||||
struct auditstruct {
|
||||
struct audit_info {
|
||||
sd_bus_creds *creds;
|
||||
const char *path;
|
||||
char *cmdline;
|
||||
uid_t loginuid;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
const char *cmdline;
|
||||
};
|
||||
|
||||
static int bus_get_selinux_security_context(
|
||||
sd_bus *bus,
|
||||
const char *name,
|
||||
sd_bus_error *error,
|
||||
char **ret) {
|
||||
|
||||
_cleanup_bus_message_unref_ sd_bus_message *m = NULL;
|
||||
const void *p;
|
||||
size_t sz;
|
||||
char *b;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(name);
|
||||
assert(ret);
|
||||
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.DBus",
|
||||
"/org/freedesktop/DBus",
|
||||
"org.freedesktop.DBus",
|
||||
"GetConnectionSELinuxSecurityContext",
|
||||
error, &m,
|
||||
"s", name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read_array(m, 'y', &p, &sz);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
b = strndup(p, sz);
|
||||
if (!b)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = b;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bus_get_audit_data(
|
||||
sd_bus *bus,
|
||||
const char *name,
|
||||
struct auditstruct *audit) {
|
||||
|
||||
pid_t pid;
|
||||
int r;
|
||||
|
||||
assert(bus);
|
||||
assert(name);
|
||||
assert(audit);
|
||||
|
||||
r = sd_bus_get_owner_pid(bus, name, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = audit_loginuid_from_pid(pid, &audit->loginuid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = get_process_uid(pid, &audit->uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = get_process_gid(pid, &audit->gid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = get_process_cmdline(pid, 0, true, &audit->cmdline);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Any time an access gets denied this callback will be called
|
||||
with the aduit data. We then need to just copy the audit data into the msgbuf.
|
||||
@ -136,19 +61,19 @@ static int audit_callback(
|
||||
char *msgbuf,
|
||||
size_t msgbufsize) {
|
||||
|
||||
struct auditstruct *audit = (struct auditstruct *) auditdata;
|
||||
const struct audit_info *audit = auditdata;
|
||||
uid_t uid = 0, login_uid = 0;
|
||||
gid_t gid = 0;
|
||||
|
||||
sd_bus_creds_get_audit_login_uid(audit->creds, &login_uid);
|
||||
sd_bus_creds_get_uid(audit->creds, &uid);
|
||||
sd_bus_creds_get_gid(audit->creds, &gid);
|
||||
|
||||
snprintf(msgbuf, msgbufsize,
|
||||
"auid=%d uid=%d gid=%d%s%s%s%s%s%s",
|
||||
audit->loginuid,
|
||||
audit->uid,
|
||||
audit->gid,
|
||||
(audit->path ? " path=\"" : ""),
|
||||
strempty(audit->path),
|
||||
(audit->path ? "\"" : ""),
|
||||
(audit->cmdline ? " cmdline=\"" : ""),
|
||||
strempty(audit->cmdline),
|
||||
(audit->cmdline ? "\"" : ""));
|
||||
login_uid, uid, gid,
|
||||
audit->path ? " path=\"" : "", strempty(audit->path), audit->path ? "\"" : "",
|
||||
audit->cmdline ? " cmdline=\"" : "", strempty(audit->cmdline), audit->cmdline ? "\"" : "");
|
||||
|
||||
msgbuf[msgbufsize-1] = 0;
|
||||
|
||||
@ -164,13 +89,12 @@ static int audit_callback(
|
||||
_printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
#ifdef HAVE_AUDIT
|
||||
if (get_audit_fd() >= 0) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
int r;
|
||||
|
||||
va_start(ap, fmt);
|
||||
r = vasprintf(&buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
@ -178,10 +102,10 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
|
||||
audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
}
|
||||
#endif
|
||||
|
||||
va_start(ap, fmt);
|
||||
log_metav(LOG_USER | LOG_INFO, __FILE__, __LINE__, __FUNCTION__, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
@ -238,76 +162,6 @@ void selinux_access_free(void) {
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
static int get_audit_data(
|
||||
sd_bus *bus,
|
||||
sd_bus_message *message,
|
||||
struct auditstruct *audit) {
|
||||
|
||||
struct ucred ucred;
|
||||
const char *sender;
|
||||
socklen_t len;
|
||||
int r, fd;
|
||||
|
||||
sender = sd_bus_message_get_sender(message);
|
||||
if (sender)
|
||||
return bus_get_audit_data(bus, sender, audit);
|
||||
|
||||
fd = sd_bus_get_fd(bus);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
len = sizeof(ucred);
|
||||
r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
audit->uid = ucred.uid;
|
||||
audit->gid = ucred.gid;
|
||||
|
||||
r = audit_loginuid_from_pid(ucred.pid, &audit->loginuid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = get_process_cmdline(ucred.pid, 0, true, &audit->cmdline);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
This function returns the security context of the remote end of the dbus
|
||||
connections. Whether it is on the bus or a local connection.
|
||||
*/
|
||||
static int get_calling_context(
|
||||
sd_bus *bus,
|
||||
sd_bus_message *message,
|
||||
sd_bus_error *error,
|
||||
security_context_t *ret) {
|
||||
|
||||
const char *sender;
|
||||
int r, fd;
|
||||
|
||||
/*
|
||||
If sender exists then
|
||||
if sender is NULL this indicates a local connection. Grab the fd
|
||||
from dbus and do an getpeercon to peers process context
|
||||
*/
|
||||
sender = sd_bus_message_get_sender(message);
|
||||
if (sender)
|
||||
return bus_get_selinux_security_context(bus, sender, error, ret);
|
||||
|
||||
fd = sd_bus_get_fd(bus);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
r = getpeercon(fd, ret);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
This function communicates with the kernel to check whether or not it should
|
||||
allow the access.
|
||||
@ -321,9 +175,12 @@ int selinux_generic_access_check(
|
||||
const char *permission,
|
||||
sd_bus_error *error) {
|
||||
|
||||
security_context_t scon = NULL, fcon = NULL;
|
||||
const char *tclass = NULL;
|
||||
struct auditstruct audit;
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
const char *tclass = NULL, *scon = NULL;
|
||||
struct audit_info audit_info = {};
|
||||
_cleanup_free_ char *cl = NULL;
|
||||
security_context_t fcon = NULL;
|
||||
char **cmdline = NULL;
|
||||
int r = 0;
|
||||
|
||||
assert(bus);
|
||||
@ -338,12 +195,16 @@ int selinux_generic_access_check(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
audit.uid = audit.loginuid = (uid_t) -1;
|
||||
audit.gid = (gid_t) -1;
|
||||
audit.cmdline = NULL;
|
||||
audit.path = path;
|
||||
r = sd_bus_query_sender_creds(
|
||||
message,
|
||||
SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|
|
||||
SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_AUDIT_LOGIN_UID|
|
||||
SD_BUS_CREDS_SELINUX_CONTEXT,
|
||||
&creds);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
r = get_calling_context(bus, message, error, &scon);
|
||||
r = sd_bus_creds_get_selinux_context(creds, &scon);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
@ -367,21 +228,23 @@ int selinux_generic_access_check(
|
||||
tclass = "system";
|
||||
}
|
||||
|
||||
get_audit_data(bus, message, &audit);
|
||||
sd_bus_creds_get_cmdline(creds, &cmdline);
|
||||
cl = strv_join(cmdline, " ");
|
||||
|
||||
errno = 0;
|
||||
r = selinux_check_access(scon, fcon, tclass, permission, &audit);
|
||||
audit_info.creds = creds;
|
||||
audit_info.path = path;
|
||||
audit_info.cmdline = cl;
|
||||
|
||||
r = selinux_check_access((security_context_t) scon, fcon, tclass, permission, &audit_info);
|
||||
if (r < 0)
|
||||
r = sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "SELinux policy denies access.");
|
||||
|
||||
log_debug("SELinux access check scon=%s tcon=%s tclass=%s perm=%s path=%s cmdline=%s: %i", scon, fcon, tclass, permission, path, audit.cmdline, r);
|
||||
log_debug("SELinux access check scon=%s tcon=%s tclass=%s perm=%s path=%s cmdline=%s: %i", scon, fcon, tclass, permission, path, cl, r);
|
||||
|
||||
finish:
|
||||
free(audit.cmdline);
|
||||
freecon(scon);
|
||||
freecon(fcon);
|
||||
|
||||
if (r && security_getenforce() != 1) {
|
||||
if (r < 0 && security_getenforce() != 1) {
|
||||
sd_bus_error_free(error);
|
||||
r = 0;
|
||||
}
|
||||
|
@ -3673,11 +3673,14 @@ static void service_bus_name_owner_change(
|
||||
s->state == SERVICE_RUNNING ||
|
||||
s->state == SERVICE_RELOAD)) {
|
||||
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
pid_t pid;
|
||||
|
||||
/* Try to acquire PID from bus service */
|
||||
|
||||
r = sd_bus_get_owner_pid(u->manager->api_bus, name, &pid);
|
||||
r = sd_bus_get_owner_creds(u->manager->api_bus, name, SD_BUS_CREDS_PID, &creds);
|
||||
if (r >= 0)
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r >= 0) {
|
||||
log_debug_unit(u->id, "%s's D-Bus name %s is now owned by process %u", u->id, name, (unsigned) pid);
|
||||
|
||||
|
@ -260,80 +260,114 @@ _public_ int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_get_owner_uid(sd_bus *bus, const char *name, uid_t *uid) {
|
||||
_public_ int sd_bus_get_owner_creds(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **creds) {
|
||||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||
uint32_t u;
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
|
||||
pid_t pid = 0;
|
||||
int r;
|
||||
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
if (!name)
|
||||
return -EINVAL;
|
||||
if (!uid)
|
||||
return -EINVAL;
|
||||
if (!BUS_IS_OPEN(bus->state))
|
||||
return -ENOTCONN;
|
||||
if (bus_pid_changed(bus))
|
||||
return -ECHILD;
|
||||
assert_return(bus, -EINVAL);
|
||||
assert_return(name, -EINVAL);
|
||||
assert_return(mask <= _SD_BUS_CREDS_MAX, -ENOTSUP);
|
||||
assert_return(creds, -EINVAL);
|
||||
assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
|
||||
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.DBus",
|
||||
"/",
|
||||
"org.freedesktop.DBus",
|
||||
"GetConnectionUnixUser",
|
||||
NULL,
|
||||
&reply,
|
||||
"s",
|
||||
name);
|
||||
c = bus_creds_new();
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
if ((mask & SD_BUS_CREDS_PID) ||
|
||||
mask & ~(SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|SD_BUS_CREDS_SELINUX_CONTEXT)) {
|
||||
uint32_t u;
|
||||
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.DBus",
|
||||
"/",
|
||||
"org.freedesktop.DBus",
|
||||
"GetConnectionUnixProcessID",
|
||||
NULL,
|
||||
&reply,
|
||||
"s",
|
||||
name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read(reply, "u", &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
pid = u;
|
||||
if (mask & SD_BUS_CREDS_PID) {
|
||||
c->pid = u;
|
||||
c->mask |= SD_BUS_CREDS_PID;
|
||||
}
|
||||
|
||||
reply = sd_bus_message_unref(reply);
|
||||
}
|
||||
|
||||
if (mask & SD_BUS_CREDS_UID) {
|
||||
uint32_t u;
|
||||
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.DBus",
|
||||
"/",
|
||||
"org.freedesktop.DBus",
|
||||
"GetConnectionUnixUser",
|
||||
NULL,
|
||||
&reply,
|
||||
"s",
|
||||
name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read(reply, "u", &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->uid = u;
|
||||
c->mask |= SD_BUS_CREDS_UID;
|
||||
|
||||
reply = sd_bus_message_unref(reply);
|
||||
}
|
||||
|
||||
if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
|
||||
const void *p;
|
||||
size_t sz;
|
||||
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.DBus",
|
||||
"/",
|
||||
"org.freedesktop.DBus",
|
||||
"GetConnectionSELinuxSecurityContext",
|
||||
NULL,
|
||||
&reply,
|
||||
"s",
|
||||
name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read_array(reply, 'y', &p, &sz);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->label = strndup(p, sz);
|
||||
if (!c->label)
|
||||
return -ENOMEM;
|
||||
|
||||
c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
|
||||
}
|
||||
|
||||
r = bus_creds_add_more(c, mask, pid, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read(reply, "u", &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
*creds = c;
|
||||
c = NULL;
|
||||
|
||||
*uid = (uid_t) u;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_get_owner_pid(sd_bus *bus, const char *name, pid_t *pid) {
|
||||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||
uint32_t u;
|
||||
int r;
|
||||
|
||||
if (!bus)
|
||||
return -EINVAL;
|
||||
if (!name)
|
||||
return -EINVAL;
|
||||
if (!pid)
|
||||
return -EINVAL;
|
||||
if (!BUS_IS_OPEN(bus->state))
|
||||
return -ENOTCONN;
|
||||
if (bus_pid_changed(bus))
|
||||
return -ECHILD;
|
||||
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
"org.freedesktop.DBus",
|
||||
"/",
|
||||
"org.freedesktop.DBus",
|
||||
"GetConnectionUnixProcessID",
|
||||
NULL,
|
||||
&reply,
|
||||
"s",
|
||||
name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_read(reply, "u", &u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (u == 0)
|
||||
return -EIO;
|
||||
|
||||
*pid = (uid_t) u;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -410,3 +410,33 @@ _public_ int sd_bus_set_property(
|
||||
|
||||
return sd_bus_call(bus, m, 0, error, NULL);
|
||||
}
|
||||
|
||||
_public_ int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **creds) {
|
||||
sd_bus_creds *c;
|
||||
|
||||
assert_return(call, -EINVAL);
|
||||
assert_return(call->sealed, -EPERM);
|
||||
assert_return(call->bus && BUS_IS_OPEN(call->bus->state), -ENOTCONN);
|
||||
assert_return(!bus_pid_changed(call->bus), -ECHILD);
|
||||
|
||||
c = sd_bus_message_get_creds(call);
|
||||
|
||||
/* All data we need? */
|
||||
if (c && (mask & ~c->mask) == 0) {
|
||||
*creds = sd_bus_creds_ref(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No data passed? Or not enough data passed to retrieve the missing bits? */
|
||||
if (!c || !(c->mask & SD_BUS_CREDS_PID)) {
|
||||
/* We couldn't read anything from the call, let's try
|
||||
* to get it from the sender or peer */
|
||||
|
||||
if (call->sender)
|
||||
return sd_bus_get_owner_creds(call->bus, call->sender, mask, creds);
|
||||
else
|
||||
return sd_bus_get_peer_creds(call->bus, mask, creds);
|
||||
}
|
||||
|
||||
return sd_bus_creds_extend(c, mask, creds);
|
||||
}
|
||||
|
796
src/libsystemd-bus/bus-creds.c
Normal file
796
src/libsystemd-bus/bus-creds.c
Normal file
@ -0,0 +1,796 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2013 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "fileio.h"
|
||||
#include "audit.h"
|
||||
#include "bus-message.h"
|
||||
#include "bus-util.h"
|
||||
#include "time-util.h"
|
||||
#include "bus-creds.h"
|
||||
|
||||
enum {
|
||||
CAP_OFFSET_INHERITABLE = 0,
|
||||
CAP_OFFSET_PERMITTED = 1,
|
||||
CAP_OFFSET_EFFECTIVE = 2,
|
||||
CAP_OFFSET_BOUNDING = 3
|
||||
};
|
||||
|
||||
void bus_creds_done(sd_bus_creds *c) {
|
||||
assert(c);
|
||||
|
||||
/* For internal bus cred structures that are allocated by
|
||||
* something else */
|
||||
|
||||
free(c->session);
|
||||
free(c->unit);
|
||||
free(c->user_unit);
|
||||
free(c->slice);
|
||||
|
||||
free(c->cmdline_array);
|
||||
}
|
||||
|
||||
_public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
|
||||
assert_return(c, NULL);
|
||||
|
||||
if (c->allocated) {
|
||||
assert(c->n_ref > 0);
|
||||
c->n_ref++;
|
||||
} else {
|
||||
sd_bus_message *m;
|
||||
|
||||
/* If this is an embedded creds structure, then
|
||||
* forward ref counting to the message */
|
||||
m = container_of(c, sd_bus_message, creds);
|
||||
sd_bus_message_ref(m);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
_public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
|
||||
assert_return(c, NULL);
|
||||
|
||||
if (c->allocated) {
|
||||
assert(c->n_ref > 0);
|
||||
c->n_ref--;
|
||||
|
||||
if (c->n_ref == 0) {
|
||||
bus_creds_done(c);
|
||||
|
||||
free(c->comm);
|
||||
free(c->tid_comm);
|
||||
free(c->exe);
|
||||
free(c->cmdline);
|
||||
free(c->cgroup);
|
||||
free(c->capability);
|
||||
free(c->label);
|
||||
free(c);
|
||||
}
|
||||
} else {
|
||||
sd_bus_message *m;
|
||||
|
||||
m = container_of(c, sd_bus_message, creds);
|
||||
sd_bus_message_unref(m);
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_public_ uint64_t sd_bus_creds_get_mask(sd_bus_creds *c) {
|
||||
assert_return(c, 0);
|
||||
|
||||
return c->mask;
|
||||
}
|
||||
|
||||
sd_bus_creds* bus_creds_new(void) {
|
||||
sd_bus_creds *c;
|
||||
|
||||
c = new0(sd_bus_creds, 1);
|
||||
if (!c)
|
||||
return NULL;
|
||||
|
||||
c->allocated = true;
|
||||
c->n_ref = 1;
|
||||
return c;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_new_from_pid(pid_t pid, uint64_t mask, sd_bus_creds **ret) {
|
||||
sd_bus_creds *c;
|
||||
int r;
|
||||
|
||||
assert_return(pid >= 0, -EINVAL);
|
||||
assert_return(mask <= _SD_BUS_CREDS_MAX, -ENOTSUP);
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
if (pid == 0)
|
||||
pid = getpid();
|
||||
|
||||
c = bus_creds_new();
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
r = bus_creds_add_more(c, mask, pid, 0);
|
||||
if (r < 0) {
|
||||
free(c);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Check if the process existed at all, in case we haven't
|
||||
* figured that out already */
|
||||
if (kill(pid, 0) < 0 && errno == ESRCH) {
|
||||
sd_bus_creds_unref(c);
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
*ret = c;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(uid, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_UID, -ENODATA);
|
||||
|
||||
*uid = c->uid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(gid, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_UID, -ENODATA);
|
||||
|
||||
*gid = c->gid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(pid, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_PID, -ENODATA);
|
||||
|
||||
assert(c->pid > 0);
|
||||
*pid = c->pid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(tid, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_TID, -ENODATA);
|
||||
|
||||
assert(c->tid > 0);
|
||||
*tid = c->tid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_pid_starttime(sd_bus_creds *c, uint64_t *usec) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(usec, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_PID_STARTTIME, -ENODATA);
|
||||
|
||||
assert(c->pid_starttime > 0);
|
||||
*usec = c->pid_starttime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT, -ENODATA);
|
||||
|
||||
assert(c->label);
|
||||
*ret = c->label;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_COMM, -ENODATA);
|
||||
|
||||
assert(c->comm);
|
||||
*ret = c->comm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_TID_COMM, -ENODATA);
|
||||
|
||||
assert(c->tid_comm);
|
||||
*ret = c->tid_comm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_EXE, -ENODATA);
|
||||
|
||||
assert(c->exe);
|
||||
*ret = c->exe;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_CGROUP, -ENODATA);
|
||||
|
||||
assert(c->cgroup);
|
||||
*ret = c->cgroup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
|
||||
int r;
|
||||
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_UNIT, -ENODATA);
|
||||
|
||||
assert(c->cgroup);
|
||||
|
||||
if (!c->unit) {
|
||||
r = cg_path_get_unit(c->cgroup, (char**) &c->unit);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = c->unit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
|
||||
int r;
|
||||
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_USER_UNIT, -ENODATA);
|
||||
|
||||
assert(c->cgroup);
|
||||
|
||||
if (!c->user_unit) {
|
||||
r = cg_path_get_user_unit(c->cgroup, (char**) &c->user_unit);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = c->user_unit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
|
||||
int r;
|
||||
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_SLICE, -ENODATA);
|
||||
|
||||
assert(c->cgroup);
|
||||
|
||||
if (!c->slice) {
|
||||
r = cg_path_get_slice(c->cgroup, (char**) &c->slice);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = c->slice;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
|
||||
int r;
|
||||
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_SESSION, -ENODATA);
|
||||
|
||||
assert(c->cgroup);
|
||||
|
||||
if (!c->session) {
|
||||
r = cg_path_get_session(c->cgroup, (char**) &c->session);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = c->session;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(uid, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_OWNER_UID, -ENODATA);
|
||||
|
||||
assert(c->cgroup);
|
||||
|
||||
return cg_path_get_owner_uid(c->cgroup, uid);
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
|
||||
size_t n, i;
|
||||
const char *p;
|
||||
bool first;
|
||||
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(c->cmdline, -ESRCH);
|
||||
assert_return(c->mask & SD_BUS_CREDS_CMDLINE, -ENODATA);
|
||||
|
||||
assert(c->cmdline);
|
||||
|
||||
for (p = c->cmdline, n = 0; p < c->cmdline + c->cmdline_length; p++)
|
||||
if (*p == 0)
|
||||
n++;
|
||||
|
||||
*(char***) &c->cmdline_array = new(char*, n + 1);
|
||||
if (!c->cmdline_array)
|
||||
return -ENOMEM;
|
||||
|
||||
for (p = c->cmdline, i = 0, first = true; p < c->cmdline + c->cmdline_length; p++) {
|
||||
if (first)
|
||||
c->cmdline_array[i++] = (char*) p;
|
||||
|
||||
first = *p == 0;
|
||||
}
|
||||
|
||||
c->cmdline_array[i] = NULL;
|
||||
*cmdline = c->cmdline_array;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(sessionid, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID, -ENODATA);
|
||||
|
||||
*sessionid = c->audit_session_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(uid, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID, -ENODATA);
|
||||
|
||||
*uid = c->audit_login_uid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
|
||||
size_t sz;
|
||||
|
||||
assert(c);
|
||||
assert(c->capability);
|
||||
|
||||
sz = c->capability_size / 4;
|
||||
if ((size_t) capability >= sz*8)
|
||||
return 0;
|
||||
|
||||
return !!(c->capability[offset * sz + (capability / 8)] & (1 << (capability % 8)));
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(capability >= 0, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS, -ENODATA);
|
||||
|
||||
return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(capability >= 0, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_PERMITTED_CAPS, -ENODATA);
|
||||
|
||||
return has_cap(c, CAP_OFFSET_PERMITTED, capability);
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(capability >= 0, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS, -ENODATA);
|
||||
|
||||
return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(capability >= 0, -EINVAL);
|
||||
assert_return(c->mask & SD_BUS_CREDS_BOUNDING_CAPS, -ENODATA);
|
||||
|
||||
return has_cap(c, CAP_OFFSET_BOUNDING, capability);
|
||||
}
|
||||
|
||||
static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
|
||||
size_t sz;
|
||||
unsigned i;
|
||||
|
||||
assert(c);
|
||||
assert(p);
|
||||
|
||||
p += strspn(p, WHITESPACE);
|
||||
|
||||
sz = strlen(p);
|
||||
if (sz % 2 != 0)
|
||||
return -EINVAL;
|
||||
|
||||
sz /= 2;
|
||||
if (!c->capability) {
|
||||
c->capability = new0(uint8_t, sz * 4);
|
||||
if (!c->capability)
|
||||
return -ENOMEM;
|
||||
|
||||
c->capability_size = sz * 4;
|
||||
}
|
||||
|
||||
for (i = 0; i < sz; i ++) {
|
||||
int x, y;
|
||||
|
||||
x = unhexchar(p[i*2]);
|
||||
y = unhexchar(p[i*2+1]);
|
||||
|
||||
if (x < 0 || y < 0)
|
||||
return -EINVAL;
|
||||
|
||||
c->capability[offset * sz + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
|
||||
uint64_t missing;
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
assert(c->allocated);
|
||||
|
||||
missing = mask & ~c->mask;
|
||||
if (missing == 0)
|
||||
return 0;
|
||||
|
||||
/* Try to retrieve PID from creds if it wasn't passed to us */
|
||||
if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
|
||||
pid = c->pid;
|
||||
|
||||
if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
|
||||
tid = c->pid;
|
||||
|
||||
/* Without pid we cannot do much... */
|
||||
if (pid <= 0)
|
||||
return 0;
|
||||
|
||||
if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID |
|
||||
SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
|
||||
SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
|
||||
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
char line[LINE_MAX];
|
||||
const char *p;
|
||||
|
||||
p = procfs_file_alloca(pid, "status");
|
||||
|
||||
f = fopen(p, "re");
|
||||
if (!f)
|
||||
return errno == ENOENT ? -ESRCH : -errno;
|
||||
|
||||
FOREACH_LINE(line, f, return -errno) {
|
||||
truncate_nl(line);
|
||||
|
||||
if (missing & SD_BUS_CREDS_UID) {
|
||||
p = startswith(line, "Uid:");
|
||||
if (p) {
|
||||
unsigned long uid;
|
||||
|
||||
p += strspn(p, WHITESPACE);
|
||||
if (sscanf(p, "%lu", &uid) != 1)
|
||||
return -EIO;
|
||||
|
||||
c->uid = (uid_t) uid;
|
||||
c->mask |= SD_BUS_CREDS_UID;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_GID) {
|
||||
p = startswith(line, "Gid:");
|
||||
if (p) {
|
||||
unsigned long gid;
|
||||
|
||||
p += strspn(p, WHITESPACE);
|
||||
if (sscanf(p, "%lu", &gid) != 1)
|
||||
return -EIO;
|
||||
|
||||
c->gid = (uid_t) gid;
|
||||
c->mask |= SD_BUS_CREDS_GID;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
|
||||
p = startswith(line, "CapEff:");
|
||||
if (p) {
|
||||
r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
|
||||
p = startswith(line, "CapPrm:");
|
||||
if (p) {
|
||||
r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
|
||||
p = startswith(line, "CapInh:");
|
||||
if (p) {
|
||||
r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
|
||||
p = startswith(line, "CapBnd:");
|
||||
if (p) {
|
||||
r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (missing & (SD_BUS_CREDS_PID_STARTTIME)) {
|
||||
unsigned long long st;
|
||||
|
||||
r = get_starttime_of_pid(pid, &st);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->pid_starttime = ((usec_t) st * USEC_PER_SEC) / (usec_t) sysconf(_SC_CLK_TCK);
|
||||
c->mask |= SD_BUS_CREDS_PID_STARTTIME;
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
|
||||
const char *p;
|
||||
|
||||
p = procfs_file_alloca(pid, "attr/current");
|
||||
r = read_one_line_file(p, &c->label);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
return r;
|
||||
else if (r >= 0)
|
||||
c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_COMM) {
|
||||
r = get_process_comm(pid, &c->comm);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->mask |= SD_BUS_CREDS_COMM;
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_EXE) {
|
||||
r = get_process_exe(pid, &c->exe);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->mask |= SD_BUS_CREDS_EXE;
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_CMDLINE) {
|
||||
const char *p;
|
||||
|
||||
p = procfs_file_alloca(pid, "cmdline");
|
||||
r = read_full_file(p, &c->cmdline, &c->cmdline_length);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (c->cmdline_length == 0) {
|
||||
free(c->cmdline);
|
||||
c->cmdline = NULL;
|
||||
} else
|
||||
c->mask |= SD_BUS_CREDS_CMDLINE;
|
||||
}
|
||||
|
||||
if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
||||
if (asprintf(&p, "/proc/%lu/task/%lu/comm", (unsigned long) pid, (unsigned long) tid) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = read_one_line_file(p, &c->tid_comm);
|
||||
if (r < 0)
|
||||
return r == -ENOENT ? -ESRCH : r;
|
||||
|
||||
c->mask |= SD_BUS_CREDS_TID_COMM;
|
||||
}
|
||||
|
||||
if (missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID)) {
|
||||
|
||||
r = cg_pid_get_path(NULL, pid, &c->cgroup);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
c->mask |= missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID);
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
|
||||
r = audit_session_from_pid(pid, &c->audit_session_id);
|
||||
if (r < 0 && r != -ENOTSUP && r != -ENXIO && r != ENOENT)
|
||||
return r;
|
||||
else if (r >= 0)
|
||||
c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
|
||||
}
|
||||
|
||||
if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
|
||||
r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
|
||||
if (r < 0 && r != -ENOTSUP && r != -ENXIO && r != ENOENT)
|
||||
return r;
|
||||
else if (r >= 0)
|
||||
c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_creds_extend(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
|
||||
int r;
|
||||
|
||||
assert_return(c, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
if ((mask & ~c->mask) == 0) {
|
||||
/* There's already all data we need. */
|
||||
|
||||
*ret = sd_bus_creds_ref(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = bus_creds_new();
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Copy the original data over */
|
||||
|
||||
if (c->mask & mask & SD_BUS_CREDS_UID) {
|
||||
n->uid = c->uid;
|
||||
n->mask |= SD_BUS_CREDS_UID;
|
||||
}
|
||||
|
||||
if (c->mask & mask & SD_BUS_CREDS_GID) {
|
||||
n->gid = c->gid;
|
||||
n->mask |= SD_BUS_CREDS_GID;
|
||||
}
|
||||
|
||||
if (c->mask & mask & SD_BUS_CREDS_PID) {
|
||||
n->pid = c->pid;
|
||||
n->mask |= SD_BUS_CREDS_PID;
|
||||
}
|
||||
|
||||
if (c->mask & mask & SD_BUS_CREDS_TID) {
|
||||
n->tid = c->tid;
|
||||
n->mask |= SD_BUS_CREDS_TID;
|
||||
}
|
||||
|
||||
if (c->mask & mask & SD_BUS_CREDS_PID_STARTTIME) {
|
||||
n->pid_starttime = c->pid_starttime;
|
||||
n->mask |= SD_BUS_CREDS_PID_STARTTIME;
|
||||
}
|
||||
|
||||
if (c->mask & mask & SD_BUS_CREDS_COMM) {
|
||||
n->comm = strdup(c->comm);
|
||||
if (!n->comm)
|
||||
return -ENOMEM;
|
||||
|
||||
n->mask |= SD_BUS_CREDS_COMM;
|
||||
}
|
||||
|
||||
if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
|
||||
n->tid_comm = strdup(c->tid_comm);
|
||||
if (!n->tid_comm)
|
||||
return -ENOMEM;
|
||||
|
||||
n->mask |= SD_BUS_CREDS_TID_COMM;
|
||||
}
|
||||
|
||||
if (c->mask & mask & SD_BUS_CREDS_EXE) {
|
||||
n->exe = strdup(c->exe);
|
||||
if (!n->exe)
|
||||
return -ENOMEM;
|
||||
|
||||
n->mask |= SD_BUS_CREDS_EXE;
|
||||
}
|
||||
|
||||
if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
|
||||
n->cmdline = memdup(c->cmdline, c->cmdline_length);
|
||||
if (!n->cmdline)
|
||||
return -ENOMEM;
|
||||
|
||||
n->cmdline_length = c->cmdline_length;
|
||||
n->mask |= SD_BUS_CREDS_CMDLINE;
|
||||
}
|
||||
|
||||
if (c->mask & mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_OWNER_UID)) {
|
||||
n->cgroup = strdup(c->cgroup);
|
||||
if (!n->cgroup)
|
||||
return -ENOMEM;
|
||||
|
||||
n->mask |= mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_OWNER_UID);
|
||||
}
|
||||
|
||||
if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
|
||||
n->capability = memdup(c->capability, c->capability_size);
|
||||
if (!n->capability)
|
||||
return -ENOMEM;
|
||||
|
||||
n->capability_size = c->capability_size;
|
||||
n->mask |= c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS);
|
||||
}
|
||||
|
||||
if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
|
||||
n->audit_session_id = c->audit_session_id;
|
||||
n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
|
||||
}
|
||||
|
||||
if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
|
||||
n->audit_login_uid = c->audit_login_uid;
|
||||
n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
|
||||
}
|
||||
|
||||
/* Get more data */
|
||||
|
||||
r = bus_creds_add_more(n, mask,
|
||||
c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
|
||||
c->mask & SD_BUS_CREDS_TID ? c->tid : 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = n;
|
||||
n = NULL;
|
||||
return 0;
|
||||
}
|
67
src/libsystemd-bus/bus-creds.h
Normal file
67
src/libsystemd-bus/bus-creds.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2013 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "time-util.h"
|
||||
|
||||
struct sd_bus_creds {
|
||||
bool allocated;
|
||||
unsigned n_ref;
|
||||
uint64_t mask;
|
||||
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
pid_t pid;
|
||||
usec_t pid_starttime;
|
||||
pid_t tid;
|
||||
|
||||
char *comm;
|
||||
char *tid_comm;
|
||||
char *exe;
|
||||
|
||||
char *cmdline;
|
||||
size_t cmdline_length;
|
||||
char **cmdline_array;
|
||||
|
||||
char *cgroup;
|
||||
char *session;
|
||||
char *unit;
|
||||
char *user_unit;
|
||||
char *slice;
|
||||
|
||||
uint8_t *capability;
|
||||
size_t capability_size;
|
||||
|
||||
uint32_t audit_session_id;
|
||||
uid_t audit_login_uid;
|
||||
|
||||
char *label;
|
||||
};
|
||||
|
||||
sd_bus_creds* bus_creds_new(void);
|
||||
|
||||
void bus_creds_done(sd_bus_creds *c);
|
||||
|
||||
int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid);
|
@ -24,6 +24,7 @@
|
||||
#include "util.h"
|
||||
#include "capability.h"
|
||||
#include "strv.h"
|
||||
#include "audit.h"
|
||||
|
||||
#include "bus-message.h"
|
||||
#include "bus-internal.h"
|
||||
@ -45,13 +46,8 @@ static char *indent(unsigned level) {
|
||||
}
|
||||
|
||||
int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
|
||||
const char *u = NULL, *uu = NULL, *s = NULL;
|
||||
char **cmdline = NULL;
|
||||
unsigned level = 1;
|
||||
int r;
|
||||
uid_t owner, audit_loginuid;
|
||||
uint32_t audit_sessionid;
|
||||
bool audit_sessionid_is_set = false, audit_loginuid_is_set = false;
|
||||
|
||||
assert(m);
|
||||
|
||||
@ -96,23 +92,6 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
|
||||
ansi_highlight_red(), strna(m->error.name), ansi_highlight_off(),
|
||||
ansi_highlight_red(), strna(m->error.message), ansi_highlight_off());
|
||||
|
||||
if (m->pid != 0)
|
||||
fprintf(f, " PID=%lu", (unsigned long) m->pid);
|
||||
if (m->pid_starttime != 0)
|
||||
fprintf(f, " PIDStartTime=%llu", (unsigned long long) m->pid_starttime);
|
||||
if (m->tid != 0)
|
||||
fprintf(f, " TID=%lu", (unsigned long) m->tid);
|
||||
if (m->uid_valid)
|
||||
fprintf(f, " UID=%lu", (unsigned long) m->uid);
|
||||
r = sd_bus_message_get_owner_uid(m, &owner);
|
||||
if (r >= 0)
|
||||
fprintf(f, " OwnerUID=%lu", (unsigned long) owner);
|
||||
if (m->gid_valid)
|
||||
fprintf(f, " GID=%lu", (unsigned long) m->gid);
|
||||
|
||||
if (m->pid != 0 || m->pid_starttime != 0 || m->tid != 0 || m->uid_valid || r >= 0 || m->gid_valid)
|
||||
fputs("\n", f);
|
||||
|
||||
if (m->monotonic != 0)
|
||||
fprintf(f, " Monotonic=%llu", (unsigned long long) m->monotonic);
|
||||
if (m->realtime != 0)
|
||||
@ -121,70 +100,7 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
|
||||
if (m->monotonic != 0 || m->realtime != 0)
|
||||
fputs("\n", f);
|
||||
|
||||
if (m->exe)
|
||||
fprintf(f, " Exe=%s", m->exe);
|
||||
if (m->comm)
|
||||
fprintf(f, " Comm=%s", m->comm);
|
||||
if (m->tid_comm)
|
||||
fprintf(f, " TIDComm=%s", m->tid_comm);
|
||||
if (m->label)
|
||||
fprintf(f, " Label=%s", m->label);
|
||||
|
||||
if (m->exe || m->comm || m->tid_comm || m->label)
|
||||
fputs("\n", f);
|
||||
|
||||
if (sd_bus_message_get_cmdline(m, &cmdline) >= 0) {
|
||||
char **c;
|
||||
|
||||
fputs(" CommandLine=[", f);
|
||||
STRV_FOREACH(c, cmdline) {
|
||||
if (c != cmdline)
|
||||
fputc(' ', f);
|
||||
|
||||
fputs(*c, f);
|
||||
}
|
||||
|
||||
fputs("]\n", f);
|
||||
}
|
||||
|
||||
if (m->cgroup)
|
||||
fprintf(f, " CGroup=%s\n", m->cgroup);
|
||||
|
||||
sd_bus_message_get_unit(m, &u);
|
||||
if (u)
|
||||
fprintf(f, " Unit=%s", u);
|
||||
sd_bus_message_get_user_unit(m, &uu);
|
||||
if (uu)
|
||||
fprintf(f, " UserUnit=%s", uu);
|
||||
sd_bus_message_get_session(m, &s);
|
||||
if (s)
|
||||
fprintf(f, " Session=%s", s);
|
||||
if (sd_bus_message_get_audit_loginuid(m, &audit_loginuid) >= 0) {
|
||||
audit_loginuid_is_set = true;
|
||||
fprintf(f, " AuditLoginUID=%lu", (unsigned long) audit_loginuid);
|
||||
}
|
||||
if (sd_bus_message_get_audit_sessionid(m, &audit_sessionid) >= 0) {
|
||||
audit_sessionid_is_set = true;
|
||||
fprintf(f, " AuditSessionID=%lu", (unsigned long) audit_sessionid);
|
||||
}
|
||||
|
||||
if (u || uu || s || audit_loginuid_is_set || audit_sessionid_is_set)
|
||||
fputs("\n", f);
|
||||
|
||||
r = sd_bus_message_has_effective_cap(m, 0);
|
||||
if (r >= 0) {
|
||||
unsigned long c, last_cap;
|
||||
|
||||
fprintf(f, " Capabilities=%s", r ? cap_to_name(0) : "");
|
||||
|
||||
last_cap = cap_last_cap();
|
||||
for (c = 0; c < last_cap; c++) {
|
||||
r = sd_bus_message_has_effective_cap(m, c);
|
||||
if (r > 0)
|
||||
fprintf(f, "|%s", cap_to_name(c));
|
||||
}
|
||||
fputs("\n", f);
|
||||
}
|
||||
bus_creds_dump(&m->creds, f);
|
||||
}
|
||||
|
||||
r = sd_bus_message_rewind(m, true);
|
||||
@ -333,3 +249,142 @@ int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header) {
|
||||
fprintf(f, " };\n\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dump_capabilities(
|
||||
sd_bus_creds *c,
|
||||
FILE *f,
|
||||
const char *name,
|
||||
int (*has)(sd_bus_creds *c, int capability)) {
|
||||
|
||||
unsigned long i, last_cap;
|
||||
unsigned n = 0;
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
assert(f);
|
||||
assert(name);
|
||||
assert(has);
|
||||
|
||||
i = 0;
|
||||
r = has(c, i);
|
||||
if (r < 0)
|
||||
return;
|
||||
|
||||
fprintf(f, " %s=", name);
|
||||
last_cap = cap_last_cap();
|
||||
|
||||
for (;;) {
|
||||
if (r > 0) {
|
||||
if (n > 0)
|
||||
fputc(' ', f);
|
||||
if (n % 4 == 3)
|
||||
fputs("\n ", f);
|
||||
|
||||
fputs(cap_to_name(i), f);
|
||||
n++;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
if (i > last_cap)
|
||||
break;
|
||||
|
||||
r = has(c, i);
|
||||
}
|
||||
|
||||
fputs("\n", f);
|
||||
}
|
||||
|
||||
int bus_creds_dump(sd_bus_creds *c, FILE *f) {
|
||||
bool audit_sessionid_is_set = false, audit_loginuid_is_set = false;
|
||||
const char *u = NULL, *uu = NULL, *s = NULL, *sl = NULL;
|
||||
uid_t owner, audit_loginuid;
|
||||
uint32_t audit_sessionid;
|
||||
char **cmdline = NULL;
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
if (!f)
|
||||
f = stdout;
|
||||
|
||||
if (c->mask & SD_BUS_CREDS_PID)
|
||||
fprintf(f, " PID=%lu", (unsigned long) c->pid);
|
||||
if (c->mask & SD_BUS_CREDS_PID_STARTTIME)
|
||||
fprintf(f, " PIDStartTime=%llu", (unsigned long long) c->pid_starttime);
|
||||
if (c->mask & SD_BUS_CREDS_TID)
|
||||
fprintf(f, " TID=%lu", (unsigned long) c->tid);
|
||||
if (c->mask & SD_BUS_CREDS_UID)
|
||||
fprintf(f, " UID=%lu", (unsigned long) c->uid);
|
||||
r = sd_bus_creds_get_owner_uid(c, &owner);
|
||||
if (r >= 0)
|
||||
fprintf(f, " OwnerUID=%lu", (unsigned long) owner);
|
||||
if (c->mask & SD_BUS_CREDS_GID)
|
||||
fprintf(f, " GID=%lu", (unsigned long) c->gid);
|
||||
|
||||
if ((c->mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID|SD_BUS_CREDS_UID|SD_BUS_CREDS_GID)) || r >= 0)
|
||||
fputs("\n", f);
|
||||
|
||||
if (c->mask & SD_BUS_CREDS_EXE)
|
||||
fprintf(f, " Exe=%s", c->exe);
|
||||
if (c->mask & SD_BUS_CREDS_COMM)
|
||||
fprintf(f, " Comm=%s", c->comm);
|
||||
if (c->mask & SD_BUS_CREDS_TID_COMM)
|
||||
fprintf(f, " TIDComm=%s", c->tid_comm);
|
||||
if (c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)
|
||||
fprintf(f, " Label=%s", c->label);
|
||||
|
||||
if (c->mask & (SD_BUS_CREDS_EXE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM|SD_BUS_CREDS_SELINUX_CONTEXT))
|
||||
fputs("\n", f);
|
||||
|
||||
if (sd_bus_creds_get_cmdline(c, &cmdline) >= 0) {
|
||||
char **i;
|
||||
|
||||
fputs(" CommandLine=", f);
|
||||
STRV_FOREACH(i, cmdline) {
|
||||
if (i != cmdline)
|
||||
fputc(' ', f);
|
||||
|
||||
fputs(*i, f);
|
||||
}
|
||||
|
||||
fputs("\n", f);
|
||||
}
|
||||
|
||||
if (c->mask & SD_BUS_CREDS_CGROUP)
|
||||
fprintf(f, " CGroup=%s", c->cgroup);
|
||||
sd_bus_creds_get_unit(c, &u);
|
||||
if (u)
|
||||
fprintf(f, " Unit=%s", u);
|
||||
sd_bus_creds_get_user_unit(c, &uu);
|
||||
if (uu)
|
||||
fprintf(f, " UserUnit=%s", uu);
|
||||
sd_bus_creds_get_slice(c, &sl);
|
||||
if (sl)
|
||||
fprintf(f, " Slice=%s", sl);
|
||||
sd_bus_creds_get_session(c, &s);
|
||||
if (s)
|
||||
fprintf(f, " Session=%s", s);
|
||||
|
||||
if ((c->mask & SD_BUS_CREDS_CGROUP) || u || uu || sl || s)
|
||||
fputs("\n", f);
|
||||
|
||||
if (sd_bus_creds_get_audit_login_uid(c, &audit_loginuid) >= 0) {
|
||||
audit_loginuid_is_set = true;
|
||||
fprintf(f, " AuditLoginUID=%lu", (unsigned long) audit_loginuid);
|
||||
}
|
||||
if (sd_bus_creds_get_audit_session_id(c, &audit_sessionid) >= 0) {
|
||||
audit_sessionid_is_set = true;
|
||||
fprintf(f, " AuditSessionID=%lu", (unsigned long) audit_sessionid);
|
||||
}
|
||||
|
||||
if (audit_loginuid_is_set || audit_sessionid_is_set)
|
||||
fputs("\n", f);
|
||||
|
||||
dump_capabilities(c, f, "EffectiveCapabilities", sd_bus_creds_has_effective_cap);
|
||||
dump_capabilities(c, f, "PermittedCapabilities", sd_bus_creds_has_permitted_cap);
|
||||
dump_capabilities(c, f, "InheritableCapabilities", sd_bus_creds_has_inheritable_cap);
|
||||
dump_capabilities(c, f, "BoundingCapabilities", sd_bus_creds_has_bounding_cap);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -27,3 +27,5 @@
|
||||
#include "sd-bus.h"
|
||||
|
||||
int bus_message_dump(sd_bus_message *m, FILE *f, bool with_header);
|
||||
|
||||
int bus_creds_dump(sd_bus_creds *c, FILE *f);
|
||||
|
@ -213,6 +213,8 @@ struct sd_bus {
|
||||
struct ucred ucred;
|
||||
char label[NAME_MAX];
|
||||
|
||||
uint64_t creds_mask;
|
||||
|
||||
int *fds;
|
||||
unsigned n_fds;
|
||||
|
||||
|
@ -548,31 +548,48 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k, sd_bus_mess
|
||||
idx += d->memfd.size;
|
||||
|
||||
} else if (d->type == KDBUS_MSG_SRC_CREDS) {
|
||||
m->pid_starttime = d->creds.starttime / NSEC_PER_USEC;
|
||||
m->uid = d->creds.uid;
|
||||
m->gid = d->creds.gid;
|
||||
m->pid = d->creds.pid;
|
||||
m->tid = d->creds.tid;
|
||||
m->uid_valid = m->gid_valid = true;
|
||||
m->creds.pid_starttime = d->creds.starttime / NSEC_PER_USEC;
|
||||
m->creds.uid = d->creds.uid;
|
||||
m->creds.gid = d->creds.gid;
|
||||
m->creds.pid = d->creds.pid;
|
||||
m->creds.tid = d->creds.tid;
|
||||
m->creds.mask |= (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID) & bus->creds_mask;
|
||||
|
||||
} else if (d->type == KDBUS_MSG_TIMESTAMP) {
|
||||
m->realtime = d->timestamp.realtime_ns / NSEC_PER_USEC;
|
||||
m->monotonic = d->timestamp.monotonic_ns / NSEC_PER_USEC;
|
||||
} else if (d->type == KDBUS_MSG_SRC_PID_COMM)
|
||||
m->comm = d->str;
|
||||
else if (d->type == KDBUS_MSG_SRC_TID_COMM)
|
||||
m->tid_comm = d->str;
|
||||
else if (d->type == KDBUS_MSG_SRC_EXE)
|
||||
m->exe = d->str;
|
||||
else if (d->type == KDBUS_MSG_SRC_CMDLINE) {
|
||||
m->cmdline = d->str;
|
||||
m->cmdline_length = l;
|
||||
} else if (d->type == KDBUS_MSG_SRC_CGROUP)
|
||||
m->cgroup = d->str;
|
||||
else if (d->type == KDBUS_MSG_SRC_AUDIT)
|
||||
m->audit = &d->audit;
|
||||
else if (d->type == KDBUS_MSG_SRC_CAPS) {
|
||||
m->capability = d->data;
|
||||
m->capability_size = l;
|
||||
|
||||
} else if (d->type == KDBUS_MSG_SRC_PID_COMM) {
|
||||
m->creds.comm = d->str;
|
||||
m->creds.mask |= SD_BUS_CREDS_COMM & bus->creds_mask;
|
||||
|
||||
} else if (d->type == KDBUS_MSG_SRC_TID_COMM) {
|
||||
m->creds.tid_comm = d->str;
|
||||
m->creds.mask |= SD_BUS_CREDS_TID_COMM & bus->creds_mask;
|
||||
|
||||
} else if (d->type == KDBUS_MSG_SRC_EXE) {
|
||||
m->creds.exe = d->str;
|
||||
m->creds.mask |= SD_BUS_CREDS_EXE & bus->creds_mask;
|
||||
|
||||
} else if (d->type == KDBUS_MSG_SRC_CMDLINE) {
|
||||
m->creds.cmdline = d->str;
|
||||
m->creds.cmdline_length = l;
|
||||
m->creds.mask |= SD_BUS_CREDS_CMDLINE & bus->creds_mask;
|
||||
|
||||
} else if (d->type == KDBUS_MSG_SRC_CGROUP) {
|
||||
m->creds.cgroup = d->str;
|
||||
m->creds.mask |= (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID) & bus->creds_mask;
|
||||
|
||||
} else if (d->type == KDBUS_MSG_SRC_AUDIT) {
|
||||
m->creds.audit_session_id = d->audit.sessionid;
|
||||
m->creds.audit_login_uid = d->audit.loginuid;
|
||||
m->creds.mask |= (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID) & bus->creds_mask;
|
||||
|
||||
} else if (d->type == KDBUS_MSG_SRC_CAPS) {
|
||||
m->creds.capability = d->data;
|
||||
m->creds.capability_size = l;
|
||||
m->creds.mask |= (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS) & bus->creds_mask;
|
||||
|
||||
} else if (d->type == KDBUS_MSG_DST_NAME)
|
||||
destination = d->str;
|
||||
else if (d->type != KDBUS_MSG_FDS &&
|
||||
|
@ -143,16 +143,12 @@ static void message_free(sd_bus_message *m) {
|
||||
if (m->iovec != m->iovec_fixed)
|
||||
free(m->iovec);
|
||||
|
||||
free(m->cmdline_array);
|
||||
|
||||
message_reset_containers(m);
|
||||
free(m->root_container.signature);
|
||||
|
||||
free(m->peeked_signature);
|
||||
|
||||
free(m->unit);
|
||||
free(m->user_unit);
|
||||
free(m->session);
|
||||
bus_creds_done(&m->creds);
|
||||
free(m);
|
||||
}
|
||||
|
||||
@ -358,15 +354,17 @@ int bus_message_from_header(
|
||||
m->n_fds = n_fds;
|
||||
|
||||
if (ucred) {
|
||||
m->uid = ucred->uid;
|
||||
m->pid = ucred->pid;
|
||||
m->gid = ucred->gid;
|
||||
m->uid_valid = m->gid_valid = true;
|
||||
m->creds.uid = ucred->uid;
|
||||
m->creds.pid = ucred->pid;
|
||||
m->creds.gid = ucred->gid;
|
||||
m->creds.mask |= SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID;
|
||||
}
|
||||
|
||||
if (label) {
|
||||
m->label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
|
||||
memcpy(m->label, label, label_sz + 1);
|
||||
m->creds.label = (char*) m + ALIGN(sizeof(sd_bus_message)) + ALIGN(extra);
|
||||
memcpy(m->creds.label, label, label_sz + 1);
|
||||
|
||||
m->creds.mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
|
||||
}
|
||||
|
||||
if (bus)
|
||||
@ -811,63 +809,10 @@ _public_ const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m) {
|
||||
return &m->error;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(uid, -EINVAL);
|
||||
assert_return(m->uid_valid, -ESRCH);
|
||||
|
||||
*uid = m->uid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(gid, -EINVAL);
|
||||
assert_return(m->gid_valid, -ESRCH);
|
||||
|
||||
*gid = m->gid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(pid, -EINVAL);
|
||||
assert_return(m->pid > 0, -ESRCH);
|
||||
|
||||
*pid = m->pid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(tid, -EINVAL);
|
||||
assert_return(m->tid > 0, -ESRCH);
|
||||
|
||||
*tid = m->tid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(usec, -EINVAL);
|
||||
assert_return(m->pid_starttime > 0, -ESRCH);
|
||||
|
||||
*usec = m->pid_starttime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **ret) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(m->label, -ESRCH);
|
||||
|
||||
*ret = m->label;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(usec, -EINVAL);
|
||||
assert_return(m->monotonic > 0, -ESRCH);
|
||||
assert_return(m->monotonic > 0, -ENODATA);
|
||||
|
||||
*usec = m->monotonic;
|
||||
return 0;
|
||||
@ -876,166 +821,19 @@ _public_ int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t
|
||||
_public_ int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(usec, -EINVAL);
|
||||
assert_return(m->realtime > 0, -ESRCH);
|
||||
assert_return(m->realtime > 0, -ENODATA);
|
||||
|
||||
*usec = m->realtime;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_comm(sd_bus_message *m, const char **ret) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(m->comm, -ESRCH);
|
||||
_public_ sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m) {
|
||||
assert_return(m, NULL);
|
||||
|
||||
*ret = m->comm;
|
||||
return 0;
|
||||
}
|
||||
if (m->creds.mask == 0)
|
||||
return NULL;
|
||||
|
||||
_public_ int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **ret) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(m->tid_comm, -ESRCH);
|
||||
|
||||
*ret = m->tid_comm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_exe(sd_bus_message *m, const char **ret) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(m->exe, -ESRCH);
|
||||
|
||||
*ret = m->exe;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_cgroup(sd_bus_message *m, const char **ret) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(m->cgroup, -ESRCH);
|
||||
|
||||
*ret = m->cgroup;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_unit(sd_bus_message *m, const char **ret) {
|
||||
int r;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(m->cgroup, -ESRCH);
|
||||
|
||||
if (!m->unit) {
|
||||
r = cg_path_get_unit(m->cgroup, &m->unit);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = m->unit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_user_unit(sd_bus_message *m, const char **ret) {
|
||||
int r;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(m->cgroup, -ESRCH);
|
||||
|
||||
if (!m->user_unit) {
|
||||
r = cg_path_get_user_unit(m->cgroup, &m->user_unit);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = m->user_unit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_session(sd_bus_message *m, const char **ret) {
|
||||
int r;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(m->cgroup, -ESRCH);
|
||||
|
||||
if (!m->session) {
|
||||
r = cg_path_get_session(m->cgroup, &m->session);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = m->session;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(uid, -EINVAL);
|
||||
assert_return(m->cgroup, -ESRCH);
|
||||
|
||||
return cg_path_get_owner_uid(m->cgroup, uid);
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline) {
|
||||
size_t n, i;
|
||||
const char *p;
|
||||
bool first;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(m->cmdline, -ESRCH);
|
||||
|
||||
for (p = m->cmdline, n = 0; p < m->cmdline + m->cmdline_length; p++)
|
||||
if (*p == 0)
|
||||
n++;
|
||||
|
||||
m->cmdline_array = new(char*, n + 1);
|
||||
if (!m->cmdline_array)
|
||||
return -ENOMEM;
|
||||
|
||||
for (p = m->cmdline, i = 0, first = true; p < m->cmdline + m->cmdline_length; p++) {
|
||||
if (first)
|
||||
m->cmdline_array[i++] = (char*) p;
|
||||
|
||||
first = *p == 0;
|
||||
}
|
||||
|
||||
m->cmdline_array[i] = NULL;
|
||||
*cmdline = m->cmdline_array;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(sessionid, -EINVAL);
|
||||
assert_return(m->audit, -ESRCH);
|
||||
|
||||
*sessionid = m->audit->sessionid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *uid) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(uid, -EINVAL);
|
||||
assert_return(m->audit, -ESRCH);
|
||||
|
||||
*uid = m->audit->loginuid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability) {
|
||||
unsigned sz;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(capability < 0, -EINVAL);
|
||||
assert_return(!m->capability, -ESRCH);
|
||||
|
||||
sz = m->capability_size / 4;
|
||||
if ((unsigned) capability >= sz*8)
|
||||
return 0;
|
||||
|
||||
return !!(m->capability[2 * sz + (capability / 8)] & (1 << (capability % 8)));
|
||||
return &m->creds;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_message_is_signal(sd_bus_message *m,
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "sd-bus.h"
|
||||
#include "kdbus.h"
|
||||
#include "time-util.h"
|
||||
#include "bus-creds.h"
|
||||
|
||||
struct bus_container {
|
||||
char enclosing;
|
||||
@ -78,19 +79,14 @@ struct sd_bus_message {
|
||||
|
||||
sd_bus_error error;
|
||||
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
pid_t pid;
|
||||
pid_t tid;
|
||||
usec_t pid_starttime;
|
||||
sd_bus_creds creds;
|
||||
|
||||
usec_t monotonic;
|
||||
usec_t realtime;
|
||||
|
||||
bool sealed:1;
|
||||
bool dont_send:1;
|
||||
bool allow_fds:1;
|
||||
bool uid_valid:1;
|
||||
bool gid_valid:1;
|
||||
bool free_header:1;
|
||||
bool free_kdbus:1;
|
||||
bool free_fds:1;
|
||||
@ -102,8 +98,6 @@ struct sd_bus_message {
|
||||
struct bus_body_part *body_end;
|
||||
unsigned n_body_parts;
|
||||
|
||||
char *label;
|
||||
|
||||
size_t rindex;
|
||||
struct bus_body_part *cached_rindex_part;
|
||||
size_t cached_rindex_part_begin;
|
||||
@ -126,24 +120,6 @@ struct sd_bus_message {
|
||||
|
||||
char sender_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1];
|
||||
char destination_buffer[3 + DECIMAL_STR_MAX(uint64_t) + 1];
|
||||
|
||||
const char *exe;
|
||||
const char *comm;
|
||||
const char *tid_comm;
|
||||
const char *cgroup;
|
||||
|
||||
const char *cmdline;
|
||||
size_t cmdline_length;
|
||||
char **cmdline_array;
|
||||
|
||||
char *session;
|
||||
char *unit;
|
||||
char *user_unit;
|
||||
|
||||
struct kdbus_audit *audit;
|
||||
|
||||
uint8_t *capability;
|
||||
size_t capability_size;
|
||||
};
|
||||
|
||||
#define BUS_MESSAGE_NEED_BSWAP(m) ((m)->header->endian != SD_BUS_NATIVE_ENDIAN)
|
||||
|
@ -20,6 +20,7 @@
|
||||
***/
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/capability.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "strv.h"
|
||||
@ -137,7 +138,7 @@ int bus_verify_polkit(
|
||||
bool *_challenge,
|
||||
sd_bus_error *e) {
|
||||
|
||||
const char *sender;
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
uid_t uid;
|
||||
int r;
|
||||
|
||||
@ -145,11 +146,11 @@ int bus_verify_polkit(
|
||||
assert(m);
|
||||
assert(action);
|
||||
|
||||
sender = sd_bus_message_get_sender(m);
|
||||
if (!sender)
|
||||
return -EBADMSG;
|
||||
r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_get_owner_uid(bus, sender, &uid);
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -160,6 +161,11 @@ int bus_verify_polkit(
|
||||
else {
|
||||
_cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
|
||||
int authorized = false, challenge = false;
|
||||
const char *sender;
|
||||
|
||||
sender = sd_bus_message_get_sender(m);
|
||||
if (!sender)
|
||||
return -EBADMSG;
|
||||
|
||||
r = sd_bus_call_method(
|
||||
bus,
|
||||
@ -271,8 +277,9 @@ int bus_verify_polkit_async(
|
||||
#ifdef ENABLE_POLKIT
|
||||
_cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
|
||||
AsyncPolkitQuery *q;
|
||||
#endif
|
||||
const char *sender;
|
||||
#endif
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
uid_t uid;
|
||||
int r;
|
||||
|
||||
@ -319,17 +326,21 @@ int bus_verify_polkit_async(
|
||||
}
|
||||
#endif
|
||||
|
||||
sender = sd_bus_message_get_sender(m);
|
||||
if (!sender)
|
||||
return -EBADMSG;
|
||||
r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_get_owner_uid(bus, sender, &uid);
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (uid == 0)
|
||||
return 1;
|
||||
|
||||
#ifdef ENABLE_POLKIT
|
||||
sender = sd_bus_message_get_sender(m);
|
||||
if (!sender)
|
||||
return -EBADMSG;
|
||||
|
||||
r = hashmap_ensure_allocated(registry, trivial_hash_func, trivial_compare_func);
|
||||
if (r < 0)
|
||||
|
@ -137,9 +137,11 @@ int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_unref);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_creds*, sd_bus_creds_unref);
|
||||
|
||||
#define _cleanup_bus_unref_ _cleanup_(sd_bus_unrefp)
|
||||
#define _cleanup_bus_message_unref_ _cleanup_(sd_bus_message_unrefp)
|
||||
#define _cleanup_bus_creds_unref_ _cleanup_(sd_bus_creds_unrefp)
|
||||
#define _cleanup_bus_error_free_ _cleanup_(sd_bus_error_free)
|
||||
|
||||
#define BUS_DEFINE_PROPERTY_GET_ENUM(function, name, type) \
|
||||
|
@ -75,41 +75,47 @@ static int list_bus_names(sd_bus *bus, char **argv) {
|
||||
(int) max_i, "NAME", 10, "PID", 15, "PROCESS", 16, "USER", 20, "CONNECTION");
|
||||
|
||||
STRV_FOREACH(i, l) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
_cleanup_free_ char *owner = NULL;
|
||||
sd_id128_t mid;
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
|
||||
if (arg_no_unique && (*i)[0] == ':')
|
||||
continue;
|
||||
|
||||
printf("%-*s", (int) max_i, *i);
|
||||
|
||||
r = sd_bus_get_owner_pid(bus, *i, &pid);
|
||||
r = sd_bus_get_owner_creds(bus, *i, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID|SD_BUS_CREDS_COMM, &creds);
|
||||
if (r >= 0) {
|
||||
_cleanup_free_ char *comm = NULL;
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
|
||||
printf(" %10lu", (unsigned long) pid);
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r >= 0) {
|
||||
const char *comm = NULL;
|
||||
|
||||
get_process_comm(pid, &comm);
|
||||
printf(" %-15s", strna(comm));
|
||||
sd_bus_creds_get_comm(creds, &comm);
|
||||
|
||||
printf(" %10lu %-15s", (unsigned long) pid, strna(comm));
|
||||
} else
|
||||
printf(" - - ");
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
if (r >= 0) {
|
||||
_cleanup_free_ char *u = NULL;
|
||||
|
||||
u = uid_to_name(uid);
|
||||
if (!u)
|
||||
return log_oom();
|
||||
|
||||
if (strlen(u) > 16)
|
||||
u[16] = 0;
|
||||
|
||||
printf(" %-16s", u);
|
||||
} else
|
||||
printf(" - ");
|
||||
} else
|
||||
printf(" - - ");
|
||||
printf(" - - - ");
|
||||
|
||||
r = sd_bus_get_owner_uid(bus, *i, &uid);
|
||||
if (r >= 0) {
|
||||
_cleanup_free_ char *u = NULL;
|
||||
|
||||
u = uid_to_name(uid);
|
||||
if (!u)
|
||||
return log_oom();
|
||||
|
||||
if (strlen(u) > 16)
|
||||
u[16] = 0;
|
||||
|
||||
printf(" %-16s", u);
|
||||
} else
|
||||
printf(" - ");
|
||||
|
||||
r = sd_bus_get_owner(bus, *i, &owner);
|
||||
if (r >= 0)
|
||||
|
@ -28,13 +28,6 @@ global:
|
||||
sd_bus_negotiate_fds;
|
||||
sd_bus_negotiate_attach_timestamp;
|
||||
sd_bus_negotiate_attach_creds;
|
||||
sd_bus_negotiate_attach_comm;
|
||||
sd_bus_negotiate_attach_exe;
|
||||
sd_bus_negotiate_attach_cmdline;
|
||||
sd_bus_negotiate_attach_cgroup;
|
||||
sd_bus_negotiate_attach_caps;
|
||||
sd_bus_negotiate_attach_selinux_context;
|
||||
sd_bus_negotiate_attach_audit;
|
||||
sd_bus_start;
|
||||
sd_bus_close;
|
||||
sd_bus_ref;
|
||||
@ -42,6 +35,7 @@ global:
|
||||
sd_bus_is_open;
|
||||
sd_bus_can_send;
|
||||
sd_bus_get_server_id;
|
||||
sd_bus_get_peer_creds;
|
||||
sd_bus_send;
|
||||
sd_bus_send_to;
|
||||
sd_bus_get_fd;
|
||||
@ -82,6 +76,7 @@ global:
|
||||
sd_bus_message_new_method_errnof;
|
||||
sd_bus_message_ref;
|
||||
sd_bus_message_unref;
|
||||
sd_bus_message_get_bus;
|
||||
sd_bus_message_get_type;
|
||||
sd_bus_message_get_serial;
|
||||
sd_bus_message_get_reply_serial;
|
||||
@ -95,27 +90,9 @@ global:
|
||||
sd_bus_message_get_sender;
|
||||
sd_bus_message_get_error;
|
||||
sd_bus_message_get_errno;
|
||||
sd_bus_message_get_bus;
|
||||
sd_bus_message_get_monotonic_timestamp;
|
||||
sd_bus_message_get_realtime_timestamp;
|
||||
sd_bus_message_get_uid;
|
||||
sd_bus_message_get_gid;
|
||||
sd_bus_message_get_pid;
|
||||
sd_bus_message_get_tid;
|
||||
sd_bus_message_get_pid_starttime;
|
||||
sd_bus_message_get_selinux_context;
|
||||
sd_bus_message_get_comm;
|
||||
sd_bus_message_get_tid_comm;
|
||||
sd_bus_message_get_exe;
|
||||
sd_bus_message_get_cgroup;
|
||||
sd_bus_message_get_cmdline;
|
||||
sd_bus_message_get_unit;
|
||||
sd_bus_message_get_user_unit;
|
||||
sd_bus_message_get_session;
|
||||
sd_bus_message_get_owner_uid;
|
||||
sd_bus_message_get_audit_sessionid;
|
||||
sd_bus_message_get_audit_loginuid;
|
||||
sd_bus_message_has_effective_cap;
|
||||
sd_bus_message_get_creds;
|
||||
sd_bus_message_is_signal;
|
||||
sd_bus_message_is_method_call;
|
||||
sd_bus_message_is_method_error;
|
||||
@ -147,6 +124,15 @@ global:
|
||||
sd_bus_message_at_end;
|
||||
sd_bus_message_rewind;
|
||||
|
||||
/* Bus management */
|
||||
sd_bus_get_unique_name;
|
||||
sd_bus_request_name;
|
||||
sd_bus_release_name;
|
||||
sd_bus_list_names;
|
||||
sd_bus_get_owner;
|
||||
sd_bus_get_owner_creds;
|
||||
sd_bus_get_owner_machine_id;
|
||||
|
||||
/* Convenience calls */
|
||||
sd_bus_call_method;
|
||||
sd_bus_get_property;
|
||||
@ -166,16 +152,36 @@ global:
|
||||
sd_bus_emit_interfaces_added;
|
||||
sd_bus_emit_interfaces_removed_strv;
|
||||
sd_bus_emit_interfaces_removed;
|
||||
sd_bus_query_sender_creds;
|
||||
|
||||
/* Bus management */
|
||||
sd_bus_get_unique_name;
|
||||
sd_bus_request_name;
|
||||
sd_bus_release_name;
|
||||
sd_bus_list_names;
|
||||
sd_bus_get_owner;
|
||||
sd_bus_get_owner_uid;
|
||||
sd_bus_get_owner_pid;
|
||||
sd_bus_get_owner_machine_id;
|
||||
/* Credentials */
|
||||
sd_bus_creds_new_from_pid;
|
||||
sd_bus_creds_ref;
|
||||
sd_bus_creds_unref;
|
||||
sd_bus_creds_extend;
|
||||
sd_bus_creds_get_mask;
|
||||
sd_bus_creds_get_uid;
|
||||
sd_bus_creds_get_gid;
|
||||
sd_bus_creds_get_pid;
|
||||
sd_bus_creds_get_pid_starttime;
|
||||
sd_bus_creds_get_tid;
|
||||
sd_bus_creds_get_comm;
|
||||
sd_bus_creds_get_tid_comm;
|
||||
sd_bus_creds_get_exe;
|
||||
sd_bus_creds_get_cmdline;
|
||||
sd_bus_creds_get_cgroup;
|
||||
sd_bus_creds_get_unit;
|
||||
sd_bus_creds_get_user_unit;
|
||||
sd_bus_creds_get_slice;
|
||||
sd_bus_creds_get_session;
|
||||
sd_bus_creds_get_owner_uid;
|
||||
sd_bus_creds_has_effective_cap;
|
||||
sd_bus_creds_has_permitted_cap;
|
||||
sd_bus_creds_has_inheritable_cap;
|
||||
sd_bus_creds_has_bounding_cap;
|
||||
sd_bus_creds_get_selinux_context;
|
||||
sd_bus_creds_get_audit_session_id;
|
||||
sd_bus_creds_get_audit_login_uid;
|
||||
|
||||
/* Error structures */
|
||||
sd_bus_error_free;
|
||||
|
@ -283,75 +283,38 @@ _public_ int sd_bus_negotiate_attach_timestamp(sd_bus *bus, int b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_negotiate_attach_creds(sd_bus *bus, int b) {
|
||||
_public_ int sd_bus_negotiate_attach_creds(sd_bus *bus, uint64_t mask) {
|
||||
assert_return(bus, -EINVAL);
|
||||
assert_return(mask <= _SD_BUS_CREDS_MAX, -EINVAL);
|
||||
assert_return(bus->state == BUS_UNSET, -EPERM);
|
||||
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CREDS, b);
|
||||
return 0;
|
||||
}
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CREDS,
|
||||
!!(mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_GID|SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_TID)));
|
||||
|
||||
_public_ int sd_bus_negotiate_attach_comm(sd_bus *bus, int b) {
|
||||
assert_return(bus, -EINVAL);
|
||||
assert_return(bus->state == BUS_UNSET, -EPERM);
|
||||
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_COMM,
|
||||
!!(mask & (SD_BUS_CREDS_COMM|SD_BUS_CREDS_TID_COMM)));
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_COMM, b);
|
||||
return 0;
|
||||
}
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_EXE,
|
||||
!!(mask & SD_BUS_CREDS_EXE));
|
||||
|
||||
_public_ int sd_bus_negotiate_attach_exe(sd_bus *bus, int b) {
|
||||
assert_return(bus, -EINVAL);
|
||||
assert_return(bus->state == BUS_UNSET, -EPERM);
|
||||
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CMDLINE,
|
||||
!!(mask & SD_BUS_CREDS_CMDLINE));
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_EXE, b);
|
||||
return 0;
|
||||
}
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CGROUP,
|
||||
!!(mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID)));
|
||||
|
||||
_public_ int sd_bus_negotiate_attach_cmdline(sd_bus *bus, int b) {
|
||||
assert_return(bus, -EINVAL);
|
||||
assert_return(bus->state == BUS_UNSET, -EPERM);
|
||||
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CAPS,
|
||||
!!(mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)));
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CMDLINE, b);
|
||||
return 0;
|
||||
}
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_SECLABEL,
|
||||
!!(mask & SD_BUS_CREDS_SELINUX_CONTEXT));
|
||||
|
||||
_public_ int sd_bus_negotiate_attach_cgroup(sd_bus *bus, int b) {
|
||||
assert_return(bus, -EINVAL);
|
||||
assert_return(bus->state == BUS_UNSET, -EPERM);
|
||||
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_AUDIT,
|
||||
!!(mask & (SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)));
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CGROUP, b);
|
||||
return 0;
|
||||
}
|
||||
bus->creds_mask = mask;
|
||||
|
||||
_public_ int sd_bus_negotiate_attach_caps(sd_bus *bus, int b) {
|
||||
assert_return(bus, -EINVAL);
|
||||
assert_return(bus->state == BUS_UNSET, -EPERM);
|
||||
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_CAPS, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_negotiate_attach_selinux_context(sd_bus *bus, int b) {
|
||||
assert_return(bus, -EINVAL);
|
||||
assert_return(bus->state == BUS_UNSET, -EPERM);
|
||||
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_SECLABEL, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_negotiate_attach_audit(sd_bus *bus, int b) {
|
||||
assert_return(bus, -EINVAL);
|
||||
assert_return(bus->state == BUS_UNSET, -EPERM);
|
||||
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||
|
||||
SET_FLAG(bus->hello_flags, KDBUS_HELLO_ATTACH_AUDIT, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2812,3 +2775,48 @@ _public_ char *sd_bus_label_unescape(const char *f) {
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
_public_ int sd_bus_get_peer_creds(sd_bus *bus, uint64_t mask, sd_bus_creds **ret) {
|
||||
sd_bus_creds *c;
|
||||
pid_t pid = 0;
|
||||
int r;
|
||||
|
||||
assert_return(bus, -EINVAL);
|
||||
assert_return(mask <= _SD_BUS_CREDS_MAX, -ENOTSUP);
|
||||
assert_return(ret, -EINVAL);
|
||||
assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
|
||||
assert_return(!bus_pid_changed(bus), -ECHILD);
|
||||
assert_return(!bus->is_kernel, -ENOTSUP);
|
||||
|
||||
if (!bus->ucred_valid && !isempty(bus->label))
|
||||
return -ENODATA;
|
||||
|
||||
c = bus_creds_new();
|
||||
if (!c)
|
||||
return -ENOMEM;
|
||||
|
||||
if (bus->ucred_valid) {
|
||||
pid = c->pid = bus->ucred.pid;
|
||||
c->uid = bus->ucred.uid;
|
||||
c->gid = bus->ucred.gid;
|
||||
|
||||
c->mask |= ((SD_BUS_CREDS_UID | SD_BUS_CREDS_PID | SD_BUS_CREDS_GID) & mask) & bus->creds_mask;
|
||||
}
|
||||
|
||||
if (!isempty(bus->label) && (mask & SD_BUS_CREDS_SELINUX_CONTEXT)) {
|
||||
c->label = strdup(bus->label);
|
||||
if (!c->label) {
|
||||
sd_bus_creds_unref(c);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT | bus->creds_mask;
|
||||
}
|
||||
|
||||
r = bus_creds_add_more(c, mask, pid, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = c;
|
||||
return 0;
|
||||
}
|
||||
|
@ -158,8 +158,8 @@ static int server(sd_bus *bus) {
|
||||
if (!m)
|
||||
continue;
|
||||
|
||||
sd_bus_message_get_pid(m, &pid);
|
||||
sd_bus_message_get_selinux_context(m, &label);
|
||||
sd_bus_creds_get_pid(sd_bus_message_get_creds(m), &pid);
|
||||
sd_bus_creds_get_selinux_context(sd_bus_message_get_creds(m), &label);
|
||||
log_info("Got message! member=%s pid=%lu label=%s",
|
||||
strna(sd_bus_message_get_member(m)),
|
||||
(unsigned long) pid,
|
||||
|
46
src/libsystemd-bus/test-bus-creds.c
Normal file
46
src/libsystemd-bus/test-bus-creds.c
Normal file
@ -0,0 +1,46 @@
|
||||
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||
|
||||
/***
|
||||
This file is part of systemd.
|
||||
|
||||
Copyright 2013 Lennart Poettering
|
||||
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "sd-bus.h"
|
||||
#include "bus-dump.h"
|
||||
#include "bus-util.h"
|
||||
#include "util.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
int r;
|
||||
|
||||
r = sd_bus_creds_new_from_pid(0, _SD_BUS_CREDS_MAX, &creds);
|
||||
assert_se(r >= 0);
|
||||
|
||||
bus_creds_dump(creds, NULL);
|
||||
|
||||
creds = sd_bus_creds_unref(creds);
|
||||
|
||||
r = sd_bus_creds_new_from_pid(1, _SD_BUS_CREDS_MAX, &creds);
|
||||
if (r != -EACCES) {
|
||||
assert_se(r >= 0);
|
||||
putchar('\n');
|
||||
bus_creds_dump(creds, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -63,24 +63,10 @@ int main(int argc, char *argv[]) {
|
||||
assert_se(r >= 0);
|
||||
|
||||
assert_se(sd_bus_negotiate_attach_timestamp(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_creds(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_comm(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_exe(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_cmdline(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_cgroup(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_caps(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_selinux_context(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_audit(a, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_creds(a, _SD_BUS_CREDS_MAX) >= 0);
|
||||
|
||||
assert_se(sd_bus_negotiate_attach_timestamp(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_creds(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_comm(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_exe(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_cmdline(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_cgroup(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_caps(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_selinux_context(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_audit(b, 1) >= 0);
|
||||
assert_se(sd_bus_negotiate_attach_creds(b, _SD_BUS_CREDS_MAX) >= 0);
|
||||
|
||||
r = sd_bus_start(a);
|
||||
assert_se(r >= 0);
|
||||
|
@ -172,7 +172,13 @@ static int method_get_session_by_pid(sd_bus *bus, sd_bus_message *message, void
|
||||
return r;
|
||||
|
||||
if (pid == 0) {
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -234,7 +240,13 @@ static int method_get_user_by_pid(sd_bus *bus, sd_bus_message *message, void *us
|
||||
return r;
|
||||
|
||||
if (pid == 0) {
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -543,9 +555,15 @@ static int method_create_session(sd_bus *bus, sd_bus_message *message, void *use
|
||||
}
|
||||
|
||||
if (leader <= 0) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
assert_cc(sizeof(uint32_t) == sizeof(pid_t));
|
||||
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), (pid_t*) &leader);
|
||||
r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1424,6 +1442,7 @@ static int method_do_shutdown_or_sleep(
|
||||
sd_bus_message_handler_t method,
|
||||
sd_bus_error *error) {
|
||||
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
bool multiple_sessions, blocked;
|
||||
int interactive, r;
|
||||
uid_t uid;
|
||||
@ -1455,7 +1474,11 @@ static int method_do_shutdown_or_sleep(
|
||||
return sd_bus_error_setf(error, BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, "Sleep verb not supported");
|
||||
}
|
||||
|
||||
r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1579,6 +1602,7 @@ static int method_can_shutdown_or_sleep(
|
||||
const char *sleep_verb,
|
||||
sd_bus_error *error) {
|
||||
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
bool multiple_sessions, challenge, blocked;
|
||||
const char *result = NULL;
|
||||
uid_t uid;
|
||||
@ -1600,7 +1624,11 @@ static int method_can_shutdown_or_sleep(
|
||||
return sd_bus_reply_method_return(message, "s", "na");
|
||||
}
|
||||
|
||||
r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1722,6 +1750,7 @@ static int method_can_hybrid_sleep(sd_bus *bus, sd_bus_message *message, void *u
|
||||
}
|
||||
|
||||
static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
const char *who, *why, *what, *mode;
|
||||
_cleanup_free_ char *id = NULL;
|
||||
_cleanup_close_ int fifo_fd = -1;
|
||||
@ -1774,11 +1803,15 @@ static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata,
|
||||
if (r == 0)
|
||||
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
|
||||
|
||||
r = sd_bus_get_owner_uid(m->bus, sd_bus_message_get_sender(message), &uid);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID|SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_get_owner_pid(m->bus, sd_bus_message_get_sender(message), &pid);
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -266,6 +266,7 @@ int seat_object_find(sd_bus *bus, const char *path, const char *interface, void
|
||||
assert(m);
|
||||
|
||||
if (streq(path, "/org/freedesktop/login1/seat/self")) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
sd_bus_message *message;
|
||||
Session *session;
|
||||
pid_t pid;
|
||||
@ -274,9 +275,13 @@ int seat_object_find(sd_bus *bus, const char *path, const char *interface, void
|
||||
if (!message)
|
||||
return 0;
|
||||
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = manager_get_session_by_pid(m, pid, &session);
|
||||
if (r <= 0)
|
||||
|
@ -225,6 +225,7 @@ static int method_lock(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
|
||||
}
|
||||
|
||||
static int method_set_idle_hint(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
Session *s = userdata;
|
||||
uid_t uid;
|
||||
int r, b;
|
||||
@ -237,7 +238,11 @@ static int method_set_idle_hint(sd_bus *bus, sd_bus_message *message, void *user
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_get_owner_uid(bus, sd_bus_message_get_sender(message), &uid);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -283,6 +288,7 @@ static int method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_
|
||||
}
|
||||
|
||||
static int method_take_control(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
Session *s = userdata;
|
||||
int r, force;
|
||||
uid_t uid;
|
||||
@ -295,7 +301,11 @@ static int method_take_control(sd_bus *bus, sd_bus_message *message, void *userd
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_get_owner_uid(bus, sd_bus_message_get_sender(message), &uid);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_UID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_uid(creds, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -477,6 +487,7 @@ int session_object_find(sd_bus *bus, const char *path, const char *interface, vo
|
||||
assert(m);
|
||||
|
||||
if (streq(path, "/org/freedesktop/login1/session/self")) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
sd_bus_message *message;
|
||||
pid_t pid;
|
||||
|
||||
@ -484,9 +495,13 @@ int session_object_find(sd_bus *bus, const char *path, const char *interface, vo
|
||||
if (!message)
|
||||
return 0;
|
||||
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = manager_get_session_by_pid(m, pid, &session);
|
||||
if (r <= 0)
|
||||
|
@ -247,6 +247,7 @@ int user_object_find(sd_bus *bus, const char *path, const char *interface, void
|
||||
assert(m);
|
||||
|
||||
if (streq(path, "/org/freedesktop/login1/user/self")) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
sd_bus_message *message;
|
||||
pid_t pid;
|
||||
|
||||
@ -254,9 +255,13 @@ int user_object_find(sd_bus *bus, const char *path, const char *interface, void
|
||||
if (!message)
|
||||
return 0;
|
||||
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = manager_get_user_by_pid(m, pid, &user);
|
||||
if (r <= 0)
|
||||
|
@ -154,6 +154,7 @@ int machine_object_find(sd_bus *bus, const char *path, const char *interface, vo
|
||||
assert(m);
|
||||
|
||||
if (streq(path, "/org/freedesktop/machine1/machine/self")) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
sd_bus_message *message;
|
||||
pid_t pid;
|
||||
|
||||
@ -161,9 +162,13 @@ int machine_object_find(sd_bus *bus, const char *path, const char *interface, vo
|
||||
if (!message)
|
||||
return 0;
|
||||
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = manager_get_machine_by_pid(m, pid, &machine);
|
||||
if (r <= 0)
|
||||
|
@ -102,7 +102,13 @@ static int method_get_machine_by_pid(sd_bus *bus, sd_bus_message *message, void
|
||||
return r;
|
||||
|
||||
if (pid == 0) {
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_creds_get_pid(creds, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -216,9 +222,15 @@ static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *use
|
||||
return r;
|
||||
|
||||
if (leader == 0) {
|
||||
_cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
|
||||
|
||||
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
assert_cc(sizeof(uint32_t) == sizeof(pid_t));
|
||||
|
||||
r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), (pid_t*) &leader);
|
||||
r = sd_bus_creds_get_pid(creds, (pid_t*) &leader);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -26,8 +26,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/capability.h>
|
||||
|
||||
#include "macro.h"
|
||||
#include "audit.h"
|
||||
@ -37,91 +35,64 @@
|
||||
#include "virt.h"
|
||||
|
||||
int audit_session_from_pid(pid_t pid, uint32_t *id) {
|
||||
char *s;
|
||||
_cleanup_free_ char *s = NULL;
|
||||
const char *p;
|
||||
uint32_t u;
|
||||
int r;
|
||||
|
||||
assert(id);
|
||||
|
||||
if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0)
|
||||
return -ENOENT;
|
||||
|
||||
/* Audit doesn't support containers right now */
|
||||
if (detect_container(NULL) > 0)
|
||||
return -ENOTSUP;
|
||||
|
||||
if (pid == 0)
|
||||
r = read_one_line_file("/proc/self/sessionid", &s);
|
||||
else {
|
||||
char *p;
|
||||
|
||||
if (asprintf(&p, "/proc/%lu/sessionid", (unsigned long) pid) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = read_one_line_file(p, &s);
|
||||
free(p);
|
||||
}
|
||||
p = "/proc/self/sessionid";
|
||||
else
|
||||
p = procfs_file_alloca(pid, "sessionid");
|
||||
|
||||
r = read_one_line_file(p, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = safe_atou32(s, &u);
|
||||
free(s);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (u == (uint32_t) -1 || u <= 0)
|
||||
return -ENOENT;
|
||||
return -ENXIO;
|
||||
|
||||
*id = u;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int audit_loginuid_from_pid(pid_t pid, uid_t *uid) {
|
||||
char *s;
|
||||
_cleanup_free_ char *s = NULL;
|
||||
const char *p;
|
||||
uid_t u;
|
||||
int r;
|
||||
|
||||
assert(uid);
|
||||
|
||||
/* Only use audit login uid if we are executed with sufficient
|
||||
* capabilities so that pam_loginuid could do its job. If we
|
||||
* are lacking the CAP_AUDIT_CONTROL capabality we most likely
|
||||
* are being run in a container and /proc/self/loginuid is
|
||||
* useless since it probably contains a uid of the host
|
||||
* system. */
|
||||
|
||||
if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0)
|
||||
return -ENOENT;
|
||||
|
||||
/* Audit doesn't support containers right now */
|
||||
if (detect_container(NULL) > 0)
|
||||
return -ENOTSUP;
|
||||
|
||||
if (pid == 0)
|
||||
r = read_one_line_file("/proc/self/loginuid", &s);
|
||||
else {
|
||||
char *p;
|
||||
|
||||
if (asprintf(&p, "/proc/%lu/loginuid", (unsigned long) pid) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
r = read_one_line_file(p, &s);
|
||||
free(p);
|
||||
}
|
||||
p = "/proc/self/loginuid";
|
||||
else
|
||||
p = procfs_file_alloca(pid, "loginuid");
|
||||
|
||||
r = read_one_line_file(p, &s);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = parse_uid(s, &u);
|
||||
free(s);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (u == (uid_t) -1)
|
||||
return -ENOENT;
|
||||
return -ENXIO;
|
||||
|
||||
*uid = (uid_t) u;
|
||||
return 0;
|
||||
|
@ -430,7 +430,7 @@ char *split_quoted(const char *c, size_t *l, char **state) {
|
||||
*state = (char*) e;
|
||||
}
|
||||
|
||||
return current;
|
||||
return (char*) current;
|
||||
}
|
||||
|
||||
int get_parent_of_pid(pid_t pid, pid_t *_ppid) {
|
||||
@ -497,7 +497,7 @@ int get_starttime_of_pid(pid_t pid, unsigned long long *st) {
|
||||
|
||||
f = fopen(p, "re");
|
||||
if (!f)
|
||||
return -errno;
|
||||
return errno == ENOENT ? -ESRCH : -errno;
|
||||
|
||||
if (!fgets(line, sizeof(line), f)) {
|
||||
if (ferror(f))
|
||||
@ -563,6 +563,7 @@ char *truncate_nl(char *s) {
|
||||
|
||||
int get_process_comm(pid_t pid, char **name) {
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
assert(name);
|
||||
assert(pid >= 0);
|
||||
@ -572,7 +573,11 @@ int get_process_comm(pid_t pid, char **name) {
|
||||
else
|
||||
p = procfs_file_alloca(pid, "comm");
|
||||
|
||||
return read_one_line_file(p, name);
|
||||
r = read_one_line_file(p, name);
|
||||
if (r == -ENOENT)
|
||||
return -ESRCH;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
|
||||
@ -729,7 +734,7 @@ int get_process_exe(pid_t pid, char **name) {
|
||||
|
||||
r = readlink_malloc(p, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
return r == -ENOENT ? -ESRCH : r;
|
||||
|
||||
d = endswith(*name, " (deleted)");
|
||||
if (d)
|
||||
|
@ -37,6 +37,7 @@ _SD_BEGIN_DECLARATIONS;
|
||||
|
||||
typedef struct sd_bus sd_bus;
|
||||
typedef struct sd_bus_message sd_bus_message;
|
||||
typedef struct sd_bus_creds sd_bus_creds;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
@ -44,6 +45,34 @@ typedef struct {
|
||||
int need_free;
|
||||
} sd_bus_error;
|
||||
|
||||
/* Flags */
|
||||
|
||||
enum {
|
||||
SD_BUS_CREDS_UID = 1ULL << 0,
|
||||
SD_BUS_CREDS_GID = 1ULL << 1,
|
||||
SD_BUS_CREDS_PID = 1ULL << 2,
|
||||
SD_BUS_CREDS_PID_STARTTIME = 1ULL << 3,
|
||||
SD_BUS_CREDS_TID = 1ULL << 4,
|
||||
SD_BUS_CREDS_COMM = 1ULL << 5,
|
||||
SD_BUS_CREDS_TID_COMM = 1ULL << 6,
|
||||
SD_BUS_CREDS_EXE = 1ULL << 7,
|
||||
SD_BUS_CREDS_CMDLINE = 1ULL << 8,
|
||||
SD_BUS_CREDS_CGROUP = 1ULL << 9,
|
||||
SD_BUS_CREDS_UNIT = 1ULL << 10,
|
||||
SD_BUS_CREDS_USER_UNIT = 1ULL << 11,
|
||||
SD_BUS_CREDS_SLICE = 1ULL << 12,
|
||||
SD_BUS_CREDS_SESSION = 1ULL << 13,
|
||||
SD_BUS_CREDS_OWNER_UID = 1ULL << 14,
|
||||
SD_BUS_CREDS_EFFECTIVE_CAPS = 1ULL << 15,
|
||||
SD_BUS_CREDS_PERMITTED_CAPS = 1ULL << 16,
|
||||
SD_BUS_CREDS_INHERITABLE_CAPS = 1ULL << 17,
|
||||
SD_BUS_CREDS_BOUNDING_CAPS = 1ULL << 18,
|
||||
SD_BUS_CREDS_SELINUX_CONTEXT = 1ULL << 19,
|
||||
SD_BUS_CREDS_AUDIT_SESSION_ID = 1ULL << 20,
|
||||
SD_BUS_CREDS_AUDIT_LOGIN_UID = 1ULL << 21,
|
||||
_SD_BUS_CREDS_MAX = (1ULL << 22) -1,
|
||||
};
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
typedef int (*sd_bus_message_handler_t)(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error);
|
||||
@ -74,14 +103,7 @@ int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t server_id);
|
||||
int sd_bus_set_anonymous(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_fds(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_timestamp(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_creds(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_comm(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_exe(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_cmdline(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_cgroup(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_caps(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_selinux_context(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_audit(sd_bus *bus, int b);
|
||||
int sd_bus_negotiate_attach_creds(sd_bus *bus, uint64_t creds_mask);
|
||||
int sd_bus_start(sd_bus *ret);
|
||||
|
||||
void sd_bus_close(sd_bus *bus);
|
||||
@ -92,6 +114,7 @@ sd_bus *sd_bus_unref(sd_bus *bus);
|
||||
int sd_bus_is_open(sd_bus *bus);
|
||||
int sd_bus_can_send(sd_bus *bus, char type);
|
||||
int sd_bus_get_server_id(sd_bus *bus, sd_id128_t *peer);
|
||||
int sd_bus_get_peer_creds(sd_bus *bus, uint64_t creds_mask, sd_bus_creds **ret);
|
||||
|
||||
int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial);
|
||||
int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *serial);
|
||||
@ -149,6 +172,8 @@ int sd_bus_message_new_method_errnof(sd_bus_message *call, sd_bus_message **m, i
|
||||
sd_bus_message* sd_bus_message_ref(sd_bus_message *m);
|
||||
sd_bus_message* sd_bus_message_unref(sd_bus_message *m);
|
||||
|
||||
sd_bus* sd_bus_message_get_bus(sd_bus_message *m);
|
||||
|
||||
int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type);
|
||||
int sd_bus_message_get_serial(sd_bus_message *m, uint64_t *serial);
|
||||
int sd_bus_message_get_reply_serial(sd_bus_message *m, uint64_t *serial);
|
||||
@ -164,28 +189,9 @@ const char *sd_bus_message_get_sender(sd_bus_message *m);
|
||||
const sd_bus_error *sd_bus_message_get_error(sd_bus_message *m);
|
||||
int sd_bus_message_get_errno(sd_bus_message *m);
|
||||
|
||||
sd_bus* sd_bus_message_get_bus(sd_bus_message *m);
|
||||
|
||||
int sd_bus_message_get_monotonic_timestamp(sd_bus_message *m, uint64_t *usec);
|
||||
int sd_bus_message_get_realtime_timestamp(sd_bus_message *m, uint64_t *usec);
|
||||
int sd_bus_message_get_uid(sd_bus_message *m, uid_t *uid);
|
||||
int sd_bus_message_get_gid(sd_bus_message *m, gid_t *gid);
|
||||
int sd_bus_message_get_pid(sd_bus_message *m, pid_t *pid);
|
||||
int sd_bus_message_get_tid(sd_bus_message *m, pid_t *tid);
|
||||
int sd_bus_message_get_pid_starttime(sd_bus_message *m, uint64_t *usec);
|
||||
int sd_bus_message_get_selinux_context(sd_bus_message *m, const char **r);
|
||||
int sd_bus_message_get_comm(sd_bus_message *m, const char **r);
|
||||
int sd_bus_message_get_tid_comm(sd_bus_message *m, const char **r);
|
||||
int sd_bus_message_get_exe(sd_bus_message *m, const char **r);
|
||||
int sd_bus_message_get_cgroup(sd_bus_message *m, const char **r);
|
||||
int sd_bus_message_get_cmdline(sd_bus_message *m, char ***cmdline);
|
||||
int sd_bus_message_get_unit(sd_bus_message *m, const char **unit);
|
||||
int sd_bus_message_get_user_unit(sd_bus_message *m, const char **unit);
|
||||
int sd_bus_message_get_session(sd_bus_message *m, const char **session);
|
||||
int sd_bus_message_get_owner_uid(sd_bus_message *m, uid_t *uid);
|
||||
int sd_bus_message_get_audit_sessionid(sd_bus_message *m, uint32_t *sessionid);
|
||||
int sd_bus_message_get_audit_loginuid(sd_bus_message *m, uid_t *loginuid);
|
||||
int sd_bus_message_has_effective_cap(sd_bus_message *m, int capability);
|
||||
sd_bus_creds *sd_bus_message_get_creds(sd_bus_message *m); /* do not unref the result */
|
||||
|
||||
int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member);
|
||||
int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member);
|
||||
@ -221,6 +227,16 @@ int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *content
|
||||
int sd_bus_message_at_end(sd_bus_message *m, int complete);
|
||||
int sd_bus_message_rewind(sd_bus_message *m, int complete);
|
||||
|
||||
/* Bus management */
|
||||
|
||||
int sd_bus_get_unique_name(sd_bus *bus, const char **unique);
|
||||
int sd_bus_request_name(sd_bus *bus, const char *name, int flags);
|
||||
int sd_bus_release_name(sd_bus *bus, const char *name);
|
||||
int sd_bus_list_names(sd_bus *bus, char ***l);
|
||||
int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner); /* free the result! */
|
||||
int sd_bus_get_owner_creds(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **creds); /* unref the result! */
|
||||
int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine);
|
||||
|
||||
/* Convenience calls */
|
||||
|
||||
int sd_bus_call_method(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, ...);
|
||||
@ -246,16 +262,39 @@ int sd_bus_emit_interfaces_added(sd_bus *bus, const char *path, const char *inte
|
||||
int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path, char **interfaces);
|
||||
int sd_bus_emit_interfaces_removed(sd_bus *bus, const char *path, const char *interface, ...) _sd_sentinel_;
|
||||
|
||||
/* Bus management */
|
||||
int sd_bus_query_sender_creds(sd_bus_message *call, uint64_t mask, sd_bus_creds **creds);
|
||||
|
||||
int sd_bus_get_unique_name(sd_bus *bus, const char **unique);
|
||||
int sd_bus_request_name(sd_bus *bus, const char *name, int flags);
|
||||
int sd_bus_release_name(sd_bus *bus, const char *name);
|
||||
int sd_bus_list_names(sd_bus *bus, char ***l);
|
||||
int sd_bus_get_owner(sd_bus *bus, const char *name, char **owner); /* free the result! */
|
||||
int sd_bus_get_owner_uid(sd_bus *bus, const char *name, uid_t *uid);
|
||||
int sd_bus_get_owner_pid(sd_bus *bus, const char *name, pid_t *pid);
|
||||
int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine);
|
||||
/* Credential handling */
|
||||
|
||||
int sd_bus_creds_new_from_pid(pid_t pid, uint64_t creds_mask, sd_bus_creds **ret);
|
||||
sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c);
|
||||
sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c);
|
||||
uint64_t sd_bus_creds_get_mask(sd_bus_creds *c);
|
||||
|
||||
int sd_bus_creds_extend(sd_bus_creds *c, uint64_t creds_mask, sd_bus_creds **ret); /* unref the result */
|
||||
|
||||
int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid);
|
||||
int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid);
|
||||
int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid);
|
||||
int sd_bus_creds_get_pid_starttime(sd_bus_creds *c, uint64_t *usec);
|
||||
int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid);
|
||||
int sd_bus_creds_get_comm(sd_bus_creds *c, const char **r);
|
||||
int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **r);
|
||||
int sd_bus_creds_get_exe(sd_bus_creds *c, const char **r);
|
||||
int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline);
|
||||
int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **r);
|
||||
int sd_bus_creds_get_unit(sd_bus_creds *c, const char **unit);
|
||||
int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **unit);
|
||||
int sd_bus_creds_get_slice(sd_bus_creds *c, const char **slice);
|
||||
int sd_bus_creds_get_session(sd_bus_creds *c, const char **session);
|
||||
int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid);
|
||||
int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability);
|
||||
int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability);
|
||||
int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability);
|
||||
int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability);
|
||||
int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **r);
|
||||
int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid);
|
||||
int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *loginuid);
|
||||
|
||||
/* Error structures */
|
||||
|
||||
@ -273,6 +312,8 @@ int sd_bus_error_copy(sd_bus_error *dest, const sd_bus_error *e);
|
||||
int sd_bus_error_is_set(const sd_bus_error *e);
|
||||
int sd_bus_error_has_name(const sd_bus_error *e, const char *name);
|
||||
|
||||
/* Auxiliary macros */
|
||||
|
||||
#define SD_BUS_MESSAGE_APPEND_ID128(x) 16, \
|
||||
(x).bytes[0], (x).bytes[1], (x).bytes[2], (x).bytes[3], \
|
||||
(x).bytes[4], (x).bytes[5], (x).bytes[6], (x).bytes[7], \
|
||||
@ -285,6 +326,8 @@ int sd_bus_error_has_name(const sd_bus_error *e, const char *name);
|
||||
&(x).bytes[8], &(x).bytes[9], &(x).bytes[10], &(x).bytes[11], \
|
||||
&(x).bytes[12], &(x).bytes[13], &(x).bytes[14], &(x).bytes[15]
|
||||
|
||||
/* Label escaping */
|
||||
|
||||
char *sd_bus_label_escape(const char *s);
|
||||
char *sd_bus_label_unescape(const char *f);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user