LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Shell scripts: gain root access - how? (https://www.linuxquestions.org/questions/programming-9/shell-scripts-gain-root-access-how-225049/)

ludeKing 08-31-2004 08:54 PM

Shell scripts: gain root access - how?
 
Hi all,
I am writing a shell script that will install a program I have written. I want it to install to some global location like /usr/local/bin, but to do that I'd need root access. THe prob is I want this script to be run as a normal user, then obtain root access by requesting the root password, or changing to root automtically.

How can I do this?

Also, can this be done in Java or Perl?

tonyfreeman 08-31-2004 09:01 PM

sudo
 
sudo is a program that gives a normal user temporary root access. The user with sudo permissions would need to be listed in /etc/sudoers file. For instance, my entry in that file is:

Code:

tfreeman  ALL=(ALL)  ALL
Now I can compile and install a program onto the system. The install needs a superuser ... so what I do is issue the install command with sudo:

Code:

sudo make install
Password:

... at the "Password" prompt I type MY password (not the root password) ... and the installation begins.

Do a man on sudo for more information.

--Tony

LongName 08-31-2004 09:02 PM

As I was reading other question/answers, you can type 'su rootpasword' to gain root privilages. I never tryed it though.

Have fun!

ludeKing 08-31-2004 09:25 PM

Um, hang on...what I am trying to do is make a script for my app which will be available for download to many users. asking them all to mod their 'sudoers' file isn't viable unfortunately.

So are you saying that in the script if I have it run 'su' then read the password, then check the password, then check for PID 0, it should be all good?

How could I implement this?

Dark_Helmet 08-31-2004 11:37 PM

Obvious question: Then why don't you tell everyone they must be root to run the script to begin with?

You can't gain root access without giving root's password (or activating some security exploit). If you could, that would be a gaping security hole. I mean, big enough that "Linux security" would be an oxymoron.

The only way I know to do this is execute su from inside your script. The su program will get the password, it will verify it's the correct password, and it will automatically update the script's process so that it runs with root privileges. The only thing your script needs to do is verify that the su command returns a successful exit status. Otherwise, the user entered the wrong password. This isn't absolutely necessary, because the script will barf with "permission denied" message when trying to install files.

An example:
Code:

#!/bin/bash

# Tell the user what you're doing. Nobody with an ounce of caution
# should just randomly give out root access without knowing what
# it will be used for. Also, the su prompt simply says "Password",
# meaning the user needs to be told *which* password to enter
# (i.e. not their normal user account password)

echo "This script needs root access to copy files to /usr/local/bin."
echo "Please enter root's password when prompted."

# Shoot off the su command to gain root privileges
su -

# Quit the script if the user failed to provide the right password
if [ $? -ne 0 ] ; then
  echo "Script is exiting because you failed to give root's password"
  exit 1
fi

# If we're here, we're supposed to have access. Copy the files over

# Give up root access immediately after you're done performing the
# copies. This should return the process to a regular user
exit

# Perform any other cleanup tasks (as a non-privileged user)

# Exit with successful status
exit 0


ludeKing 09-01-2004 08:51 AM

Dark_helmet, that is exactly what I was after, a way to ask for the root password and then continue only if you are now root.... i just didn't know how to implement it.;)

thanks mate!


question though: how do you 'give up root access' like you said.
just make sure everything you need root for is at the end then exit the script?
will this return to normal user access?
is there a way to do it within the script?


scissors 09-01-2004 11:14 AM

Code:

# Give up root access immediately after you're done performing the
# copies. This should return the process to a regular user
exit

This "exit" will exit root's shell and return you to the original user's shell.

Dark_Helmet 09-01-2004 01:59 PM

Ugh... sorry.. This is what happens when you think something "in theory" will work.

My script above is flawed. When executing "su -" it opens a new shell process (as expected), but waits for user input. In other words, the script "stalls". I made the incorrect assumption that the shell process would "upgrade" itself, and that's wrong.

There is another option: su -c

Change the script above to this:
Code:

#!/bin/bash

# Tell the user what you're doing. Nobody with an ounce of caution
# should just randomly give out root access without knowing what
# it will be used for. Also, the su prompt simply says "Password",
# meaning the user needs to be told *which* password to enter
# (i.e. not their normal user account password)

echo "This script needs root access to copy files to /usr/local/bin."
echo "Please enter root's password when prompted."

# Launch a script that copies files
su -c "/path/to/the/copy/script"

# If the previous command failed (the script needs to return 0
# for this to work), then tell the user we encountered an error
if [ $? -ne 0 ] ; then
  echo "There was an error executing the copy commands."
  echo "Either you did not give the right password, or the"
  echo "supporting copy script is not present."
  exit 1
fi

# Perform any other cleanup tasks (as a non-privileged user)

# Exit with successful status
exit 0


ludeKing 09-01-2004 08:30 PM

Ack, so you need to have another script to run the root commands? Could it just be a subroutine of the script? The main thing I am worried about is people hacking my scripts to make them do other things... maybe I could write a short C++ program and get the script to run that?

Also, can you do this root access stuff in Perl? ie 'su -c'

And can you 'compile' shell scripts so the source can't be viewed and modified?

Dark_Helmet 09-01-2004 09:18 PM

In a nutshell, you can do any single command with the "su -c" command. That's a little misleading, because you can do "tricks". Like I showed, you can launch a script. So it's "one command" that really executes multiple commands. Similarly, you can use semicolons in the command string. For example, I just tried this:
Code:

[Dark@Spaceball1 Dark]$ su -c "echo \"hi!\"; whoami"
Password:
hi!
root
[Dark@Spaceball1 Dark]$

Using the semicolon, you can shove multiple commands into a single command string for su -c. That can get complicated, messy, or both if you have a lot of commands to execute. That's why I suggested the script.

If you're going to distribute this software with a script-based install system, then there is no way you can prevent people from hacking on it. It's just not possible. The user running the script is expected to have the root password, and that means they have root access. And, of course, if they have root access, they can open any script and modify it any way they see fit.

If you do not want people to see what your installer is doing (which will make people suspicious), then you will have to write it as some form of compiled executable. The reason you're concerned about people hacking your script is the very same reason an administrator would be suspicious of your installer. There is no way for them to verify what your installer will do, and it's asking for root access.

Personally, I would leave it as a script. And yes, you can use su -c in perl. It's just a regular system command, and Perl has the ability to execute system commands in scripts.

ludeKing 09-02-2004 08:18 AM

Ok, thanks dark_helmet...... hmm, I'm tossing up ideas here..

Basically I am writing a program that will take a zipped or otherwise source file and install it for the user, with Java as a GUI front end.
I was going to do the whole thing in Java but the system commands were getting tricky to do, so I thought of having Java do the frontend(GUI) and perhaps Perl as the backend. Obviously it will be taking certain parameters that the user selects in the GUI and putting them into the Perl script (probably writing to a temporary log then reading the params from the log)....

The thingis I don't want this Perl script hacked at all otherwise the whole program won't work... I was thinking of checking its md5sum each time it was run, but thats a workaround, not a solution really.

Then I thought maybe C++ as the innards of the actual installer, still with Java as the GUI... but my C++ is pretty crap. At least then I can compile it and no-one can hack it!

What do you think, Perl or C++?

p.s. oh and the shell script was just an installer to get the actual finished prog I make into a global location, but thats sorted now, cheers!

Dark_Helmet 09-02-2004 09:04 AM

My first preference would be Perl.

Checking the md5sum is a pretty good idea. It would allow experienced administrators to look at what the script does and get a warm & fuzzy feeling that the script isn't trying to do something naughty. However, it won't remove all doubt, because someone will be super-paranoid, and there's always a way that a program can abuse trust. For example, a wild-eyed admin might be fine with the script, but suspicious that the Java portion runs a key logger right before the root password is typed in. In other words, if something is hidden from the user, someone will be suspicious.

So, if you distribute the Java gui in byte code format or as a compiled executable without the source code, then some admins will raise an eyebrow. However, you'll be reasonably certain that nobody can tinker with the md5sum for the perl script, which implies that you can be reasonably certain that the script is ok if the md5sum matches.

If you distribute the software with the source code, then there's no stopping someone from creating a new Perl script, calculating the new script's md5sum, and replacing the old one in the Java code with the new one.

One other option you could consider is this: If you are running a server or have access to a project server (like sourceforge), you can store your Perl script there, it's md5sum, and give the option in the gui to download it directly from the server. If you do, it would be advisable to let them look over the script before executing it. Or at least, have an option the user can change to run the script automatically or let them review it (defaulting to review). Also, if you do it this way, it would probably be good to encrypt the md5sum that the server provides (since it's no longer stored in the java code itself). That way, nobody can replace the md5sum with a new value for a hacked version of the perl script.

