typedef struct {
int fd;
+ SharedPolicy *policy;
+ uid_t bus_uid;
} ClientContext;
static ClientContext *client_context_free(ClientContext *c) {
DEFINE_TRIVIAL_CLEANUP_FUNC(ClientContext*, client_context_free);
-static int client_context_new(ClientContext **out, int fd) {
+static int client_context_new(ClientContext **out) {
_cleanup_(client_context_freep) ClientContext *c = NULL;
c = new0(ClientContext, 1);
if (!c)
return log_oom();
- c->fd = fd;
+ c->fd = -1;
*out = c;
c = NULL;
comm[sizeof(comm) - 2] = '*';
(void) prctl(PR_SET_NAME, comm);
- r = proxy_load_policy(p, arg_configuration);
+ r = proxy_set_policy(p, c->policy, arg_configuration);
if (r < 0)
goto exit;
- r = proxy_hello_policy(p, getuid());
+ r = proxy_hello_policy(p, c->bus_uid);
if (r < 0)
goto exit;
return NULL;
}
-static int loop_clients(int accept_fd) {
+static int loop_clients(int accept_fd, uid_t bus_uid) {
+ _cleanup_(shared_policy_freep) SharedPolicy *sp = NULL;
pthread_attr_t attr;
int r;
goto exit_attr;
}
+ r = shared_policy_new(&sp);
+ if (r < 0)
+ goto exit_attr;
+
for (;;) {
ClientContext *c;
pthread_t tid;
break;
}
- r = client_context_new(&c, fd);
+ r = client_context_new(&c);
if (r < 0) {
log_oom();
close(fd);
continue;
}
+ c->fd = fd;
+ c->policy = sp;
+ c->bus_uid = bus_uid;
+
r = pthread_create(&tid, &attr, run_client, c);
if (r < 0) {
log_error("Cannot spawn thread: %m");
}
int main(int argc, char *argv[]) {
+ const char *user = "systemd-bus-proxy";
int r, accept_fd;
+ uid_t uid, bus_uid;
+ gid_t gid;
log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
log_parse_environment();
log_open();
+ bus_uid = getuid();
+
+ if (geteuid() == 0) {
+ r = get_user_creds(&user, &uid, &gid, NULL, NULL);
+ if (r < 0) {
+ log_error_errno(r, "Cannot resolve user name %s: %m", user);
+ goto finish;
+ }
+
+ r = drop_privileges(uid, gid, 1ULL << CAP_IPC_OWNER);
+ if (r < 0) {
+ log_error_errno(r, "Cannot drop privileges: %m");
+ goto finish;
+ }
+ }
+
r = parse_argv(argc, argv);
if (r <= 0)
goto finish;
goto finish;
}
- r = loop_clients(accept_fd);
+ r = loop_clients(accept_fd, bus_uid);
finish:
sd_notify(false,