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);
88 DBusMessage *m = NULL, *reply = NULL;
89 const char *unix_process = "unix-process", *pid = "pid", *starttime = "start-time", *cancel_id = "";
91 uint32_t flags = interactive ? 1 : 0;
94 unsigned long long starttime_raw;
95 uint64_t starttime_u64;
96 DBusMessageIter iter_msg, iter_struct, iter_array, iter_dict, iter_variant;
98 dbus_bool_t authorized = FALSE, challenge = FALSE;
103 sender = dbus_message_get_sender(request);
107 pid_raw = get_unix_process_id(c, sender, error);
111 r = get_starttime_of_pid(pid_raw, &starttime_raw);
115 m = dbus_message_new_method_call(
116 "org.freedesktop.PolicyKit1",
117 "/org/freedesktop/PolicyKit1/Authority",
118 "org.freedesktop.PolicyKit1.Authority",
119 "CheckAuthorization");
123 dbus_message_iter_init_append(m, &iter_msg);
125 pid_u32 = (uint32_t) pid_raw;
126 starttime_u64 = (uint64_t) starttime_raw;
128 if (!dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_STRUCT, NULL, &iter_struct) ||
129 !dbus_message_iter_append_basic(&iter_struct, DBUS_TYPE_STRING, &unix_process) ||
130 !dbus_message_iter_open_container(&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_array) ||
131 !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) ||
132 !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &pid) ||
133 !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "u", &iter_variant) ||
134 !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT32, &pid_u32) ||
135 !dbus_message_iter_close_container(&iter_dict, &iter_variant) ||
136 !dbus_message_iter_close_container(&iter_array, &iter_dict) ||
137 !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) ||
138 !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &starttime) ||
139 !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "t", &iter_variant) ||
140 !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT64, &starttime_u64) ||
141 !dbus_message_iter_close_container(&iter_dict, &iter_variant) ||
142 !dbus_message_iter_close_container(&iter_array, &iter_dict) ||
143 !dbus_message_iter_close_container(&iter_struct, &iter_array) ||
144 !dbus_message_iter_close_container(&iter_msg, &iter_struct) ||
145 !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &action) ||
146 !dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_ARRAY, "{ss}", &iter_array) ||
147 !dbus_message_iter_close_container(&iter_msg, &iter_array) ||
148 !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_UINT32, &flags) ||
149 !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &cancel_id)) {
154 reply = dbus_connection_send_with_reply_and_block(c, m, -1, error);
160 if (dbus_set_error_from_message(error, reply)) {
165 if (!dbus_message_iter_init(reply, &iter_msg) ||
166 dbus_message_iter_get_arg_type(&iter_msg) != DBUS_TYPE_STRUCT) {
171 dbus_message_iter_recurse(&iter_msg, &iter_struct);
173 if (dbus_message_iter_get_arg_type(&iter_struct) != DBUS_TYPE_BOOLEAN) {
178 dbus_message_iter_get_basic(&iter_struct, &authorized);
180 if (!dbus_message_iter_next(&iter_struct) ||
181 dbus_message_iter_get_arg_type(&iter_struct) != DBUS_TYPE_BOOLEAN) {
186 dbus_message_iter_get_basic(&iter_struct, &challenge);
190 else if (_challenge) {
191 *_challenge = !!challenge;
199 dbus_message_unref(m);
202 dbus_message_unref(reply);