Running a program as non root from a script - linux

I have a question closely related to this thread:
Best practice to run Linux service as a different user
but I need the solution to work in "every" Linux distribution.
I would like to run a program as a non root user from a script. This way, when init.d starts up the services at boot time as root, the script launches the process as the non-root user I specify. Of course the solution shouldn't prompt for a password.
I think this is the normal/correct procedure when deploying applications.
How could I do that?
Thanks a lot

A good way would be to drop privileges from your actual program. Then just pass that user as a parameter. Inside you can handle it in a very standard way (setuid())
Otherwise su -c 'your command' different_user will work just fine on any linux. (as long as different_user exists)

There are two ways:
sudo command - you need to add the original user to /etc/sudoers with such entry that the program can be run without (NOPASSWD)
seteuid() system call (if you can modify the program)
If you are root, you can also use su (see #cnicutar's answer for details)

Related

Elevate privileges of running process

Is there a way for one process (such as an executable or bash script) to elevate the privileges of another, running, process? e.g. If I have a program running as normal user user, is it possible for another process, running as root to elevate the privileges of the first as if it had been run as root originally?
I have seen exploits modify the credential struct of a process to perform this, but I'm not sure if there's a way to do this more legitimately.
Looking further into this, it appears that there is no way to do this without installing a kernel module; essentially a rootkit. The kind of thing I want is demonstrated here.
No, these properties of a process cannot be altered after it starts.
No. The only way to elevate a process’s privileges is by execing a setuid binary (such as /usr/bin/sudo); you can’t do it to an already running process.
You can, however, ask sudo to copy a file to a temporary path, launch your editor with your own privileges on the temporary path, and then copy the result back in place as root:
sudo -e filename
This is possible, but only at Ring 0, using the commit_creds(prepare_creds(0)), which will update the task struct associated with the userland process, setting UID/GUID to 0. This is only possible with code already running in Ring 0, such as a Kernel module/rootkit or kernel exploit. An example of how this may be done is here.
You could start a new process using sudo, but starting a new instance with higher permissions will always result in a new process being created.
It's not possible to grant additional permissions to an already running process.

What is the difference between /etc/rc.local and ~/.bashrc?

This is a linux related problem. I have searched around but did not get a good explanation.
It seems to me that both file configure the setup when I log in, but is there any difference? I notice that there seems to be "some rule" in deciding what should go into two different files. For example, if I need to add a specific search path to $PATH, I should do it in ~/.bashrc. But if I decide to change some system setting, like
/sys/class/backlight
or
/sys/devices/cpu/cpu#/online
then I have to do this in /etc/rc.local, otherwise it will not work.
Is it because these configurations can not differ between users?
Thanks.
The difference is in when they are run and who they're running as when run i.e. rc.local is run on a change of run level and it runs as root. bashrc is bash specific and run on a non login shell as a particular user.
You can find a good explanation of rc.local here
The script /etc/rc.local is for use by the system administrator. It is
traditionally executed after all the normal system services are
started, at the end of the process of switching to a multiuser
runlevel. You might use it to start a custom service, for example a
server that's installed in /usr/local. Most installations don't need
/etc/rc.local, it's provided for the minority of cases where it's
needed.
and you can find what you need about bashrc
man bash
When an interactive shell that is not a login shell is started, bash
reads and executes commands from ~/.bashrc, if that
file exists. This may be inhibited by using the --norc option.
The --rcfile file option will force bash to read and
execute commands from file instead of ~/.bashrc.
There's more info on bashrc in this question...
https://superuser.com/questions/49289/what-is-the-bashrc-file
This question was asked by me a month ago, though later I realized that stack overflow is not the best site for this Linux question. Thanks for people who answered this question earlier, but I would like to add some more explanation here.
Basically there are (at least) three stages where a user may change system environment in Linux:
when the system boots; This stage is most appropriate if we fancy permanent system setting, and should be made via /etc/.... For example, in my original question, the backlight, as well as on-line/off-line management of some CPUs can be set in this way, and /etc/rc.local is the right shell script I should edit. By "permanent", it means that this update will affect all users using the system.
when a user logs in; This stage is most appropriate if a user only wants to change his personal Linux environment. Therefore, files under ~/ (or HOME) should be the right place to look for. For example, ~/.profile (historically referred to as ./bash_profile or ~/bash_login) is a shell script run at login time. ~/pam_environment is not a shell script, but useful for setting environmental variables (see Ubunte-official-wiki-environmental_variables for more information).
when a user starts a bash shell; This stage is more restricted, as it only has effects inside a bash shell (as well as its child processes), hence does not affect GUI environment. So if a user is doing most of his job from a shell, then this is an appropriate stage to go for. The shell script related to this stage is ~/.bashrc. For example, environmental variables PATH can be changed here.
Hopefully this summary is more intuitive than technical.
.bashrc runs for each bash session started (i.e. every time you open a shell). It sounds as though you're talking of .bashrc as if it were .bash_profile which is run once per login.
Depending on what kind of setup you're running the rc.local is a legacy construct but, traditionally it was run on the last run level during start up. You can see this link for other related posts talking about rc.local.
If you're on a system running systemd this is usually included by default in the systemd package systemd-backlight.service.

Bash script which can be executed after password is supplied

I need to get a hold of web-server logs by regular users who have /bin/bash as their shell enabled. Logs are stored in a directory which has drwx------ permissions and is owned by root:root so obviously they can't access any files in it (and yes, I can't really change this permissions setup).
The system(s) is Debian Linux. So I'm looking for some wrapper script, it might not be bash exactly, which, in my vision, will do the following:
you pass one argument to it - a sitename - i.e. site.com;
it greps all the lines containing this site.com;
stores the result to user home dir.
This part is easy, the real problem arises when you want to bypass restrictions yet to stay (at least somewhat) safe. So:
script must only be started after password is provided for it to be run;
in case of bash scripts they are run with permissions of the user account who ran it - so my guess is it should have su -m root -c 'grep ...' in it, but I found no way how to pass password to the prompt inside the script so far (sudo is not exactly suitable unfortunately);
if there is a way to pass password to su from inside the script then of course script itself must have permissions 751 and owner of root:root - so that the end user who runs the script (or anyone else) won't be able to see the script's content.
I'm open to suggestions how this should be done or if it's should be done at all (at least this way) :) Thank you.
Given what I understand of your needs, I summarize here the various options that come to my mind. In no particular order:
Use sudo together with a policy file (/etc/sudoers -- edit with
visudo) to restrict the commands available to the user
Use a cron job (more or less smart) to collect data on the server at regular
intervals and store them at a location accessible to you (or mail them to you...)
If you have administrative access to the server, you might create a special user with
the "log-grepping" tool as connection shell (/etc/passwd)
If you have ssh access to your server, you may also use the
authorized_keys file on the server to restrict remote command over ssh
Those are only general directions. Read about them. Try them. And if you're struggled, don't hesitate to post an other question!
As a last word, as it has already been stated in a comment, please refrain yourself to develop your own "security restriction system". sudo, ssh, pam (and probably others ... selinux?) have been specifically crafted for that purpose...

