-1

Normally one uses visudo to edit /etc/sudoers and perhaps add a line similar to this one

kirk ALL=(spock) NOPASSWD: ALL

which will allow the kirk user to become spock.

Question

I need to create a non-interactive Bash script that will allow user1, user2, user3 to become spock.

Does anyone knows how to do that?

Sandra Schlichting
  • 25,050
  • 33
  • 110
  • 162
  • 3
    Does this answer your question? [How do I edit /etc/sudoers from a script?](https://stackoverflow.com/questions/323957/how-do-i-edit-etc-sudoers-from-a-script) – Lety Nov 26 '20 at 14:43

2 Answers2

2

visudo honors EDITOR env var which defines the editor program to use.

Thus, you can use sed as editor, tell sed to read commands from STDIN (-f-) and pass the changes to the whole visudo/sed pipline via STDIN. Example:

echo '$ a # comment' | EDITOR="sed -f- -i" visudo

This will add '# comment' line to the end of sudoers file. ($ instructs sed to append the line to the end of file, 'a' is the command to append followed by the line).

In order to add a sudoer, you will need something like

echo '$ a kirk ALL=(spock) NOPASSWD: ALL' | EDITOR="sed -f- -i" visudo

Note that visudo also does syntax check so it will fail if the command produces broken sudoers file:

root@chi:~# echo '$ a broken directive' | EDITOR="sed -f- -i" visudo
>>> /etc/sudoers: syntax error near line 44 <<<

P.S. Tested with GNU sed 4.2.2. There may be problems with e.g. Busybox sed.

Valery Panov
  • 274
  • 2
  • 6
1

Since you want to allow multiple users to be able to sudo as spock , I'd recommend adding User_Alias in you sudoers file (/etc/sudoers) for all users who can become spock

Please note, I'm using a dummy file sudoers.test in place of my /etc/sudoers for this example, it should work fine with /etc/sudoers as well.

$ cat sudoers.test
User_Alias USERS_SPOCK = kirk,bob
USERS_SPOCK ALL=(spock) NOPASSWD: ALL

Once that is done you can use something like the add_users bash script below to add users to this file.

$ cat add_users
#!/bin/env bash
# 
# Usage:
#   add_users User_Alias users [users]
#
# change it to /etc/sudoers
SUDOERS_FILE=sudoers.test

# read args to an array
IFS=', ' read -r -a arg_array <<< "$@"

# alias to add users to
alias_name=${arg_array[0]}
# array of users to add to the list
new_users=${arg_array[@]:1}

# Find the specified alias and the users associated with that alias
IFS=', ' read -r -a current_users <<< $(grep "User_Alias $alias_name" $SUDOERS_FILE | sed -e "s/User_Alias $alias_name = //g")
[ "${#current_users[@]}" = "0" ] && echo "ERR: No Users found for User_Alias: $alias_name" && exit 1

echo "== LOG.INFO Users currently in User_Alias $alias_name: ${current_users[@]} -- (${#current_users[@]} users)"
echo "== LOG.INFO New Users to be added to User_Alias $alias_name: ${new_users[@]} -- (${#new_users[@]} users)"

# All only users not currenltly there in sudoers file.
for user in ${new_users[@]}; do
    if [[ ! " ${current_users[@]} " =~ " $user " ]]; then
        current_users+=($user)
        echo "== LOG.DEBUG Adding user '$user' to User_Alias $alias_name"
    else
        echo "== LOG.WARN Skipping user '$user': already part of User_Alias $alias_name"
    fi
done

echo "== LOG.INFO After update Users in User_Alias $alias_name: ${current_users[@]} -- (${#current_users[@]} users)"

all_users=$(echo ${current_users[@]} | tr ' ' ',')

# Update the current sudoers file
sed -i "s/User_Alias $alias_name = .*$/User_Alias $alias_name = $all_users/g" $SUDOERS_FILE

[ "$?" = "0" ] && echo "== LOG.INFO Sudoers updated successfully." || echo "== LOG.ERR Some error occured while updating Sudoers."

echo "== LOG.INFO Verifying sudoers file post edit"
visudo -c $SUDOERS_FILE
$ ./add_users USERS_SPOCK alice andrew
== LOG.INFO Users currently in User_Alias USERS_SPOCK: kirk bob -- (2 users)
== LOG.INFO New Users to be added to User_Alias USERS_SPOCK: alice andrew -- (1 users)
== LOG.DEBUG Adding user 'alice' to User_Alias USERS_SPOCK
== LOG.DEBUG Adding user 'andrew' to User_Alias USERS_SPOCK
== LOG.INFO After update Users in User_Alias USERS_SPOCK: kirk bob alice andrew -- (4 users)
== LOG.INFO Sudoers updated successfully.
== LOG.INFO Verifying sudoers file post edit
sudoers.test: parsed OK
$
$ cat sudoers.test
User_Alias USERS_SPOCK = kirk,bob,alice,andrew
USERS_SPOCK ALL=(spock) NOPASSWD: ALL
$

After these changes are made in /etc/sudoers as root. Any of the member of User Alias USERS_SPOCK can run any command as spock

alice$ sudo -u spock <random command>
alice$ sudo -u spock <my awesome script>
imthor
  • 563
  • 3
  • 6