1use super::{command_mechanism, ActionSpec};
2use sysknife_types::RiskLevel;
3
4pub fn specs() -> Vec<ActionSpec> {
5 vec![
6 list_users(),
7 list_groups(),
8 create_user("alice", Some("/bin/bash"), Some("/home/alice")),
9 delete_user("alice"),
10 add_user_to_group("alice", "wheel"),
11 remove_user_from_group("alice", "wheel"),
12 create_group("developers", false),
13 delete_group("developers"),
14 lock_user_account("alice"),
15 unlock_user_account("alice"),
16 ]
17}
18
19pub fn list_users() -> ActionSpec {
20 ActionSpec {
21 action_name: "ListUsers",
22 mechanism: command_mechanism("getent", ["passwd"]),
23 risk_level: RiskLevel::Low,
24 reboot_required: false,
25 rollback_available: false,
26 }
27}
28
29pub fn list_groups() -> ActionSpec {
30 ActionSpec {
31 action_name: "ListGroups",
32 mechanism: command_mechanism("getent", ["group"]),
33 risk_level: RiskLevel::Low,
34 reboot_required: false,
35 rollback_available: false,
36 }
37}
38
39pub fn create_user(username: &str, shell: Option<&str>, home: Option<&str>) -> ActionSpec {
40 let mut args = vec!["useradd".to_string(), "--create-home".to_string()];
41 if let Some(home) = home {
42 args.push("--home-dir".to_string());
43 args.push(home.to_string());
44 }
45 if let Some(shell) = shell {
46 args.push("--shell".to_string());
47 args.push(shell.to_string());
48 }
49 args.push(username.to_string());
50
51 ActionSpec {
52 action_name: "CreateUser",
53 mechanism: super::ActionMechanism::Command {
54 program: "sudo",
55 args,
56 },
57 risk_level: RiskLevel::High,
58 reboot_required: false,
59 rollback_available: false,
60 }
61}
62
63pub fn delete_user(username: &str) -> ActionSpec {
64 ActionSpec {
65 action_name: "DeleteUser",
66 mechanism: command_mechanism("sudo", ["userdel", username]),
67 risk_level: RiskLevel::High,
70 reboot_required: false,
71 rollback_available: false,
72 }
73}
74
75pub fn add_user_to_group(username: &str, group: &str) -> ActionSpec {
76 let script = format!(
82 "grep -q '^{}:' /etc/group || getent group '{}' >> /etc/group; usermod --append --groups '{}' '{}'",
83 group, group, group, username
84 );
85 ActionSpec {
86 action_name: "AddUserToGroup",
87 mechanism: command_mechanism("sudo", ["sh", "-c", script.as_str()]),
88 risk_level: RiskLevel::High,
92 reboot_required: false,
93 rollback_available: false,
94 }
95}
96
97pub fn remove_user_from_group(username: &str, group: &str) -> ActionSpec {
98 let script = format!(
102 "grep -q '^{}:' /etc/group || getent group '{}' >> /etc/group; gpasswd --delete '{}' '{}'",
103 group, group, username, group
104 );
105 ActionSpec {
106 action_name: "RemoveUserFromGroup",
107 mechanism: command_mechanism("sudo", ["sh", "-c", script.as_str()]),
108 risk_level: RiskLevel::High,
111 reboot_required: false,
112 rollback_available: false,
113 }
114}
115
116pub fn create_group(group: &str, system: bool) -> ActionSpec {
122 let mut args = vec!["groupadd".to_string()];
123 if system {
124 args.push("--system".to_string());
125 }
126 args.push(group.to_string());
127 ActionSpec {
128 action_name: "CreateGroup",
129 mechanism: super::ActionMechanism::Command {
130 program: "sudo",
131 args,
132 },
133 risk_level: RiskLevel::High,
134 reboot_required: false,
135 rollback_available: false,
136 }
137}
138
139pub fn delete_group(group: &str) -> ActionSpec {
145 ActionSpec {
146 action_name: "DeleteGroup",
147 mechanism: command_mechanism("sudo", ["groupdel", group]),
148 risk_level: RiskLevel::High,
149 reboot_required: false,
150 rollback_available: false,
151 }
152}
153
154pub fn lock_user_account(username: &str) -> ActionSpec {
160 ActionSpec {
161 action_name: "LockUserAccount",
162 mechanism: command_mechanism("sudo", ["usermod", "--lock", username]),
163 risk_level: RiskLevel::High,
164 reboot_required: false,
165 rollback_available: false,
166 }
167}
168
169pub fn unlock_user_account(username: &str) -> ActionSpec {
174 ActionSpec {
175 action_name: "UnlockUserAccount",
176 mechanism: command_mechanism("sudo", ["usermod", "--unlock", username]),
177 risk_level: RiskLevel::High,
178 reboot_required: false,
179 rollback_available: false,
180 }
181}