If they can, then you won't be able to stop them anyway, and that's the thing about security: there is no absolute security; there are only degrees of security. You gain more confidence by making it more difficult to break, but it is breakable somehow, someway. I don't mean to go all philosophical, but that's just how things are...

ludeKing 09-02-2004 09:59 AM

wow... thanks for the insight.

I think it would be ok if I have the md5sum of the perl script stored in the java program, then have the Perl script do all the rooting, so to speak. That way, the Java prog isn't logging keystrokes, the things the Perl script does are all open to any nosey users/admins, but its still secure in that if the md5sums don't match, its been tampered with, hence should abort.

What would you think of that? my script is secure and your mind is at ease because you can see everything thats going on in the open source script!

And did you not choose C++ becauuse of the same reasons... closed source, suspicious etc?

Dark_Helmet 09-02-2004 10:32 AM

That's a decent middle-ground. You'll still run across the suspicious types. Just because you say you won't run a key logger (or any other security threat), it's no guarantee that you won't. You can never get rid of that possibility unless you provide the source.

A better way to look at it is from the target audience perspective, and that's something I overlooked. I assume you would be targetting Linux newcomers to ease software installation or something along those lines? That group probably won't be as concerned with security and would be willing to trust software more than, say, a system administrator with years of experience. You could also ask your primary group of users (if there is such a group) about how secure they want things. Make sure to separate what they "want" from what they are "willing" to use.

