views:

500

answers:

8

Is it possible to use a sudo frontend (like gksudo) to elevate the privileges of the current process? I know I can do the following:

sudo cat /etc/passwd-

But I'm interested in doing this:

sudo-become-root # magic function/command
cat /etc/passwd-

I'm writing in Python. My usecase is that I have a program that runs as the user, but may encounter files to read/write that are root-owned. I'd like to prompt for password, gain root privileges, do what I need, and then optionally drop privileges again.

I know I could separate admin logic and non-admin logic into separate processes, and then just run the admin process as root (with some communication -- policykit/dbus would be a good fit here). But I was hoping for a much simpler (though admittedly more risky) solution.

I'm thinking something like running Solaris's ppriv through sudo to then modify the current process's privileges. Which seems like a hacky-but-workable roundtrip. But as far as I know, linux doesn't offer ppriv.

(I'm surprised this isn't obvious already; it seems like a not-uncommon thing to want and doesn't seem to be a security hole to allow escalation in-process over escalation of a new process.)

A: 

Your magic function/command could be

sudo su
kogut
or perhaps `sudo $SHELL`
Noufal Ibrahim
That would be fine if I'm doing it interactively, but I need to do this programmatically.
Michael Terry
A: 
echo 'echo tee; echo hee'|sudo -s

The output is:

tee
hee
mst
+1  A: 

If you want to deal cleanly with administrative rights inside a program, you might want to use PolicyKit rather than sudo, depending on the OS you plan to run your program on.

For PolicyKit for Python, see python-slip.

Otherwise, there are two ways to call sudo to become root:

sudo -s

will make you root and keep your current environment (equivalent to sudo su)

sudo -i

will make you root and give you root's environment, too (equivalent to sudo su -)

Another way of dealing with the problem is to consider that you have the rights you need, and let the user of the program choose how to give the rights to your program (using sudo/setuid/unix groups/whatever else).

See also this question on ServerFault on the same subject.

Raphink
Right, but that would require the separation of admin and non-admin code, which I'm trying to avoid.
Michael Terry
Michael, that separation is very important in itself.
kaizer.se
I agree it's nice to have. But I'm trying to be minimally invasive for now and was curious if it's possible to do it without the separation.
Michael Terry
+1  A: 

Aptitude has a "become root" option. You may wish to see what the author did there.

Broam
Interesting. Apparently aptitude will just restart itself with sudo. The fact that they don't have a better solution suggests that there isn't one.
Michael Terry
A: 

I don't like the idea of being able to run arbitrary commands as root from a lower privileged process. However, since you want it, one of the ideas that comes to mind is to keep a setuid restricted shell which can only execute the commands you're interested in allowing. You can then use the subprocess.Popen functions to run your command using this restricted shell that will run it with elevated privileges.

Noufal Ibrahim
I'm trying to avoid having to 'run another process' as root. I wanted to run the current process as root.
Michael Terry
A: 

I wonder if this would work:

Add another group to your system, install the script as a root program and have the sudoers file contain a line that allows the script to be executed by this group. Finally add the group to the list of accounts that need to run the script.

Then the script can only be run by root or any account that has the special group in the group set after supplying the account password at the start.

See Sudo Manual for other options.

David Harris
But then the question should be on superuser ;-)
Raphink
A: 

Unfortunately, I'm not aware of a way to do what you want to do cleanly. I think your best bet is to make the program setuid (or run it under sudo) and then either do your dirty work and drop permissions, or fork() and drop permissions from one process and keep the other one around to do your root work.

What you're looking for are the setuid(2) / setreuid(2) / setregid(2) / setgroups(2) calls, but they are all hard wired to not allow you to gain privileges mid-invocation. You can only use them to "give away" privileges, as far as I know.

Steven Schlansker
Yar, that seems to be the case. Ah well. I suppose there are good reasons why it's somehow worse to gain privileges mid-invocations rather than being able to re-invoke something with privileges. Will look for another way of doing what I wanted. Thanks all!
Michael Terry
A: 

You want to authenticate with PAM. There's an example here.

LiraNuna
You can only change your UID if you're already root (or have CAP_SETUID, but unless you go through special contortions a normal app won't have that).
ephemient
Oh, I saw some example once that auths with PAM to gain some sort of privileges. I guess root is not one of them. I will keep this answer for others.
LiraNuna