Cron shutdown fails to execute

Interesting concept. If what I have with the addition of the shutdown works, I'm going to have to go with it. I'm running short of days left here, and need to get this stuff buttoned up.

Thanks again, I will check out the grub man pages and see what that's about.

1 Like

Well, didn't work on the actual machine. Seems like on my private machine, I'm a member of the sudo group. Not so on the public computer.

Can you run the script under a certain user, then set up sudo to not ask for a password from that user?

00 10 * * * gitm command

So something like:
00 10 * * * gitm /usr/sbin/poweroff -f
... or whatever your path and command is.

If that doesn't work, try:
00 10 * * * gitm sudo -i /usr/sbin/poweroff -f

sudo visudo
or
sudoedit /etc/sudoers

Enter the following:

# Allow {username} to execute any command
gitm		ALL=(ALL) NOPASSWD:ALL

Where "gitm" is a user (Ghost In The Machine) used only for auto shutdown and other auto-admin scripts.

Not sure, I'd have to research it and try it out.

I find it hard to believe that while an user can shutdown a system at the click of a button, it's this hard to script the action without running into these permissions issues.

I have added the user to the admin group, and using the user pwd in the script allows the command to work. Of course, this isn't the best from a security point of view. Considering the users, probably not too risky.

Thanks!

I ran across this:

gnome-session-quit [--logout|--power-off|--reboot] [--force] [--no-prompt]

Tried it on a Fedora VM with a new non-privleged user.
This combination seemed to work
gnome-session-quit --power-off --force

Will try it on Zorin public pc's tommorow after revoking users admin privleges.

Ran fine from the terminal, running from crontab failed. Oh well!

From https://unix.stackexchange.com/questions/208205/how-to-schedule-shutdown-every-day

And yet another way:

The shutdown command has already an embedded scheduler so you don't need a cron job for it to run at the specified time. In Linux as everywhere else, it's better to stick to the KISS principle (Keep It Short and Simple).

shutdown -h 22:00 will work fine, no need to run it in the background. Add the command at the end of /etc/rc.local (or /etc/rc.d/rc.local depending on your system) for execution in the last startup script.

The advantage of not using cron is that in this way the shutdown remains scheduled during the day, and you can cancel it at any time by typing

shutdown -c 

Anyone know where the rc.local file or it's equivalent resides in Zorin?

Are you talking about where you put user executable scripts?
/usr/local/bin

I'd just create a script that calls shutdown -h 22:00, make it executable, drop it into /usr/local/bin, then call it from Zorin menu > System Tools > Startup Applications.

As soon as the machine boots, it's got the command to shutdown at the specified time.


Or you can set it to run as a service, so the user never even sees any command prompt. Here's a quick how-to, used to remap the hard drive light to a keyboard light, but you can do the same for the shutdown command:

So let's say you want to name your script "autosd".

Create a text file with your shutdown script in it. Save it to /etc/init.d/autosd.

Set the file as executable:
sudo chmod +x /etc/init.d/autosd

Create a sym-link in the proper run level directory:
sudo ln -s /etc/init.d/autosd /etc/rc5.d/S01autosd

You want to use /etc/rc5.d, the 5th run-level, as that's the desktop... so as soon as the machine boots far enough to get to the graphical desktop, it'll have a command to shut down at the specified time.

You might want to put a wall message so anyone still using the machines don't freak out when it shuts down on them.

More info:
man shutdown
man wall

That worked on my machine, will check on the public pc's tomorrow.
Thanks for the guidance, I'll keep my fingers crossed!

1 Like

Just keep in mind that might pop up a terminal window... if you don't want that, go with the second option I wrote of above... creating a service.

On my test run, it didn't, but I'm in the sudo group
On the public machines, I'll pull the guest out of that group and see what happens.
A terminal window is ok, as long as no input is needed.
The action will run afterhours, when nobody is at the computers.
The computers start up again in the am via the pc bios.

