364 const bool operation_success)
const
366 const CommandResult status_result = run_command({
371 snapshot.
service = parse_status(status_result.output);
372 snapshot.events = read_recent_events(400);
373 snapshot.application_rules = read_application_rules();
374 snapshot.operation_message = operation_message;
375 snapshot.operation_success = operation_success;
376 if (snapshot.service.state ==
"unknown" && status_result.exit_code != 0)
377 snapshot.service.state =
"unavailable";
391 return command_success(run_command({
393 }), std::string(
"RootGuard action completed: ") + action, message);
397 const auto result = run_command({
399 "set-protection",
"--state", request.
enabled ?
"on" :
"off"
401 if (!command_success(result,
"RootGuard protection mode updated.", message))
403 const auto reload = run_command({
406 std::string reloadMessage;
407 const bool reloadSuccess = command_success(
408 reload,
"RootGuard policy reloaded.", reloadMessage);
409 if (!reloadMessage.empty())
410 message +=
" " + reloadMessage;
411 if (!reloadSuccess && request.
enabled) {
412 const auto rollback = run_command({
414 "set-protection",
"--state",
"off"
416 std::string rollbackMessage;
417 const bool rollbackSuccess = command_success(
418 rollback,
"Unsafe future enablement was rolled back to audit mode.",
420 message += rollbackSuccess
421 ?
" " + rollbackMessage
422 :
" WARNING: the policy rollback to audit mode failed: " + rollbackMessage;
424 return reloadSuccess;
428 std::vector<std::string> command {
431 "set-application-rules"
433 const auto appendRules = [&command](
const char* option,
434 const std::vector<std::string>& entries) {
435 for (
const auto& entry : entries) {
436 command.emplace_back(option);
437 command.push_back(entry);
440 appendRules(
"--trusted-application",
442 appendRules(
"--trusted-executable",
444 appendRules(
"--denied-executable",
447 const auto saveResult = run_command(command);
448 if (!command_success(saveResult,
449 "RootGuard application rules saved.", message))
452 const auto restartResult = run_command({
457 std::string restartMessage;
458 const bool restartSuccess = command_success(
459 restartResult,
"RootGuard restarted with the new rules.",
461 if (!restartMessage.empty())
462 message +=
" " + restartMessage;
463 return restartSuccess;
469 if (event.filename.empty()) {
470 message =
"The incident has no actionable path.";
475 const bool metadataAvailable =
event.old_mode != 0 ||
event.new_mode != 0 ||
476 event.old_uid != 0 ||
event.new_uid != 0 ||
477 event.old_gid != 0 ||
event.new_gid != 0;
478 if (!metadataAvailable) {
480 return command_success(run_command({
482 "unblock-service",
"--path",
event.filename
483 }),
"The blocked service was unmasked. It was not restarted.", message);
485 message =
"The change was denied before it was committed; no metadata restoration was required.";
488 return command_success(run_command({
490 "restore",
"--path",
event.filename,
491 "--mode", octal_argument(event.old_mode),
492 "--uid", std::to_string(event.old_uid),
493 "--gid", std::to_string(event.old_gid),
494 "--device", std::to_string(event.device),
495 "--inode", std::to_string(event.inode)
496 }),
"Protected metadata restored.", message);
500 return command_success(run_command({
502 "remove",
"--path",
event.filename,
503 "--device", std::to_string(event.device),
504 "--inode", std::to_string(event.inode)
505 }),
"The file was removed and quarantined.", message);