static int bus_get_audit_data( DBusConnection *connection, const char *name, struct auditstruct *audit, DBusError *error) { pid_t pid; int r; pid = bus_get_unix_process_id(connection, name, error); if (pid <= 0) return -EIO; r = audit_loginuid_from_pid(pid, &audit->loginuid); if (r < 0) return r; r = get_process_uid(pid, &audit->uid); if (r < 0) return r; r = get_process_gid(pid, &audit->gid); if (r < 0) return r; r = get_process_cmdline(pid, LINE_MAX, true, &audit->cmdline); if (r < 0) return r; return 0; }
static int bus_get_selinux_security_context( DBusConnection *connection, const char *name, char **scon, DBusError *error) { _cleanup_dbus_message_unref_ DBusMessage *m = NULL, *reply = NULL; DBusMessageIter iter, sub; const char *bytes; char *b; int nbytes; m = dbus_message_new_method_call( DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS, "GetConnectionSELinuxSecurityContext"); if (!m) { dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); return -ENOMEM; } if (!dbus_message_append_args( m, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) { dbus_set_error_const(error, DBUS_ERROR_NO_MEMORY, NULL); return -ENOMEM; } reply = dbus_connection_send_with_reply_and_block(connection, m, -1, error); if (!reply) return -EIO; if (dbus_set_error_from_message(error, reply)) return -EIO; if (!dbus_message_iter_init(reply, &iter)) return -EIO; if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) return -EIO; dbus_message_iter_recurse(&iter, &sub); dbus_message_iter_get_fixed_array(&sub, &bytes, &nbytes); b = strndup(bytes, nbytes); if (!b) return -ENOMEM; *scon = b; log_debug("GetConnectionSELinuxSecurityContext %s (pid %ld)", *scon, (long) bus_get_unix_process_id(connection, name, error)); return 0; }
int verify_polkit( DBusConnection *c, DBusMessage *request, const char *action, bool interactive, bool *_challenge, DBusError *error) { #ifdef ENABLE_POLKIT DBusMessage *m = NULL, *reply = NULL; const char *unix_process = "unix-process", *pid = "pid", *starttime = "start-time", *cancel_id = ""; uint32_t flags = interactive ? 1 : 0; pid_t pid_raw; uint32_t pid_u32; unsigned long long starttime_raw; uint64_t starttime_u64; DBusMessageIter iter_msg, iter_struct, iter_array, iter_dict, iter_variant; int r; dbus_bool_t authorized = FALSE, challenge = FALSE; #endif const char *sender; unsigned long ul; assert(c); assert(request); sender = dbus_message_get_sender(request); if (!sender) return -EINVAL; ul = dbus_bus_get_unix_user(c, sender, error); if (ul == (unsigned long) -1) return -EINVAL; /* Shortcut things for root, to avoid the PK roundtrip and dependency */ if (ul == 0) return 1; #ifdef ENABLE_POLKIT pid_raw = bus_get_unix_process_id(c, sender, error); if (pid_raw == 0) return -EINVAL; r = get_starttime_of_pid(pid_raw, &starttime_raw); if (r < 0) return r; m = dbus_message_new_method_call( "org.freedesktop.PolicyKit1", "/org/freedesktop/PolicyKit1/Authority", "org.freedesktop.PolicyKit1.Authority", "CheckAuthorization"); if (!m) return -ENOMEM; dbus_message_iter_init_append(m, &iter_msg); pid_u32 = (uint32_t) pid_raw; starttime_u64 = (uint64_t) starttime_raw; if (!dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_STRUCT, NULL, &iter_struct) || !dbus_message_iter_append_basic(&iter_struct, DBUS_TYPE_STRING, &unix_process) || !dbus_message_iter_open_container(&iter_struct, DBUS_TYPE_ARRAY, "{sv}", &iter_array) || !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) || !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &pid) || !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "u", &iter_variant) || !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT32, &pid_u32) || !dbus_message_iter_close_container(&iter_dict, &iter_variant) || !dbus_message_iter_close_container(&iter_array, &iter_dict) || !dbus_message_iter_open_container(&iter_array, DBUS_TYPE_DICT_ENTRY, NULL, &iter_dict) || !dbus_message_iter_append_basic(&iter_dict, DBUS_TYPE_STRING, &starttime) || !dbus_message_iter_open_container(&iter_dict, DBUS_TYPE_VARIANT, "t", &iter_variant) || !dbus_message_iter_append_basic(&iter_variant, DBUS_TYPE_UINT64, &starttime_u64) || !dbus_message_iter_close_container(&iter_dict, &iter_variant) || !dbus_message_iter_close_container(&iter_array, &iter_dict) || !dbus_message_iter_close_container(&iter_struct, &iter_array) || !dbus_message_iter_close_container(&iter_msg, &iter_struct) || !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &action) || !dbus_message_iter_open_container(&iter_msg, DBUS_TYPE_ARRAY, "{ss}", &iter_array) || !dbus_message_iter_close_container(&iter_msg, &iter_array) || !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_UINT32, &flags) || !dbus_message_iter_append_basic(&iter_msg, DBUS_TYPE_STRING, &cancel_id)) { r = -ENOMEM; goto finish; } reply = dbus_connection_send_with_reply_and_block(c, m, -1, error); if (!reply) { /* Treat no PK available as access denied */ if (dbus_error_has_name(error, DBUS_ERROR_SERVICE_UNKNOWN)) { r = -EACCES; dbus_error_free(error); goto finish; } r = -EIO; goto finish; } if (!dbus_message_iter_init(reply, &iter_msg) || dbus_message_iter_get_arg_type(&iter_msg) != DBUS_TYPE_STRUCT) { r = -EIO; goto finish; } dbus_message_iter_recurse(&iter_msg, &iter_struct); if (dbus_message_iter_get_arg_type(&iter_struct) != DBUS_TYPE_BOOLEAN) { r = -EIO; goto finish; } dbus_message_iter_get_basic(&iter_struct, &authorized); if (!dbus_message_iter_next(&iter_struct) || dbus_message_iter_get_arg_type(&iter_struct) != DBUS_TYPE_BOOLEAN) { r = -EIO; goto finish; } dbus_message_iter_get_basic(&iter_struct, &challenge); if (authorized) r = 1; else if (_challenge) { *_challenge = !!challenge; r = 0; } else r = -EPERM; finish: if (m) dbus_message_unref(m); if (reply) dbus_message_unref(reply); return r; #else return -EPERM; #endif }