mod convert;
mod json;
use std::{cell::RefCell, error::Error, rc::Rc};
use json::{
cmd_setpolicy, cmd_whitelist_action, cred_caps, cred_set, cred_setpolicy, cred_unset,
env_set_policylist, env_setlist_add, env_setpolicy, env_whitelist_set, grant_revoke,
path_purge, path_set, path_setlist2, path_setpolicy, role_add_del, set_authentication,
set_bounding, set_execinfo, set_privileged, set_timeout, set_umask, task_add_del,
unset_timeout,
};
use log::debug;
use rootasrole_core::{
database::{
options::{Opt, OptType},
structs::{IdTask, RoleGetter},
},
file::FileSettings,
};
use crate::cli::process::json::{
workdir_purge, workdir_set_path, workdir_setlist, workdir_setpolicy,
};
use super::{
data::{InputAction, Inputs},
usage,
};
#[allow(clippy::too_many_lines)]
pub fn process_input(storage: &mut FileSettings, inputs: Inputs) -> Result<bool, Box<dyn Error>> {
if inputs.action == InputAction::Convert {
debug!("chsr convert");
return convert::convert(
storage,
inputs
.convertion
.expect("Convertion data should be present"),
inputs.convert_reconfigure,
);
}
let rconfig = &storage.get_root().config;
match inputs {
Inputs {
action: InputAction::Help,
..
} => {
usage::help();
Ok(false)
}
Inputs {
action: InputAction::List,
options, role_id,
role_type,
task_id,
task_type, options_type, ..
} => {
debug!("chsr list");
match json::list_json(
rconfig,
role_id.as_ref(),
task_id,
options,
options_type,
task_type,
role_type,
) {
Ok(()) => {
debug!("chsr list ok");
Ok(false)
}
Err(e) => {
debug!("chsr list err {e:?}");
Err(e)
}
}
}
Inputs {
action,
role_id: Some(role_id),
task_id: None,
setlist_type: None,
options: false,
actors: None,
role_type,
..
} => role_add_del(rconfig, action, role_id, role_type),
Inputs {
action,
role_id: Some(role_id),
actors: Some(actors),
options: false,
..
} => grant_revoke(rconfig, &role_id, action, actors),
Inputs {
action,
role_id: Some(role_id),
task_id: Some(task_id),
setlist_type: None,
options: false,
cmd_id: None,
cred_caps: None,
cred_setuid: None,
cred_setgid: None,
task_type,
cmd_policy: None,
cred_policy: None,
..
} => task_add_del(rconfig, &role_id, action, task_id, task_type),
Inputs {
action: InputAction::Set,
role_id: Some(role_id),
task_id: Some(task_id),
cred_caps,
cred_setuid,
cred_setgid,
cmd_id: None,
cmd_policy: None,
cred_policy: None,
options: false,
..
} => cred_set(
rconfig,
&role_id,
task_id,
cred_caps,
cred_setuid,
cred_setgid,
),
Inputs {
action: InputAction::Del,
role_id: Some(role_id),
task_id: Some(task_id),
cred_caps,
cred_setuid,
cred_setgid,
cmd_id: None,
cmd_policy: None,
options: false,
setlist_type: None,
..
} => cred_unset(
rconfig,
&role_id,
task_id,
cred_caps,
cred_setuid.as_ref(),
cred_setgid.as_ref(),
),
Inputs {
action,
role_id: Some(role_id),
task_id: Some(task_id),
setlist_type: Some(setlist_type),
cred_caps: Some(pcred_caps),
cmd_policy: None,
options: false,
..
} => cred_caps(rconfig, &role_id, task_id, setlist_type, action, pcred_caps),
Inputs {
role_id: Some(role_id),
task_id: Some(task_id),
cred_policy: Some(cred_policy),
options: false,
..
} => cred_setpolicy(rconfig, &role_id, task_id, cred_policy),
Inputs {
action,
role_id: Some(role_id),
task_id: Some(task_id),
cmd_id: Some(cmd_id),
setlist_type: Some(setlist_type),
..
} => cmd_whitelist_action(rconfig, &role_id, task_id, cmd_id, setlist_type, action),
Inputs {
role_id: Some(role_id),
task_id: Some(task_id),
cmd_policy: Some(cmd_policy),
..
} => cmd_setpolicy(rconfig, &role_id, task_id, cmd_policy),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options_type: Some(OptType::Env),
options_env_policy: Some(options_env_policy),
options_key_env: Some(options_env),
..
} => env_set_policylist(
rconfig,
role_id.as_ref(),
task_id,
&options_env,
options_env_policy,
),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options_root: Some(options_root),
..
} => set_privileged(rconfig, role_id.as_ref(), task_id, Some(options_root)),
Inputs {
action: InputAction::Del,
role_id,
task_id,
options_root: Some(_),
..
} => set_privileged(rconfig, role_id.as_ref(), task_id, None),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options_bounding: Some(options_bounding),
..
} => set_bounding(rconfig, role_id.as_ref(), task_id, Some(options_bounding)),
Inputs {
action: InputAction::Del,
role_id,
task_id,
options_bounding: Some(_),
..
} => set_bounding(rconfig, role_id.as_ref(), task_id, None),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options_auth: Some(options_auth),
..
} => set_authentication(rconfig, role_id.as_ref(), task_id, Some(options_auth)),
Inputs {
action: InputAction::Del,
role_id,
task_id,
options_auth: Some(_),
..
} => set_authentication(rconfig, role_id.as_ref(), task_id, None),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options_execinfo: Some(options_execinfo),
..
} => set_execinfo(rconfig, role_id.as_ref(), task_id, Some(options_execinfo)),
Inputs {
action: InputAction::Del,
role_id,
task_id,
options_execinfo: Some(_),
..
} => set_execinfo(rconfig, role_id.as_ref(), task_id, None),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options_umask: Some(options_umask),
..
} => set_umask(rconfig, role_id.as_ref(), task_id, Some(options_umask)),
Inputs {
action: InputAction::Del,
role_id,
task_id,
options_umask: Some(_),
..
} => set_umask(rconfig, role_id.as_ref(), task_id, None),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options_path: Some(options_path),
options_type: Some(OptType::Path),
setlist_type,
..
} => path_set(
rconfig,
role_id.as_ref(),
task_id,
setlist_type,
&options_path,
),
Inputs {
action: InputAction::Purge,
role_id,
task_id,
options_path: None,
options_type: Some(OptType::Path),
setlist_type,
..
} => path_purge(rconfig, role_id.as_ref(), task_id, setlist_type),
Inputs {
action: InputAction::Purge,
role_id,
task_id,
options_path: None,
options_type: Some(OptType::Workdir),
setlist_type,
..
} => workdir_purge(rconfig, role_id.as_ref(), task_id, setlist_type),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options_key_env: Some(options_env),
options_type: Some(OptType::Env),
setlist_type,
options_env_values: None,
options_env_policy: None,
..
} => env_whitelist_set(
rconfig,
role_id.as_ref(),
task_id,
setlist_type.as_ref(),
&options_env,
),
Inputs {
action: InputAction::Del,
role_id,
task_id,
options: true,
timeout_arg: Some(timeout_arg),
setlist_type: None,
..
} => unset_timeout(rconfig, role_id.as_ref(), task_id, timeout_arg),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options: true,
timeout_arg: Some(_),
timeout_type,
timeout_duration,
timeout_max_usage,
..
} => set_timeout(
rconfig,
role_id.as_ref(),
task_id,
timeout_type,
timeout_duration,
timeout_max_usage,
),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options_type: Some(OptType::Path),
options_path_policy: Some(options_path_policy),
..
} => path_setpolicy(rconfig, role_id.as_ref(), task_id, options_path_policy),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options_type: Some(OptType::Workdir),
options_workdir_policy: Some(options_workdir_policy),
..
} => workdir_setpolicy(rconfig, role_id.as_ref(), task_id, options_workdir_policy),
Inputs {
action,
role_id,
task_id,
options_key_env,
options_env_values,
options_type: Some(OptType::Env),
setlist_type,
options_env_policy: None,
..
} => env_setlist_add(
rconfig,
role_id.as_ref(),
task_id,
setlist_type,
action,
options_key_env,
options_env_values,
),
Inputs {
action,
role_id,
task_id,
options_path: Some(options_path),
options_type: Some(OptType::Path),
setlist_type,
..
} => path_setlist2(
rconfig,
role_id.as_ref(),
task_id,
setlist_type,
action,
&options_path,
),
Inputs {
action: InputAction::Set,
role_id,
task_id,
options_path: Some(options_path),
options_type: Some(OptType::Workdir),
setlist_type: None,
..
} => workdir_set_path(rconfig, role_id.as_ref(), task_id, options_path.as_str()),
Inputs {
action,
role_id,
task_id,
options_path: Some(options_path),
options_type: Some(OptType::Workdir),
setlist_type,
..
} => workdir_setlist(
rconfig,
role_id.as_ref(),
task_id,
setlist_type,
action,
&options_path,
),
Inputs {
role_id,
task_id,
options_type: Some(OptType::Env),
options_env_policy: Some(options_env_policy),
options_key_env: None,
..
} => env_setpolicy(rconfig, role_id.as_ref(), task_id, options_env_policy),
_ => Err("Unknown Input".into()),
}
}
pub fn perform_on_target_opt(
rconfig: &Rc<RefCell<rootasrole_core::database::structs::SPolicy>>,
role_id: Option<&String>,
task_id: Option<IdTask>,
exec_on_opt: impl Fn(Rc<RefCell<Opt>>) -> Result<(), Box<dyn Error>>,
) -> Result<(), Box<dyn Error>> {
fn execute_or_create_option(
exec_on_opt: impl Fn(Rc<RefCell<Opt>>) -> Result<(), Box<dyn Error>>,
options: &mut Option<Rc<RefCell<Opt>>>,
) -> Result<(), Box<dyn Error>> {
if let Some(opt) = options {
exec_on_opt(opt.clone())
} else {
let new_opt = Rc::new(RefCell::new(Opt::default()));
let result = exec_on_opt(new_opt.clone());
*options = Some(new_opt);
result
}
}
if let Some(role_id) = role_id {
let role = rconfig.role(role_id).ok_or("Role not found")?;
let mut role_borrowed = role.as_ref().borrow_mut();
if let Some(task_id) = task_id {
let task = role_borrowed.task(&task_id).ok_or("Task not found")?;
return execute_or_create_option(exec_on_opt, &mut task.as_ref().borrow_mut().options);
}
return execute_or_create_option(exec_on_opt, &mut role_borrowed.options);
}
execute_or_create_option(exec_on_opt, &mut rconfig.as_ref().borrow_mut().options)
}