static int rename_service(sd_bus *a, sd_bus *b) { _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; _cleanup_free_ char *p = NULL, *name = NULL; const char *comm; char **cmdline; uid_t uid; pid_t pid; int r; assert(a); assert(b); r = sd_bus_get_owner_creds(b, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID|SD_BUS_CREDS_CMDLINE|SD_BUS_CREDS_COMM|SD_BUS_CREDS_AUGMENT, &creds); if (r < 0) return r; r = sd_bus_creds_get_euid(creds, &uid); if (r < 0) return r; r = sd_bus_creds_get_pid(creds, &pid); if (r < 0) return r; r = sd_bus_creds_get_cmdline(creds, &cmdline); if (r < 0) return r; r = sd_bus_creds_get_comm(creds, &comm); if (r < 0) return r; name = uid_to_name(uid); if (!name) return -ENOMEM; p = strv_join(cmdline, " "); if (!p) return -ENOMEM; /* The status string gets the full command line ... */ sd_notifyf(false, "STATUS=Processing requests from client PID "PID_FMT" (%s); UID "UID_FMT" (%s)", pid, p, uid, name); /* ... and the argv line only the short comm */ if (arg_command_line_buffer) { size_t m, w; m = strlen(arg_command_line_buffer); w = snprintf(arg_command_line_buffer, m, "[PID "PID_FMT"/%s; UID "UID_FMT"/%s]", pid, comm, uid, name); if (m > w) memzero(arg_command_line_buffer + w, m - w); } log_debug("Running on behalf of PID "PID_FMT" (%s), UID "UID_FMT" (%s), %s", pid, p, uid, name, a->unique_name); return 0; }
static int server(sd_bus *bus) { int r; bool client1_gone = false, client2_gone = false; while (!client1_gone || !client2_gone) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL; pid_t pid = 0; const char *label = NULL; r = sd_bus_process(bus, &m); if (r < 0) { log_error_errno(r, "Failed to process requests: %m"); goto fail; } if (r == 0) { r = sd_bus_wait(bus, (uint64_t) -1); if (r < 0) { log_error_errno(r, "Failed to wait: %m"); goto fail; } continue; } if (!m) continue; 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="PID_FMT" label=%s", strna(sd_bus_message_get_member(m)), pid, strna(label)); /* bus_message_dump(m); */ /* sd_bus_message_rewind(m, true); */ if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "LowerCase")) { const char *hello; _cleanup_free_ char *lowercase = NULL; r = sd_bus_message_read(m, "s", &hello); if (r < 0) { log_error_errno(r, "Failed to get parameter: %m"); goto fail; } lowercase = strdup(hello); if (!lowercase) { r = log_oom(); goto fail; } ascii_strlower(lowercase); r = sd_bus_reply_method_return(m, "s", lowercase); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient1")) { r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } client1_gone = true; } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "ExitClient2")) { r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } client2_gone = true; } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "Slow")) { sleep(1); r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } else if (sd_bus_message_is_method_call(m, "org.freedesktop.systemd.test", "FileDescriptor")) { int fd; static const char x = 'X'; r = sd_bus_message_read(m, "h", &fd); if (r < 0) { log_error_errno(r, "Failed to get parameter: %m"); goto fail; } log_info("Received fd=%d", fd); if (write(fd, &x, 1) < 0) { log_error_errno(errno, "Failed to write to fd: %m"); safe_close(fd); goto fail; } r = sd_bus_reply_method_return(m, NULL); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } else if (sd_bus_message_is_method_call(m, NULL, NULL)) { r = sd_bus_reply_method_error( m, &SD_BUS_ERROR_MAKE_CONST(SD_BUS_ERROR_UNKNOWN_METHOD, "Unknown method.")); if (r < 0) { log_error_errno(r, "Failed to send reply: %m"); goto fail; } } } r = 0; fail: if (bus) { sd_bus_flush(bus); sd_bus_unref(bus); } return r; }
static int bus_scope_set_transient_property( Scope *s, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error) { int r; assert(s); assert(name); assert(message); flags |= UNIT_PRIVATE; if (streq(name, "TimeoutStopUSec")) return bus_set_transient_usec(UNIT(s), name, &s->timeout_stop_usec, message, flags, error); if (streq(name, "PIDs")) { _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; unsigned n = 0; r = sd_bus_message_enter_container(message, 'a', "u"); if (r < 0) return r; for (;;) { uint32_t upid; pid_t pid; r = sd_bus_message_read(message, "u", &upid); if (r < 0) return r; if (r == 0) break; if (upid == 0) { if (!creds) { 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; } else pid = (uid_t) upid; r = unit_pid_attachable(UNIT(s), pid, error); if (r < 0) return r; if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = unit_watch_pid(UNIT(s), pid); if (r < 0 && r != -EEXIST) return r; } n++; } r = sd_bus_message_exit_container(message); if (r < 0) return r; if (n <= 0) return -EINVAL; return 1; } else if (streq(name, "Controller")) { const char *controller; /* We can't support direct connections with this, as direct connections know no service or unique name * concept, but the Controller field stores exactly that. */ if (sd_bus_message_get_bus(message) != UNIT(s)->manager->api_bus) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Sorry, Controller= logic only supported via the bus."); r = sd_bus_message_read(message, "s", &controller); if (r < 0) return r; if (!isempty(controller) && !service_name_is_valid(controller)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Controller '%s' is not a valid bus name.", controller); if (!UNIT_WRITE_FLAGS_NOOP(flags)) { r = free_and_strdup(&s->controller, empty_to_null(controller)); if (r < 0) return r; } return 1; } return 0; }