mount without sudo using sticky bit?

I am trying to write a shell script to mount loop device, and I am assigning this script with a sticky bit to execute as uid(root).(this is for other users on server) The problem is I can't seem to run 'mount' command without using sudo in front of it. When I am in root account, I can run 'mount' command without any issue, so I thought by setting script with rws-r_x-r_x would do it.
Am I misunderstanding the concept of using sticky bit? or is there any other way?
The server is running under Ubuntu 10.04
You mean the setuid bit, not the sticky one. The kernel doesn't honor the setuid bit on scripts. See this post for a thorough description, here's a summary: the gist is that suid on a script is insecure.* The kernel starts reading the script to execute it, but it sees the #!/path/to/interpreter and figures out that it needs to be interpreted. It then cancels "executing" the script directly and calls the specified interpreter, passing the script name as the first argument (and all subsequent arguments in order after that). The reason setting UID is insecure in this instance is that an attacker could potentially change the script to be executed between the kernel setting the new UID and the interpreter reading the file.
*: The other post mentioned that perl handles its scripts in such a way that they can be suid.
As for the actual mounting problem at hand, add a line to /etc/fstab/ and include the user option.

best approah (security) to do some admin work through web page in Linux?

I want to build a web based admin tools that allow the system admin to run pre-configured commands and scripts through a web page (simple and limited webmin), what is the best approach?
I already started with Ubuntu installing LAMP and give the user www-data root's privileges !!!
as I learned (please check the link) this is a really bad move !!!, so how to build such web-based system without the security risk?
cheers
I did something like this a couple of years ago. It was (I like think) fairly secure and only accessible to a limited number of pre-vetted, authenticated users, but it still left me with an uneasy feeling! If you can avoid doing it, I'd recommend you do :)
I had a database sitting between the frontend web-tier and the script which was actually executing actions. The relevant table contained a symbolic command name and an optional numeric argument, which was sufficient for my needs. This allows you to audit what's been executed, provides a quick and dirty way to have a non-www user do things, and means if the website is compromised they're constrained by the DB structure (somewhat) and the script which pulls data from it.
The data from the DB can be read by a daemon running in a separate, unprivileged account. The daemon pulls and sanitises data from the DB and maps the 'command' to an actual executable (with a hard-coded map, so commandA executes A, commandB executes foo, and anything else would get flagged as an error). The account can be locked down using AppArmor (or SELinux, I imagine) to prevent it from executing, reading or writing anything you don't expect it to. Have a system in place to alert you of any errors from either the daemon or AppArmor/SELinux.
The executables which the daemon runs can be setuid'd if appropriate, or you can use the sudoers mechanism to allow the unprivileged account to execute them without a password.
I already started with Ubuntu installing LAMP and give the user www-data root's privileges
Don't do this.
If you really want to execute some very specific scripts under root privileged. Create such predefined very limited scripts, allow their password-less execution with sudo for specific user and then run them via script and don't forget authentication.
Generally this is bad idea.
SSH is your best friend.

Resources