System shutdown without password in ubuntu 11.04 - linux

I'm writing a QT application which has a shutdown button. I want to shutdown system with this button but when I use the shell command "shutdown -h now" the system asks for password.
I want to shutdown without password.
My QT code is:
QObject *parent;
myProcess = new QProcess(this);
QString command= "sudo shutdown";
QStringList arguments;
arguments << "-h " << "now" ;
myProcess->start(command,arguments);

Ensure that the user running the process is in the sudoers file.
Use visudo to alter the sudoers file and add something like the following:
<username> ALL = NOPASSWD: /sbin/shutdown
hth

Look at going through gksudo/kdesudo for calling reboot, one of those should be on most Linux installations.
They're simple wrappers that will ask the user for their password to confirm elevating privileges to root and, in your case, calling reboot or shutdown.
Just play nice with the rest of the system and let shutdown ask the user for his password.

Instead of calling a shell command you can call reboot directly to halt or reboot the system. See "man 2 reboot". But you will still get a permission error if the user does not have the CAP_SYS_BOOT capability. With sudo or suid binary, as described in the comment above, you will get this capability (and more).
You can also set the CAP_SYS_BOOT capability for your binary with the setcap program or similar. Remember that this will have to be done after each time the program is recompiled, and you have to use sudo to use setcap.

Related

sudo not working correctly after some time

I have Linux server (CentOS release 6.4) which is able to process source code sent by users. On the server is a Java application which starts a bash script which will run compilation and execution commands of these source codes in a limited way (time and memory are limited, no Internet, executed by limited user).
The Java program must be always be running, so it can register new job requests.
When started, the Java program works fine, but after some time (talking in days), commands are not executed properly. I get the following error message:
sudo: sorry, you must have a tty to run sudo
the line which is causing that is:
sudo -u codiana $COMMAND &
where $COMMAND is command to execute along with its arguments
After application restart (kill and start again) everything works.
Is there some time limit on Linux which can cause that?
You can comment /etc/sudoers:
#Defaults requiretty
Edit:
man sudoers | grep requiretty -A 5
requiretty If set, sudo will only run when the user is logged in
to a real tty. When this flag is set, sudo can only be
run from a login session and not via other means such
as cron(8) or cgi-bin scripts. This flag is off by
default.
So if this is not desired open /etc/sudoers with you text editor of choice and comment out this line.

How to Open xterm window from a terminal and run a command in background from xterm?

My application tries to execute roots command "sudo ifup eth0" and "sudo ifdown eth0". But it returned an error "sudo: sorry, you must have a tty to run sudo".
So, it requires a tty to execute the sudo commands. So, I tried to execute the commands by opening tty sessions
gnome-terminal --command="sudo ifdown eth0" &
xterm -e "sudo ifdown eth0" &
then it worked fine. But I am not able to send the command from newly created gnome-terminal or xterm.
i.e., if I close the newly created gnome or xterm windows before they had executed the commands, then the commands were terminated immediately.
Can you give suggestion how to disable the window from closing by the user
or
how to make it invisible to the user?
Note: you can test this by using system-config-network command instead of ifdown and ifup
I would suggest not to use xterm or gnome-terminal to provide a terminal for sudo, but to deal with the "sorry, you must have a tty to run sudo" message directly.
There is a requiretty option in the sudoers file that makes sudo demand a terminal. If this option is unset with !requiretty and the command is executed with the NOPASSWD option sudo should run without the need to open a new terminal window. There are more details in this serverfault post.
That is how sudo is used for instance in cron scripts.
Since requiretty option provides additional security in an environment where sudo is used not only in cron scripts but to let remote users issue commands with elevated privileges, the action of !requiretty can be restricted.
User_Alias LOCAL_USERS = john, mary
Cmnd_Alias NETWORK_SCRIPTS = /sbin/ifup, /sbin/ifdown
Defaults!NETWORK_SCRIPTS !requiretty
LOCAL_USERS ALL = NOPASSWD: NETWORK_SCRIPTS
If you run your code within X session, then you can use gksudo instead of sudo:
gksudo -m "Your message" /command/to/run
It will prompt user for password (if needed) using nice GUI interface. No need to xterm or gnome-terminal.
Effect will be more secure than allowing particular command to run without any password and solution will be more consistent to what users are used to.
In general, sudo or su need to prompt for a password, or programs could escalate their privileges without user intervention. If you application needs to elevate for some purpose, you will need to use an xterm or similar. There are difficulties though in getting the return code back (konsole might need --nofork and gnome-terminal might need --disable-factory, but the options sadly vary by version), and it's not easy to get it right on every system. Most unixes and linux distributions provide xterm, but some old Fedora/RHEL/CentOS provide X without xterm, so it's another dependency to think about.
The command launched by xterm -e sudo -- ... can then do the standard double-fork and setsid. Once the user has entered his password in the xterm, it goes away immediately, but your command runs in the background with elevated privileges. It can connect back to the original program using a socket or fifo to run as a root co-process.
The daemon or disown commands or similar might be useful if you want to wrap an existing application in a double-fork & setsid (eg, xterm -e sudo -- daemon system-config-network or perhaps xterm -e sudo -- bash -c "system-config-network & disown -a").