I don't know if this would be popular with experienced system administrators, because they are probably set in their ways. They install software from source with nothing but make, a makefile, and a compiler. Each component in that process is open to inspection. The utility would need to provide some really super-cool feature to get their attention. And it's from this perspective that I've been bringing up the points in my previous posts. So, if this is not your "target demographic" you can discount some of the points made earlier.

Just some other notes about methods using the md5sum (not promoting or discouraging any particular method).

With the md5sum embedded in the Java code, it's less resistant to tampering, but you link the gui with the script. If you make an improvement in the script, you have to redistribute both the gui and the script.

With the md5sum being separate, you can improve the script, and simply plug it in. However, you need to take extra precaution protecting the md5sum (like encrypting it as I mentioned before).

EDIT:
The reason I suggested Perl is because it is open to inspection, scripts are slightly easier to improve on (you can tinker with them easily as opposed to edit, compile, run, debug), it minimizes suspicions, and as you said, your C++ skills aren't as strong. It just seems that Perl is the clear choice.

ludeKing 09-02-2004 09:02 PM

Thanks,
Yep my target audience really is people who say 'how do i install xxx program' etc.. those who don't know much about Linux but want to make the switch and have the same style of InstallShield thing as in Windows.

Well with al lthis info I think I should be right..
I've got the installer for the actaul program to /usr/local/bin done and I know what I'm gonna write the make/make install script etc in, so cheers!

Just for being helpful, here's a screenie of what the end product may look like:
http://turing.une.edu.au/~sswinsbu/screenie.jpg

Thanks for your help!

edit: pick the typo in the screenie.
Also, what do you prefer, Sourcery or Sourcerer?


All times are GMT -5. The time now is 03:59 AM.