n-alexander
n-alexander

Reputation: 15363

How do I edit /etc/sudoers from a script?

I need to edit /etc/sudoers from a script to add/remove stuff from white lists.

Assuming I have a command that would work on a normal file, how could I apply it to /etc/sudoers?

Can I copy and modify it, then have visudo replace the original with the modified copy? By providing my own script in $EDITOR?

Or can I just use the same locks and cp?

The question is more about potential issues than about just finding something that works.

Upvotes: 148

Views: 109738

Answers (14)

DrInk
DrInk

Reputation: 38

Since this question has much more pv than this one, and sed is more flexible comparing to tee, I'll just leave the link to a "better" solution and my solution here.

Based on Valery Panov's answer, I wrote this

echo 's/^#\s*\(%wheel\s*ALL=(ALL)\s*ALL\)/\1/g' | EDITOR='sed -f- -i' visudo

to uncomment this line in /etc/sudoers

# %wheel  ALL=(ALL)       ALL

Upvotes: 0

pevik
pevik

Reputation: 4781

On most distributions (at least Debian-based, Redhat-based, openSUSE-based, etc.), you can insert a custom script into the /etc/sudoers.d/ directory, with rights 0440 - For more information see man sudo ("Including other files from within sudo") or the same information on the official site.

It might help.

Upvotes: 25

Adam Mazurkiewicz
Adam Mazurkiewicz

Reputation: 91

This is the solution I came up with. It's a quick and dirty solution, but it works...

echo "username ALL=(ALL) NOPASSWD:ALL" | sudo tee -a /etc/sudoers

It pipes the echo output into tee which is running under sudo. Tee then appends the output into the sudoers file.

Upvotes: 5

Albert Vonpupp
Albert Vonpupp

Reputation: 4867

I think the most straight forward solution is to:

Create a script addsudoers.sh

#!/bin/sh

while [ -n "$1" ]; do
    echo "$1    ALL=(ALL:ALL) ALL" >> /etc/sudoers;
    shift # shift all parameters
done

and call it with the users you want to add it as:

root prompt> ./addsudoers.sh user1 user2

For the full explanation see this answer: Adding users to sudoers through shell script

Regards!

Upvotes: 4

Im-Kirk-Dougla-Cus
Im-Kirk-Dougla-Cus

Reputation: 141

Lots of answers, been working with sudo for yonks but did not have a need to automate the setup config till now. I used a mix of some of the answers above, writing my config line to the /etc/sudoers.d include location so i don't have to modify the main sudoers file, then checked that file for syntax , simple example below:

Write your line to a sudoers include file:

sudo bash -c 'echo "your_user ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers.d/99_sudo_include_file'

Check that your sudoers include file passed the visudo syntax checks:

sudo visudo -cf /etc/sudoers.d/99_sudo_include_file

Upvotes: 10

Mnebuerquo
Mnebuerquo

Reputation: 5949

If your sudo allows adding entries in /etc/sudoers.d, then you can use this answer by @dragon788:

https://superuser.com/a/1027257/26022

Basically you use visudo to verify the file before you copy it into /etc/sudoers.d, so you can be sure you're not breaking sudo for anyone.

visudo -c -q -f filename

This checks it and returns success (0) if it's valid, so you can use it with if, && and other script boolean operations. Once you validate, just copy it into /etc/sudoers.d and it should work. Make sure its owned by root and not writable by other.

Upvotes: 10

beckerr
beckerr

Reputation: 2011

Old thread, but what about:

echo 'foobar ALL=(ALL:ALL) ALL' | sudo EDITOR='tee -a' visudo

Upvotes: 201

Apollo
Apollo

Reputation: 1986

Try to echo it. You have to run it in a subshell, though. Example:

sudo sh -c "echo \"group ALL=(user) NOPASSWD: ALL\" >> /etc/sudoers"

Upvotes: 0

sstendal
sstendal

Reputation: 3218

Use visudo for this with a custom editor. This solves all the race conditions and "hack" problems with Brian's solution.

#!/bin/sh
if [ -z "$1" ]; then
  echo "Starting up visudo with this script as first parameter"
  export EDITOR=$0 && sudo -E visudo
else
  echo "Changing sudoers"
  echo "# Dummy change to sudoers" >> $1
fi

This script will add the line "# Dummy change to sudoers" to the end of sudoers. No hacks and no race conditions.

Annotated version that explains how this actually works:

if [ -z "$1" ]; then

  # When you run the script, you will run this block since $1 is empty.

  echo "Starting up visudo with this script as first parameter"

  # We first set this script as the EDITOR and then starts visudo.
  # Visudo will now start and use THIS SCRIPT as its editor
  export EDITOR=$0 && sudo -E visudo
else

  # When visudo starts this script, it will provide the name of the sudoers 
  # file as the first parameter and $1 will be non-empty. Because of that, 
  # visudo will run this block.

  echo "Changing sudoers"

  # We change the sudoers file and then exit  
  echo "# Dummy change to sudoers" >> $1
fi

Upvotes: 46

zelanix
zelanix

Reputation: 3562

Just to add a further option to the answers above, if the race condition is not a major concern, then the following command can be used to avoid manually copying a modified file to /etc/sudoers

sudo EDITOR="cp /tmp/sudoers.new" visudo

This will ensure that the new file is validated and installed correctly with permissions update.

Note that if there is an error in the /tmp/sudoers.new file then visudo will prompt for user input so it is advisable to check it with visudo -c -f /tmp/sudoers.new first.

Upvotes: 2

Kamal
Kamal

Reputation: 17

This worked for me based off what others posted here. When i used other peoples script it would open visudo for me but would not make the edit. This made the edit i needed to allow all users, including standard users, to install java 7u17 for safari/firefox.

#!/usr/bin/env bash
rm /etc/sudoers.new
cp /etc/sudoers /etc/sudoers.new
echo "%everyone   ALL = NOPASSWD: /usr/sbin/installer -pkg /Volumes/Java 7 Update 17/Java 7 Update 17.pkg -target /" >> /etc/sudoers.new
cp /etc/sudoers.new /etc/sudoers

This added the %everyone blah blah blah to the bottom of the sudoers file. I had to run the script like this.

sudo sh sudoersedit.sh

Good luck :D

Upvotes: -2

Ali Afshar
Ali Afshar

Reputation: 41643

Set up a custom editor. Basically it will be a script that accepts the filename (in this case /etc/sudoers.tmp), and modify and save that in place. So you could just write out to that file. When you are done, exit the script, and visudo will take care of modifying the actual sudoers file for you.

sudo EDITOR=/path/to/my_dummy_editor.sh visudo

Upvotes: 4

ngn
ngn

Reputation: 7892

visudo is supposed to be the human interface for editing /etc/sudoers. You can achieve the same by replacing the file directly, but you have to take care yourself about concurrent editing and syntax validation. Mind the r--r----- permissions.

Upvotes: 11

Brian C. Lane
Brian C. Lane

Reputation: 4171

You should make your edits to a temporary file, then use visudo -c -f sudoers.temp to confirm that the changes are valid and then copy it over the top of /etc/sudoers

#!/bin/sh
if [ -f "/etc/sudoers.tmp" ]; then
    exit 1
fi
touch /etc/sudoers.tmp
edit_sudoers /tmp/sudoers.new
visudo -c -f /tmp/sudoers.new
if [ "$?" -eq "0" ]; then
    cp /tmp/sudoers.new /etc/sudoers
fi
rm /etc/sudoers.tmp

Upvotes: 31

Related Questions