sudo without prompt in CentOS

I have a java application connect to a remote CentOS using ssh connection.
There's a shell script, in order to execute it, I need to input the password.
[user#**** ~]$ sudo ***
Password:
My question is how to execute the script without prompt .(I can't modify /etc/sudoers and I also don't want to use outputStream to send the password.)
The best and much more secure way is to sudo visudo and attach "NOPASSWD:" to get sudo not require a password.
The way in the middle is using the sudo -S parameter, that expect the password coming from standard input instead that from the terminal device.
The worst and less secure way is to pass a clear text password that one could catch even via ps -ef command using "expect" utility (install it, then "man expect")

Enter password for a sudo command in a chain of commands

In Linux how can I enter the password for one of the commands in a chain of commands which requires a sudo. One example which I can think of is when after running a long compile job, I want to shutdown the machine.
make ; sudo init 0
I want the shutdown command to run only after make finishes, but would like to enter the password right away, because I won't be there when the first command is done. Also, I don't want to run "make" with super user privileges. So switching to root and running the commands is also out of the question.
Thanks!
sudo sh -c "su -c 'make' $USER && init 0"
Change your uid early and often. That's the Chicago way!
You can run sudo -v to update the sudo timestamp - this means you won't need to enter a password for x minutes (default is 5). You can change the timeout by editing the timestamp_timeout in the sudoers file.
You also might want to change your command to
make && sudo init 0
which will only shut down if make completes successfully.
One possibility is to use Expect
to automate the password input.
Here's a simple HOW-TO for expect and passwords: http://www.linux.com/archive/feed/56066
Another possibility is to edit your /etc/sudoers and set your user to be able to use sudo without password. if you check the file it will be explained in the comments there.
Why not pipe the password into sudo?
make; echo 'password' | sudo -S init 0
Change the timeout for sudo to something long enough to cover your usage, then run something like sudo echo to authenticate, then run your other commands. As long as the password timeout hasn't been reached, it should execute without asking again.
You can add that to your sudoers file
username ALL = NOPASSWD: /sbin/init
where username is the username you want to allow.

Best practice to run Linux service as a different user

Services default to starting as root at boot time on my RHEL box. If I recall correctly, the same is true for other Linux distros which use the init scripts in /etc/init.d.
What do you think is the best way to instead have the processes run as a (static) user of my choosing?
The only method I'd arrived at was to use something like:
su my_user -c 'daemon my_cmd &>/dev/null &'
But this seems a bit untidy...
Is there some bit of magic tucked away that provides an easy mechanism to automatically start services as other, non-root users?
EDIT: I should have said that the processes I'm starting in this instance are either Python scripts or Java programs. I'd rather not write a native wrapper around them, so unfortunately I'm unable to call setuid() as Black suggests.
On Debian we use the start-stop-daemon utility, which handles pid-files, changing the user, putting the daemon into background and much more.
I'm not familiar with RedHat, but the daemon utility that you are already using (which is defined in /etc/init.d/functions, btw.) is mentioned everywhere as the equivalent to start-stop-daemon, so either it can also change the uid of your program, or the way you do it is already the correct one.
If you look around the net, there are several ready-made wrappers that you can use. Some may even be already packaged in RedHat. Have a look at daemonize, for example.
After looking at all the suggestions here, I've discovered a few things which I hope will be useful to others in my position:
hop is right to point me back
at /etc/init.d/functions: the
daemon function already allows you
to set an alternate user:
daemon --user=my_user my_cmd &>/dev/null &
This is implemented by wrapping the
process invocation with runuser -
more on this later.
Jonathan Leffler is right:
there is setuid in Python:
import os
os.setuid(501) # UID of my_user is 501
I still don't think you can setuid
from inside a JVM, however.
Neither su nor runuser
gracefully handle the case where you
ask to run a command as the user you
already are. E.g.:
[my_user#my_host]$ id
uid=500(my_user) gid=500(my_user) groups=500(my_user)
[my_user#my_host]$ su my_user -c "id"
Password: # don't want to be prompted!
uid=500(my_user) gid=500(my_user) groups=500(my_user)
To workaround that behaviour of su and runuser, I've changed my init script to something like:
if [[ "$USER" == "my_user" ]]
then
daemon my_cmd &>/dev/null &
else
daemon --user=my_user my_cmd &>/dev/null &
fi
Thanks all for your help!
Some daemons (e.g. apache) do this by themselves by calling setuid()
You could use the setuid-file flag to run the process as a different user.
Of course, the solution you mentioned works as well.
If you intend to write your own daemon, then I recommend calling setuid().
This way, your process can
Make use of its root privileges (e.g. open log files, create pid files).
Drop its root privileges at a certain point during startup.
Just to add some other things to watch out for:
Sudo in a init.d script is no good since it needs a tty ("sudo: sorry, you must have a tty to run sudo")
If you are daemonizing a java application, you might want to consider Java Service Wrapper (which provides a mechanism for setting the user id)
Another alternative could be su --session-command=[cmd] [user]
on a CENTOS (Red Hat) virtual machine for svn server:
edited /etc/init.d/svnserver
to change the pid to something that svn can write:
pidfile=${PIDFILE-/home/svn/run/svnserve.pid}
and added option --user=svn:
daemon --pidfile=${pidfile} --user=svn $exec $args
The original pidfile was /var/run/svnserve.pid. The daemon did not start becaseu only root could write there.
These all work:
/etc/init.d/svnserve start
/etc/init.d/svnserve stop
/etc/init.d/svnserve restart
Some things to watch out for:
As you mentioned, su will prompt for a password if you are already the target user
Similarly, setuid(2) will fail if you are already the target user (on some OSs)
setuid(2) does not install privileges or resource controls defined in /etc/limits.conf (Linux) or /etc/user_attr (Solaris)
If you go the setgid(2)/setuid(2) route, don't forget to call initgroups(3) -- more on this here
I generally use /sbin/su to switch to the appropriate user before starting daemons.
Why not try the following in the init script:
setuid $USER application_name
It worked for me.
I needed to run a Spring .jar application as a service, and found a simple way to run this as a specific user:
I changed the owner and group of my jar file to the user I wanted to run as.
Then symlinked this jar in init.d and started the service.
So:
#chown myuser:myuser /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar
#ln -s /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar /etc/init.d/springApp
#service springApp start
#ps aux | grep java
myuser 9970 5.0 9.9 4071348 386132 ? Sl 09:38 0:21 /bin/java -Dsun.misc.URLClassPath.disableJarChecking=true -jar /var/lib/jenkins/workspace/springApp/target/springApp-1.0.jar

Resources