how can i check admin-privileges for my script during running?
The concept of "admin-privileges" in our day of fine grained privilege control is becoming hard to define. If you are running on unix with "traditional" access control model, getting the effective user id (available in os module) and checking that against root (0) could be what you are looking for. If you know accessing a file on the system requires the privileges you want your script to have, you can use the os.access() to check if you are privileged enough.
Unfortunately there is no easy nor portable method to give. You need to find out or define the security model used, what system provided APIs are available to query and set privileges and try to locate (or possibly implement yourself) the appropriate python modules that can be used to access the API.
The classic question, why do you need to find out? What if your script tries to do what it needs to do and "just" catches and properly handles failures?
On Unix you can check whether you are root using the os.getuid function:
os.getuid() == 0 and "root" or "not root"
If you're just trying to see if you have access to a certain file that requires administrative rights, a good way to check would be:
import os
print os.access("/path/to/file", os.W_OK)
#replace W_OK with R_OK to test for read permissions
On the other hand, if you really need to know if a user is an administrative account, you can also use this code on Windows 2000 and higher:
import ctypes
print ctypes.windll.shell32.IsUserAnAdmin()
Therefore, a better, cross-platform way to find out if an user is an administrator is:
import ctypes, os
try:
is_admin = os.getuid() == 0
except:
is_admin = ctypes.windll.shell32.IsUserAnAdmin()
print is_admin
Of course, this method will only detect if the user is root on Unix, or is a member of the Administrators group on Windows. However, this is sufficient for most purposes, in my opinion.
Also note that this will fail on Windows versions below 2000, as well as Windows ME, since those are DOS-based versions of Windows and don't have any notion of permissions.
Related
I am working in python and sometimes with os.rename() I run into the problem that if the file or folder to rename is open in the windows system I get a PermissionError: [WinError 5] error.
So if I close the folder and rerun the script, everything works.
In any case I am working on Windows, but I think it is good practice that I take into account that it could also be run on Machintosh.
I don't know what the best practice is for this, but please have a little patience, I'm still learning python and really don't know how to ask the question any better than that.
In general, no. This is a violation of system security: another entity (user, session, process, etc.) is using the resource (file or folder), in a way that requires exclusive rights (typically update / modify rights). If you steal the resource, how is that other entity supposed to react or adapt to the change?
This is why an OS has these privileges and locks: to manage system resources. Since you already have user control over the resource, you are supposed to use that authority to release the file lock -- not cracking the security from outside.
However, as the controlling user, you do likely have rights to view your own sessions and jobs, to inquire which one owns the resource, and then terminate the job or otherwise force it to release the resource.
In that fashion, it is possible to steal the resource from the other process. If you want to do that, you need to educate yourself on your OS's capabilities and rights. The most useful ones will be available through Python's os package. Enjoy the learning.
To echo Prune's answer, figuring out where it's in use and closing it sounds difficult, and probably not a great idea anyway. Imagine if it's not available because some other program is currently saving to one of the files — you could end up with corrupted data.
That said, you could make your Python script smart enough to notice there's a permission error, then pause and let you know so that you could try and close things on your own before telling it to try again and continue.
import os
def try_to_rename(src, dst):
while True:
try:
os.rename(src, dst)
break
except PermissionError:
input(f"Unable to rename {src} to {dst}. If one or both "
"files/folders are open, please close them. Press Enter to "
"continue.")
P.S. It makes little difference for this simple example, but for working extensively with paths and files, I'd recommend pathlib over os. It can really make things a lot more convenient and readable.
I read the docs for checks: https://docs.djangoproject.com/en/2.2/topics/checks/
I am missing something: I would like to have a web view where an admin can see what's wrong.
Calling this view should execute the check and the result (ok or failure messages) should be visible.
I could hack something like this myself.
But I would like to go a common way, if there is already such a way.
As opposed to unit-testing this is about checking a production server.
How to do this the django-way?
Examples for checks I have on my mind: Checking if third party services are available (smtp server, archive systems, ERP systems, ...)
The builtin system check is mainly for development actually - the point is that if those tests fail your project will very probably not run at all.
But you can nonetheless call this (or any other) management command from python code using management.call_command - you'll just need to provide a writable file-like object to capture stdout/stderr:
from StringIO import StringIO
from django.core.management import call_command, check
def check_view(request):
out = StringIO()
cmd = check.Command(stdout=out, stderr=out)
call_command(check)
out.seek(0)
context = {"results": out.readlines()}
return render(request, "check.html", context)
Then it's just a matter of plugin this into your admin (which is documented so I won't give a complete example).
NB : wrt/ adding your own checks to the check command, this is fully documented too.
Cloud platform providers often provide health checks that ping your app at a certain point eg: /health
django-health-check provides tests that could be executed when /health is accessed.
If they all pass it returns a 200. Otherwise the cloud provider will notify your admins.
Of course you could make that page only visible for admins to manually check or write your own script to supervise your application status.
I am trying to kill a task but in order to do it I need admin privileges.
And so far I was not able to find a functional code that would bypass the need for admin. And when I found one than it was filled with errors or was made for python 2.
I was not able to find a functional code that would bypass the need for admin
Assuming that you have admin privileges on your system, you can run your script with evaluated privileges as detailed in this answer. Otherwise, aside from exploits specific to your version of Windows, it is not possible to "bypass" the need for admin.
As for not being able to use code written in Python 2, you can always convert code between between Python versions. This can be done manually or using an automated tool such as the standard 2to3 program that ships with CPython.
One other side note: the infinite loop in the sample of code that you posted would normally be written as
while True:
# body statements
Using 1 in place of True still works as non-zero integers are "truthy" when evaluated in a context where a boolean expression is expected.
The documentation for os.getuid() says:
Return the current process’s user id.
And of os.geteuid() says:
Return the current process’s effective user id.
So what is the difference between user id and effective user id?
For me both works same (on both 2.x and 3.x). I am using it to check if script is being run as root.
To understand how os.getuid and os.geteuid differ, you need to understand that they're are not Python specific functions (other than the os module prefix). Those functions are wrapping the getuid and geteuid system calls that are provided by essentially all Unix-like operating systems.
So, rather than looking at Python docs (which are not likely to give a lot of details), you should look at the docs for your operating system. Here is the relevant documentation for Linux, for example. Wikipedia also has a good article on Unix User IDs.
The difference between the regular UID and the Effective UID is that only the EUID is checked when you do something that requires special access (such as reading or writing a file, or making certain system calls). The UID indicates the actual user who is performing the action, but it is (usually) not considered when examining permissions. In normal programs they will be the same. Some programs change their EUID to add or subtract from the actions they are allowed to take. A smaller number also change their UID, to effectively "become" another user.
Here's an example a program that changes its EUID: The passwd program (which is used to change your password) must write to the system's password file, which is owned by the root user. Regular users can't write to that file, since if they could, they could change everyone else's password too. To resolve this, the passwd program has a bit set in its file permissions (known as the setuid bit) that indicates to the OS that it should be run with the EUID of the program's owner (e.g. root) even when it is launched by another user. The passwd program would then see its UID as the launching user, and its EUID as root. Writing to the system password file requires the EUID to be privileged. The UID is useful too, since passwd needs to know which user it's changing the password for.
There are a few other cases where the UID and EUID won't match, but they're not too common. For instance, a file server running as the super user might change its EUID to match a specific user who is requesting some file manipulations. Using the user's EUID allows the server to avoid accessing things that the user is not allowed to touch.
Function os.getuid() returns ID of a user who runs your program. Function os.geteuid() of a user your program use permissions of. In most cases this will be the same. Well known case when these values will be different is when setuid bit is set for your program executable file, and user that runs your program is different from user that own program executable. In this case os.getuid() will return ID of user who runs program, while os.geteuid() will return ID of user who own program executable.
I am trying to make an application that should not portable between computers or between users of the same computer.
Which is the best way to do this?
edit:
By not portable I meant, the application should not be usable without installing it. ie) moving the installed folder to a different computer or different user login of the same computer.
How can we get an id that is always unique to a user login in a computer?.
please excuse my poor english.
Almost no matter what mechanism you implement, the other user will always be able to decompile the program and route around what prevents running it with relative ease. Two exceptions:
Move key functionality + authentication into c modules. This makes circumvention harder, but not impossible
Move key functionality + authentication into a call to a program executing on a remote machine that you control. Here the other user needs to re-implement the function(s) based on sample input and output - direct reverse engineering is not possible.
These points are covered in further detail in the answers to the linked-to question. Of course, as some answers point out, you need to determine how much trouble you wish to go to and if it is worth your while to do so. Maybe a naive python native access control is enough deterrant, even if an adept programmer can work around it.
Let your installation script copy some modules of your program to user application directory.
In your program add that path to sys.path, that import would find your modules.
If you want only one user to have access you have to create some kind of "login".
That's what registration or activation keys are for.
http://en.wikipedia.org/wiki/Product_key
You include the user name and some machine identification in the key,