1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2011 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/types.h>
27 #include "dbus-common.h"
30 /* This mimics dbus_bus_get_unix_user() */
31 static pid_t get_unix_process_id(
32 DBusConnection *connection,
36 DBusMessage *m = NULL, *reply = NULL;
39 m = dbus_message_new_method_call(
43 "GetConnectionUnixProcessID");
45 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL);
49 if (!dbus_message_append_args(
51 DBUS_TYPE_STRING, &name,
53 dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL);
57 reply = dbus_connection_send_with_reply_and_block(connection, m, -1, error);
61 if (dbus_set_error_from_message(error, reply))
64 if (!dbus_message_get_args(
66 DBUS_TYPE_UINT32, &pid,
72 dbus_message_unref(m);
75 dbus_message_unref(reply);
87 DBusMessage *m = NULL, *reply = NULL;
88 const char *unix_process = "unix-process", *pid = "pid", *starttime = "start-time", *cancel_id = "";
90 uint32_t flags = interactive ? 1 : 0;
93 unsigned long long starttime_raw;
94 uint64_t starttime_u64;
95 DBusMessageIter iter_msg, iter_struct, iter_array, iter_dict, iter_variant;
97 dbus_bool_t authorized = FALSE;
102 sender = dbus_message_get_sender(request);
106 pid_raw = get_unix_process_id(c, sender, error);
110 r = get_starttime_of_pid(pid_raw, &starttime_raw);
114 m = dbus_message_new_method_call(
115 "org.freedesktop.PolicyKit1",
116 "/org/freedesktop/PolicyKit1/Authority",
117 "org.freedesktop.PolicyKit1.Authority",
118 "CheckAuthorization");
122 dbus_message_iter_init_append(m, &iter_msg);
124 pid_u32 = (uint32_t) pid_raw;
125 starttime_u64 = (uint64_t) starttime_raw;
127 if (!dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_STRUCT, NULL, &iter_struct) ||
128 !dbus_message_iter_append_basic(&iter_struct, DBUS_TYPE_STRING, &unix_process) ||
129 !dbus_message_iter_open_container(&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_array) ||
130 !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) ||
131 !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &pid) ||
132 !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "u", &iter_variant) ||
133 !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT32, &pid_u32) ||
134 !dbus_message_iter_close_container(&iter_dict, &iter_variant) ||
135 !dbus_message_iter_close_container(&iter_array, &iter_dict) ||
136 !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) ||
137 !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &starttime) ||
138 !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "t", &iter_variant) ||
139 !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT64, &starttime_u64) ||
140 !dbus_message_iter_close_container(&iter_dict, &iter_variant) ||
141 !dbus_message_iter_close_container(&iter_array, &iter_dict) ||
142 !dbus_message_iter_close_container(&iter_struct, &iter_array) ||
143 !dbus_message_iter_close_container(&iter_msg, &iter_struct) ||
144 !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &action) ||
145 !dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_ARRAY, "{ss}", &iter_array) ||
146 !dbus_message_iter_close_container(&iter_msg, &iter_array) ||
147 !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_UINT32, &flags) ||
148 !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &cancel_id)) {
153 reply = dbus_connection_send_with_reply_and_block(c, m, -1, error);
159 if (dbus_set_error_from_message(error, reply)) {
164 if (!dbus_message_iter_init(reply, &iter_msg) ||
165 dbus_message_iter_get_arg_type(&iter_msg) != DBUS_TYPE_STRUCT) {
170 dbus_message_iter_recurse(&iter_msg, &iter_struct);
172 if (dbus_message_iter_get_arg_type(&iter_struct) != DBUS_TYPE_BOOLEAN) {
177 dbus_message_iter_get_basic(&iter_struct, &authorized);
179 r = authorized ? 0 : -EPERM;
184 dbus_message_unref(m);
187 dbus_message_unref(reply);