mirror of
https://github.com/troglobit/finit.git
synced 2026-10-16 10:39:35 +00:00
libink/finit: properties, and org.finit on the system bus
Runlevel and version are state, not actions, so they belong behind org.freedesktop.DBus.Properties rather than another method each. Finit also claims org.finit on the system bus when it finds one, so ordinary D-Bus clients can reach it without knowing about /run/finit/bus. Opportunistic on purpose: no dbus-daemon is a normal state for the systems Finit runs on, not an error to report. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
dd1390a6c2
commit
ebc0ef62e6
22 files changed
+1474
-154
No files matched your search
@@ -66,3 +66,31 @@ case "$(cat /tmp/dbus-initctl-cond.out)" in
|
||||
*)
|
||||
fail "initctl cond set didn't produce expected signal: $(cat /tmp/dbus-initctl-cond.out)" ;;
|
||||
esac
|
||||
|
||||
# ---------- arc B: signal + reload <svc> routing ----------
|
||||
|
||||
# initctl signal exits 0 iff the bus call succeeded. We send SIGCONT
|
||||
# (no observable side-effect on a healthy daemon) so the test stays
|
||||
# benign regardless of how keventd handles it.
|
||||
say "initctl signal routes through Manager1.Signal"
|
||||
texec initctl signal keventd CONT >/dev/null \
|
||||
|| fail "initctl signal returned non-zero"
|
||||
assert "initctl signal ok" 0 -eq 0
|
||||
|
||||
say "initctl signal on a bogus identity reports NoSuchService"
|
||||
set +e
|
||||
texec initctl signal no-such-svc-anywhere CONT >/tmp/dbus-sig-bad.out 2>&1
|
||||
sigbad_rc=$?
|
||||
set -e
|
||||
assert "Bogus signal target rejected (rc=$sigbad_rc)" "$sigbad_rc" -ne 0
|
||||
case "$(cat /tmp/dbus-sig-bad.out)" in
|
||||
*"no such task or service"*)
|
||||
assert "Error message mentions missing service" 0 -eq 0 ;;
|
||||
*)
|
||||
fail "Unexpected initctl signal output: $(cat /tmp/dbus-sig-bad.out)" ;;
|
||||
esac
|
||||
|
||||
say "initctl reload <svc> routes through Service1.Reload"
|
||||
texec initctl reload keventd >/dev/null \
|
||||
|| fail "initctl reload keventd returned non-zero"
|
||||
assert "Per-service reload ok" 0 -eq 0
|
||||
@@ -67,3 +67,69 @@ case "$result" in
|
||||
*InvalidArgs*) assert "Non-root reached signature check (InvalidArgs, not AccessDenied)" 0 -eq 0 ;;
|
||||
*) fail "Unexpected reply from non-root ListServices: $result" ;;
|
||||
esac
|
||||
|
||||
# ---------- Properties ----------
|
||||
|
||||
say "Introspect on /org/finit/manager advertises org.freedesktop.DBus.Properties"
|
||||
xml=$(texec "$CLIENT" introspect "$BUS" /org/finit/manager)
|
||||
case "$xml" in
|
||||
*'org.freedesktop.DBus.Properties'*) assert "Properties interface in XML" 0 -eq 0 ;;
|
||||
*) fail "Properties interface missing from XML" ;;
|
||||
esac
|
||||
|
||||
say "Manager1 declares Runlevel + Version as <property> in introspection XML"
|
||||
case "$xml" in
|
||||
*'<property name="Runlevel"'*'<property name="Version"'*)
|
||||
assert "Runlevel and Version both declared" 0 -eq 0 ;;
|
||||
*)
|
||||
fail "Property declarations missing or out of order: $xml" ;;
|
||||
esac
|
||||
|
||||
# ---------- arc B: SetDebug + Suspend authz ----------
|
||||
|
||||
say "Manager1.SetDebug as root succeeds"
|
||||
texec "$CLIENT" call-void "$BUS" /org/finit/manager \
|
||||
org.finit.Manager1 SetDebug >/dev/null \
|
||||
|| fail "SetDebug returned non-zero"
|
||||
# Toggle back so this test leaves debug in the same state we found it
|
||||
texec "$CLIENT" call-void "$BUS" /org/finit/manager \
|
||||
org.finit.Manager1 SetDebug >/dev/null || true
|
||||
assert "SetDebug round-trip ok" 0 -eq 0
|
||||
|
||||
say "Manager1.SetDebug from non-root is rejected with AccessDenied"
|
||||
set +e
|
||||
texec "$CLIENT" call-void-as-uid 1 "$BUS" /org/finit/manager \
|
||||
org.finit.Manager1 SetDebug >/tmp/dbus-setdbg.out 2>&1
|
||||
sdbg_rc=$?
|
||||
set -e
|
||||
assert "Non-root SetDebug rejected (rc=$sdbg_rc)" "$sdbg_rc" -eq 1
|
||||
case "$(cat /tmp/dbus-setdbg.out)" in
|
||||
*AccessDenied*) assert "SetDebug authz fires" 0 -eq 0 ;;
|
||||
*) fail "Unexpected reply: $(cat /tmp/dbus-setdbg.out)" ;;
|
||||
esac
|
||||
|
||||
# Suspend would actually suspend the test sysroot if it succeeded -- so
|
||||
# we only test the non-root rejection path, which fails before suspend()
|
||||
# is called.
|
||||
say "Manager1.Suspend from non-root is rejected with AccessDenied"
|
||||
set +e
|
||||
texec "$CLIENT" call-void-as-uid 1 "$BUS" /org/finit/manager \
|
||||
org.finit.Manager1 Suspend >/tmp/dbus-susp.out 2>&1
|
||||
susp_rc=$?
|
||||
set -e
|
||||
assert "Non-root Suspend rejected (rc=$susp_rc)" "$susp_rc" -eq 1
|
||||
case "$(cat /tmp/dbus-susp.out)" in
|
||||
*AccessDenied*) assert "Suspend authz fires" 0 -eq 0 ;;
|
||||
*) fail "Unexpected reply: $(cat /tmp/dbus-susp.out)" ;;
|
||||
esac
|
||||
|
||||
say "initctl runlevel reads via Properties.Get when D-Bus available"
|
||||
# runlevel output format is "<prev> <curr>", e.g. "N 2". Just check
|
||||
# we get a sensible two-token line.
|
||||
rl=$(texec initctl runlevel)
|
||||
case "$rl" in
|
||||
[N0-9S]\ [0-9S])
|
||||
assert "initctl runlevel returned '$rl'" 0 -eq 0 ;;
|
||||
*)
|
||||
fail "Unexpected initctl runlevel output: $rl" ;;
|
||||
esac
|
||||
@@ -175,8 +175,6 @@ static int drop_uid(const char *uid_arg, const char *progname)
|
||||
static int mode_hello(int argc, char *argv[])
|
||||
{
|
||||
link_client_t *c;
|
||||
const link_reply_t *r;
|
||||
link_reader_t reader;
|
||||
const char *name;
|
||||
int rc;
|
||||
|
||||
@@ -188,9 +186,7 @@ static int mode_hello(int argc, char *argv[])
|
||||
"org.freedesktop.DBus", "Hello", NULL);
|
||||
rc = report_rc(c, rc);
|
||||
if (rc == 0) {
|
||||
r = link_client_reply(c);
|
||||
link_reader_init(&reader, r->body, r->body_len);
|
||||
if (link_r_string(&reader, &name) == 0)
|
||||
if (link_reply_get_string(link_client_reply(c), &name) == 0)
|
||||
printf("%s\n", name);
|
||||
else
|
||||
rc = 2;
|
||||
@@ -202,8 +198,6 @@ static int mode_hello(int argc, char *argv[])
|
||||
static int mode_introspect(int argc, char *argv[])
|
||||
{
|
||||
link_client_t *c;
|
||||
const link_reply_t *r;
|
||||
link_reader_t reader;
|
||||
const char *xml;
|
||||
int rc;
|
||||
|
||||
@@ -216,9 +210,7 @@ static int mode_introspect(int argc, char *argv[])
|
||||
"Introspect", NULL);
|
||||
rc = report_rc(c, rc);
|
||||
if (rc == 0) {
|
||||
r = link_client_reply(c);
|
||||
link_reader_init(&reader, r->body, r->body_len);
|
||||
if (link_r_string(&reader, &xml) == 0)
|
||||
if (link_reply_get_string(link_client_reply(c), &xml) == 0)
|
||||
printf("%s\n", xml);
|
||||
else
|
||||
rc = 2;
|
||||
@@ -227,23 +219,17 @@ static int mode_introspect(int argc, char *argv[])
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Decode body with signature "as" -- u32 array byte-len, then "s" strings.
|
||||
* libink's public reader doesn't yet have an array helper, so we walk
|
||||
* the wire form with link_r_u32 + link_r_string + link_r_pos. */
|
||||
/* Decode body with signature "as", print one string per line. */
|
||||
static int print_string_array(const link_reply_t *r)
|
||||
{
|
||||
link_reader_t reader;
|
||||
uint32_t array_len;
|
||||
size_t end;
|
||||
|
||||
if (!r || !r->signature || strcmp(r->signature, "as") != 0)
|
||||
return -1;
|
||||
|
||||
link_reader_init(&reader, r->body, r->body_len);
|
||||
if (link_r_u32(&reader, &array_len) < 0)
|
||||
return -1;
|
||||
end = link_r_pos(&reader) + array_len;
|
||||
if (end > r->body_len)
|
||||
if (link_r_array_begin(&reader, &end) < 0)
|
||||
return -1;
|
||||
|
||||
while (link_r_pos(&reader) < end) {
|
||||
@@ -330,8 +316,6 @@ static int mode_call_void_as_uid(int argc, char *argv[])
|
||||
static int mode_get_service(int argc, char *argv[])
|
||||
{
|
||||
link_client_t *c;
|
||||
const link_reply_t *r;
|
||||
link_reader_t reader;
|
||||
const char *path;
|
||||
int rc;
|
||||
|
||||
@@ -344,11 +328,8 @@ static int mode_get_service(int argc, char *argv[])
|
||||
"s", argv[3]);
|
||||
rc = report_rc(c, rc);
|
||||
if (rc == 0) {
|
||||
r = link_client_reply(c);
|
||||
link_reader_init(&reader, r->body, r->body_len);
|
||||
/* Reply signature is "o" but link_r_path / link_r_string
|
||||
* have the same wire form. */
|
||||
if (link_r_path(&reader, &path) == 0)
|
||||
/* Reply sig is "o", same wire form as "s". */
|
||||
if (link_reply_get_string(link_client_reply(c), &path) == 0)
|
||||
printf("%s\n", path);
|
||||
else
|
||||
rc = 2;
|
||||
|
||||
Reference in new issue
Block a user