I read up on the why this poweroff issue is this way, goes way back to multi-user computers.

Taking a lot of my energy to save some energy!

Just found this... it might help you or a future admin who's attempting to secure a system:

gsettings set org.gnome.desktop.lockdown mount-removable-storage-devices-as-read-only false
gsettings set org.gnome.desktop.lockdown disable-command-line false
gsettings set org.gnome.desktop.lockdown disable-log-out false
gsettings set org.gnome.desktop.lockdown disable-printing false
gsettings set org.gnome.desktop.lockdown disable-lock-screen false
gsettings set org.gnome.desktop.lockdown disable-print-setup false
gsettings set org.gnome.desktop.lockdown disable-user-switching false
gsettings set org.gnome.desktop.lockdown disable-application-handlers false
gsettings set org.gnome.desktop.lockdown disable-save-to-disk false
gsettings set org.gnome.desktop.lockdown user-administration-disabled false

Thanks- Would those be used in the CLI and do they toggle true/false.
Might be useful, do you know where the documentation is?

I didn't see mention of it anywhere, but were you creating the cron job at the user-level? Or is this a system-level cron job?

I tried to take what I believe to be your intended purpose and after a bit of research and different searches, tried to throw together something that might work.

Disclaimer: I am still very actively learning and I don't have much practice creating these kinds of script files and also don't have another machine on which to test the below possible solution. A sanity check on the method might be needed by other, more experienced people here or elsewhere.

I read that if you create a script that adds a user to the /etc/sudoers file and grants permission to execute /sbin/poweroff, you can place it in the /etc/skel/ directory with the execute permission set. This way, the script will be copied to the home directory of any new user and it allows them to execute it for an easy shutdown.

An example script is below that takes one argument, (whoami) which will fill the username variable of the new user's username. That argument is included so that the script works when run while the new user is logged-in and prevents the you, the administrator, from needing to do this process manually for each new user on the machine in question.
It then checks if a sudoers file already exists for that user, and if not, creates one with the necessary configuration to allow the user to run /sbin/poweroff without a password.
You might also notice that it creates a crontab file for a user which calls to shut down the system at the time you specified in your OP, but I believe that the 00 10 indicates a 10:00AM shut down time - I only mention this because you said you wanted the machine to shut down after hours and that they will start up again in the AM. The cron expressions use 24-hour format. That said, you might consider changing to 0 19 for a 7:00PM shut down which is truly after hours. Or even, 59 23 for an 11:59PM shutdown, etc...
Regardless, the file is then given the appropriate permissions. Then, places it in /etc/skel/. It should only allow the user to run the poweroff command without a password. For any other sudo commands, the user will be prompted for the master password.

#!/bin/bash

# Define variables
USERNAME="$(whoami)"
SUDOERS_FILE="/etc/sudoers.d/$USERNAME"
CRONTAB_FILE="/var/spool/cron/crontabs/$USERNAME"
SCRIPT_FILE="/etc/skel/add-sudoers.sh"
BASHRC_FILE="$HOME/.bashrc"

# Check if the sudoers file already exists
if [ -f "$SUDOERS_FILE" ]; then
  exit 0
fi

# Create the sudoers file for the user
echo "$USERNAME ALL=(ALL) NOPASSWD:/sbin/poweroff" > "$SUDOERS_FILE"
chmod 440 "$SUDOERS_FILE"

# Create the crontab file for the user
echo "00 10 * * * /sbin/shutdown -h now" > "$CRONTAB_FILE"
chmod 600 "$CRONTAB_FILE"
chown $USERNAME:$USERNAME "$CRONTAB_FILE"

# Create the script file in /etc/skel/
echo '#!/bin/bash' > "$SCRIPT_FILE"
echo '/sbin/shutdown -h now' >> "$SCRIPT_FILE"
chmod 755 "$SCRIPT_FILE"
chown root:root "$SCRIPT_FILE"

