From a831e7f367c908cec2632d02fa5365878fe83a95 Mon Sep 17 00:00:00 2001 From: jim-p Date: Thu, 20 Jun 2013 14:55:47 -0400 Subject: Activate sudo package. --- config/sudo/sudo.inc | 176 +++++++++++++++++++++++++++++++++++++++++++++++++++ config/sudo/sudo.xml | 89 ++++++++++++++++++++++++++ 2 files changed, 265 insertions(+) create mode 100644 config/sudo/sudo.inc create mode 100644 config/sudo/sudo.xml (limited to 'config/sudo') diff --git a/config/sudo/sudo.inc b/config/sudo/sudo.inc new file mode 100644 index 00000000..cfbdddbc --- /dev/null +++ b/config/sudo/sudo.inc @@ -0,0 +1,176 @@ + array( + "username" => "user:root", + "runas" => "user:root", + "cmdlist" => "ALL" + ), + 1 => array( + "username" => "user:admin", + "runas" => "user:root", + "cmdlist" => "ALL" + ), + 2 => array( + "username" => "group:admins", + "runas" => "user:root", + "cmdlist" => "ALL" + ) + ); + } +} + +function sudo_write_config() { + global $config; + $sudoers = ""; + if (!is_array($config['installedpackages']['sudo']['config'][0]['row'])) { + /* No config, wipe sudoers file and bail. */ + unlink(SUDO_SUDOERS); + log_error("No sudo configuration found, removing sudoers file to prevent unpredictable results."); + return; + } + $sudocfg = &$config['installedpackages']['sudo']['config'][0]['row']; + /* Parse the config and massage it into proper sudo config lines. */ + foreach ($sudocfg as $sudo_commands) { + // (user|group) ALL=(ALL|user spec) ALL|command list + list($etype, $ename) = explode(":", $sudo_commands['username']); + $user = ($etype == "group") ? "%{$ename}" : $ename; + list($rtype, $rname) = explode(":", $sudo_commands['runas']); + $runas = ($rtype == "group") ? ":{$rname}" : $rname; + $nopasswd = ($sudo_commands['nopasswd'] == "ON") ? "NOPASSWD:" : ""; + $commands = (empty($sudo_commands['cmdlist'])) ? "ALL" : $sudo_commands['cmdlist']; + $commands = ($commands == "all") ? "ALL" : $commands; + $sudoers .= "{$user} ALL=({$runas}) {$nopasswd} {$commands}\n"; + } + + /* Check validity of the sudoers data created above. */ + $tmpsudoers = tempnam("/tmp", "sudoers"); + file_put_contents($tmpsudoers, $sudoers); + $result = exec("/usr/local/sbin/visudo -c -f {$tmpsudoers}"); + + /* If the file is OK, move it into place with the correct permissions, otherwise log an error and trash it. */ + if (stristr($result, "parsed OK")) { + rename($tmpsudoers, SUDO_SUDOERS); + chmod(SUDO_SUDOERS, 0440); + } else { + log_error("Sudoers file invalid: {$result}"); + unlink($tmpsudoers); + } +} + +/* Get a list of users and groups in a format we can use to make proper sudoers entries. +Optionally include "ALL" as a user (for use by the Run As list) + */ +function sudo_get_users($list_all_user = false) { + global $config; + if (!is_array($config['system']['user'])) + $config['system']['user'] = array(); + $a_user = &$config['system']['user']; + if (!is_array($config['system']['group'])) + $config['system']['group'] = array(); + $a_group = &$config['system']['group']; + $users = array(); + + /* Make an entry for root, even though admin is essentially the same as root, they are distinct. */ + $tmpuser = array(); + $tmpuser["name"] = "user:root"; + $tmpuser["descr"] = "User: root"; + $users[] = $tmpuser; + + /* Add the all user if we want it */ + if ($list_all_user) { + $tmpuser = array(); + $tmpuser["name"] = "user:ALL"; + $tmpuser["descr"] = "User: ALL Users"; + $users[] = $tmpuser; + } + + foreach ($a_user as $user) { + $tmpuser = array(); + $tmpuser["name"] = "user:{$user['name']}"; + $tmpuser["descr"] = "User: {$user['name']}"; + $users[] = $tmpuser; + } + + /* Add the wheel group here. We may need other manual groups later (e.g. operator) */ + $tmpuser = array(); + $tmpuser["name"] = "group:wheel"; + $tmpuser["descr"] = "Group: wheel"; + $users[] = $tmpuser; + + foreach ($a_group as $group) { + $tmpgroup = array(); + $tmpgroup["name"] = "group:{$group['name']}"; + $tmpgroup["descr"] = "Group: {$group['name']}"; + $users[] = $tmpgroup; + } + + return $users; +} + +/* Make sure commands passed in are valid executables to help ensure a valid sudoers file and expected behavior. + This also forces the user to give full paths to executables, which they should be doing anyhow. + */ +function sudo_validate_commands($input_errors) { + $idx = 0; + while(isset($_POST["cmdlist{$idx}"])) { + $commands = $_POST["cmdlist" . $idx++]; + if (strtoupper($commands) == "ALL") + continue; + $commands = explode(",", $commands); + foreach ($commands as $command) { + list($cmd, $params) = explode(" ", trim($command), 2); + if (!is_executable($cmd)) + $input_errors[] = htmlspecialchars($cmd) . " is not an executable command."; + } + } +} +?> diff --git a/config/sudo/sudo.xml b/config/sudo/sudo.xml new file mode 100644 index 00000000..56163abf --- /dev/null +++ b/config/sudo/sudo.xml @@ -0,0 +1,89 @@ + + + Sudo Command Control + None + sudo + 0.1 + Sudo - Shell Command Privilege Delegation Utility + /usr/local/pkg/sudo.inc + + sudo + +
System
+ /pkg_edit.php?xml=sudo.xml +
+ installedpackages->package->sudo + + /usr/local/pkg/ + 077 + http://www.pfsense.com/packages/config/sudo/sudo.inc + + + + listtopic + Sudo Options + + + info +
More information on the full command options may be found in the sudoers manual. +

By default the command is "ALL" meaning the user can run any commands. Leaving the commands field blank assumes "ALL". A comma-separated list of commands can be supplied to limit the user to individual binaries. Full paths to binaries must be used. + ]]>
+
+ + User Permissions + none + rowhelper + + + User/Group + username + select_source + + descr + name + + + + Run As + runas + select_source + + descr + name + + + + No Password + nopasswd + checkbox + + + Command List + cmdlist + Commands the user may run. Comma-separated list, full paths preferred. Default: ALL + input + 30 + ALL + + + +
+ + + + + + + + + +
-- cgit v1.2.3