Open file as superuser in python

I need to open the system file and read it. This file is usually read only by root (superuser). I have a way to set the superuser password for the user. I would like to use these credentials to open the file and read it without running my entire program as a superuser process. Is there a way to achieve this in a multi-platform way?

+4
source share
4 answers

Since privileges work very differently on Unix-like systems and Windows, you need to have code on the platform. In any case, you need to split your program into two separate programs, one of which runs with higher permissions, and the other with standard / reduced permissions.

On Unix-like systems (including Linux and Mac OS X), an executable file that works with elevated privileges should do this:

  • Suppose you are running root and open a file for reading. Since you mentioned that the file is very large, you are not actually reading the entire file, you just keep the handle of the open file. If it does not open, print an error message and exit.
  • Use setreuid(2) and setregid(2) to set the user id and group id back to the unprivileged user.
  • Use one of the exec(3) functions to execute an unprivileged executable.
  • If you want to make it so that you can run this program without using sudo , then make it root and make it set-user-ID executable using chown root the-program; chmod +s the-program chown root the-program; chmod +s the-program .

An unprivileged program will now run with normal permissions, but when it starts, it will have an open file descriptor (file descriptor No. 3), which you can use to read from your special file.

For Windows, this is similar, but slightly different:

  • Suppose you are using root and open the file for reading using CreateFile . Do not use the default security attributes - create a SECURITY_ATTRIBUTES structure with bInheritHandle set to TRUE so that the handle is inherited by child processes. If the file cannot be opened, print an error message and exit.
  • Use CreateProcess to start the child process. Go to the descriptor above on the command line (for example, printed as a numeric value); you can also use the shared memory area , but this is more of a problem than it costs for this problem.
  • Paste the manifest into this executable with the requireAdministrator set to TRUE . After that, when you run the program, you will receive a UAC prompt asking you to allow the program to make changes.

Then the child process captures the inherited descriptor, parsing the command line, and then it can read the data as it sees fit.

One of the problems with this approach is that when you inherit a descriptor, you need to use low level system calls ( read(2) on Unix, ReadFile on Windows) to read from it - you cannot use higher level functions like like C fread(3) or C ++ iostream (ok, Unix has fdopen(3) , but there is no equivalent on Windows as far as I know).

As I’m sure, you have already noticed that everything above was in C. On Unix, this is pretty easy to translate to Python, since the os module has many goodies like setreuid , exec* and fdopen . On Windows, you can perform some of these actions with the ctypes and / or Pywin32 module , but maybe stick with C.

+4
source

What you are looking for is called privilege escalation, and it very much depends on the platform on which you work. In general, what your program will have to do is run the part as superuser. For example, on Unix systems, you can use sudo to read the contents of a file.

But, as already mentioned, it really depends on which system you are running on.

+4
source

I would divide the program into two parts.

  • Processes the file and accesses the contents. He may suggest that he began with the privileges he needs.
  • Anything that does not require special privileges.

Place a configuration entry that describes how an exec or subprocess command requires additional privileges. i.e.

access_special_file: sudo access_special_file

or

access_special_file: runas / user: AccountWithPrivs access_special_file

This offloads some system features to increase privileges in the system shell, where there may be more convenient ways to obtain the necessary permissions.

+3
source

On linux, this is cynch, as @ViktorKerkez showed . This is how I transferred my WiFi password files (read only root / sudo):

 import subprocess import sys # substitute your Windoze/DOS/PowerlessShell command here: cat_wifi_pws = 'sudo cat /etc/NetworkManager/system-connections/*' process = subprocess.Popen(cat_wifi_pws, stdout=subprocess.PIPE, shell=True) # read one line at a time, as it becomes available for line in iter(process.stdout.readline, ''): sys.stdout.write(line) 

Of course, this will tell you your sudo password. And you can use gksudo if you are on a system that has it and you prefer dialog boxes. As a bonus, if you have a decent timeout_default in /etc/sudoers and you recently ran sudo in the same shell where you ran the python interpreter, you don’t have to enter a password at all.

+2
source

All Articles