# Add command to .bashrc file
echo "[ -f $SCRIPT_FILE ] && $SCRIPT_FILE \"$USERNAME\" &" >> "$BASHRC_FILE"

# Execute command for current session
[ -f $SCRIPT_FILE ] && $SCRIPT_FILE "$USERNAME" &

Adding a line to the user's .bashrc file allows for automatic execution of the add-sudoers.sh script on login, using [ -f ~/add-sudoers.sh ] && ~/add-sudoers.sh "$USERNAME" &.
On login, the script should be able to run for any user's account, as long as they have permission to create files in the specified directories and modify the crontab and sudoers files for their own user account. The script does not require root or sudo permissions to run, since it only modifies files and settings specific to the user running the script.

You can safely remove the section which creates the script file at /etc/skel/poweroff_script.sh and contains #!/bin/bash\n/sbin/shutdown -h now. The script should still work as intended.

This poweroff_script.sh script file that gets placed in /etc/skel is meant to provide the user with an executable file and provides them an easy way to shut down the machine without needing to type a long command - especially if this script is placed in their home directory or the Zorin menu. However, it is not essential for the user to have this file in order to shut down the machine. The user should still be able to use the shutdown command to initiate a shutdown, which is what the script is already adding to the user's crontab file.

At the very least, this might help you or someone else identify a solution intended to solve your problem if this doesn't work. :bulb:

1 Like

This is great @ajo001, there is one piece missing though... second command from the bottom you add an alias to .bashrc. Anytime you add to that file you must reload the source file for changes to take effect. So you would need to add:
source ~/.bashrc
Immediately after your alias creation, otherwise it will error on the call of the shutdown command and fail until the computer is restarted.

While this is a helpful script, won't this give any user administrative capabilities? Wouldn't it be better to setup a user to run the script as and add that user to the sudoers file? Then noone will know the name of that user and the script will work as intended?! This would eliminate the chance that any user has administrative access to the machine.

I did notice the permission set specifically for the shutdown function. I'm not that familiar with sudoers just yet.

User Level. Worked it out for now.

To my understanding, the only admin function that would be given to each user is the ability to use the shutdown command.

I guess in theory, if the /etc/skel portion is left in there, which copies this script to each user's home directory, they could also be able to find the the script and execute it themselves. The only thing I think would happen then, is that they essentially create the cron entry to activate it and instruct the machine to shutdown at the specified time.

I could be wrong though. We'd have to let someone try it out and report their results.

That does seem like it could work but I don't know how I would make that work as automatically as the other script. The reason I did it that way is because of the requirements to have each user's sudoer file update as well as their cron; both of which I believe need to happen at the user level. This way, the admin account (marcsitkin) wouldn't be required to log in for every user and make their cron and update the sudoer file.

Glad @Marcsitkin was able to get it working or figured out tho.

1 Like

Another avenue a system admin can take:
1- Set up the OS as you normally would.

2a- Set the original installed OS drive to read-only so no one can alter it.

2b- Or install it on an external USB drive that's not plugged into the computer during normal use.

3- Create a .ISO image file of that OS installation.

4- Loop-mount that .ISO file to boot it. It'll have all the necessary drivers and files needed for that computer, and when it's shut down, all the files created since boot-up are gone.

5a- (If you've used 2a above) When you want to update the OS, just set the hard drive where the OS is installed to read/write, do the updates, then go back to #3 above and repeat the process.

5b- (If you've used 2b above) Update the OS installed on the external drive, then go back to #3 above to create a .ISO file, drop that new .ISO file onto the computer's disk to overwrite the existing .ISO file.

Or (if it's having problems with drive lettering):
Install the OS to the computer's drive. Create a .ISO file. Overwrite the installed OS with that .ISO file (drop the .ISO file onto the computer's drive, don't 'burn' it). Loop-mount that .ISO file to boot it. Not sure if that would work, though.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.