how to find the owner of a file or directory in python
I'm not really much of a python guy, but I was able to whip this up:
from os import stat
from pwd import getpwuid
def find_owner(filename):
return getpwuid(stat(filename).st_uid).pw_name
Getting the owner of the file for Windows with Python faster
It's useful in cases like this to run the code through a profiler:
> python3 -m cProfile -s cumtime owners.py
1.251999855041504 sec
163705 function calls (158824 primitive calls) in 1.263 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
5/1 0.000 0.000 1.263 1.263 {built-in method builtins.exec}
1 0.019 0.019 1.263 1.263 owners.py:1(<module>)
4999 0.024 0.000 1.058 0.000 owners.py:6(GET_THE_OWNER)
4999 0.423 0.000 0.423 0.000 {built-in method win32security.LookupAccountSid}
4999 0.264 0.000 0.280 0.000 {built-in method io.open}
4999 0.262 0.000 0.262 0.000 {built-in method win32security.GetFileSecurity}
5778/938 0.011 0.000 0.130 0.000 os.py:280(walk)
...
There's some here that can't be helped, but the calls to LookupAccountSid and io.open can be helped. The SIDs don't change, and no doubt you have a fairly small list of SIDs to use compared to the list of files. I'm actually not sure why you're opening the file and closing it, but that alone is taking considerable time:
_owner_sid_cache = {}
def GET_THE_OWNER(FILENAME):
# open (FILENAME, "r").close ()
sd = win32security.GetFileSecurity (FILENAME, win32security.OWNER_SECURITY_INFORMATION)
owner_sid = sd.GetSecurityDescriptorOwner ()
if str(owner_sid) not in _owner_sid_cache:
name, _domain, _type = win32security.LookupAccountSid (None, owner_sid)
_owner_sid_cache[str(owner_sid)] = name
return _owner_sid_cache[str(owner_sid)]
Between using this version of the function, and outputting data to a file instead of the relatively slow console, the time was dropped the time from 252 seconds to 5 seconds on a test folder on my local machine with 60,000 files.
Howto determine file owner on windows using python without pywin32
The following uses ctypes to call GetNamedSecurityInfo
. Originally it followed the code snippet that's linked in the question, but GetNamedSecurityInfo
is more useful in general than GetFileSecurity
, especially since it's paired with SetNamedSecurityInfo
in place of the obsolete function SetFileSecurity
.
ctypes and classes
import ctypes as ctypes
from ctypes import wintypes as wintypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
advapi32 = ctypes.WinDLL('advapi32', use_last_error=True)
ERROR_INVALID_FUNCTION = 0x0001
ERROR_FILE_NOT_FOUND = 0x0002
ERROR_PATH_NOT_FOUND = 0x0003
ERROR_ACCESS_DENIED = 0x0005
ERROR_SHARING_VIOLATION = 0x0020
SE_FILE_OBJECT = 1
OWNER_SECURITY_INFORMATION = 0x00000001
GROUP_SECURITY_INFORMATION = 0x00000002
DACL_SECURITY_INFORMATION = 0x00000004
SACL_SECURITY_INFORMATION = 0x00000008
LABEL_SECURITY_INFORMATION = 0x00000010
_DEFAULT_SECURITY_INFORMATION = (OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION |
LABEL_SECURITY_INFORMATION)
LPDWORD = ctypes.POINTER(wintypes.DWORD)
SE_OBJECT_TYPE = wintypes.DWORD
SECURITY_INFORMATION = wintypes.DWORD
class SID_NAME_USE(wintypes.DWORD):
_sid_types = dict(enumerate('''
User Group Domain Alias WellKnownGroup DeletedAccount
Invalid Unknown Computer Label'''.split(), 1))
def __init__(self, value=None):
if value is not None:
if value not in self.sid_types:
raise ValueError('invalid SID type')
wintypes.DWORD.__init__(value)
def __str__(self):
if self.value not in self._sid_types:
raise ValueError('invalid SID type')
return self._sid_types[self.value]
def __repr__(self):
return 'SID_NAME_USE(%s)' % self.value
PSID_NAME_USE = ctypes.POINTER(SID_NAME_USE)
class PLOCAL(wintypes.LPVOID):
_needs_free = False
def __init__(self, value=None, needs_free=False):
super(PLOCAL, self).__init__(value)
self._needs_free = needs_free
def __del__(self):
if self and self._needs_free:
kernel32.LocalFree(self)
self._needs_free = False
PACL = PLOCAL
class PSID(PLOCAL):
def __init__(self, value=None, needs_free=False):
super(PSID, self).__init__(value, needs_free)
def __str__(self):
if not self:
raise ValueError('NULL pointer access')
sid = wintypes.LPWSTR()
advapi32.ConvertSidToStringSidW(self, ctypes.byref(sid))
try:
return sid.value
finally:
if sid:
kernel32.LocalFree(sid)
class PSECURITY_DESCRIPTOR(PLOCAL):
def __init__(self, value=None, needs_free=False):
super(PSECURITY_DESCRIPTOR, self).__init__(value, needs_free)
self.pOwner = PSID()
self.pGroup = PSID()
self.pDacl = PACL()
self.pSacl = PACL()
# back references to keep this object alive
self.pOwner._SD = self
self.pGroup._SD = self
self.pDacl._SD = self
self.pSacl._SD = self
def get_owner(self, system_name=None):
if not self or not self.pOwner:
raise ValueError('NULL pointer access')
return look_up_account_sid(self.pOwner, system_name)
def get_group(self, system_name=None):
if not self or not self.pGroup:
raise ValueError('NULL pointer access')
return look_up_account_sid(self.pGroup, system_name)
def _check_bool(result, func, args):
if not result:
raise ctypes.WinError(ctypes.get_last_error())
return args
# msdn.microsoft.com/en-us/library/aa376399
advapi32.ConvertSidToStringSidW.errcheck = _check_bool
advapi32.ConvertSidToStringSidW.argtypes = (
PSID, # _In_ Sid
ctypes.POINTER(wintypes.LPWSTR)) # _Out_ StringSid
# msdn.microsoft.com/en-us/library/aa379166
advapi32.LookupAccountSidW.errcheck = _check_bool
advapi32.LookupAccountSidW.argtypes = (
wintypes.LPCWSTR, # _In_opt_ lpSystemName
PSID, # _In_ lpSid
wintypes.LPCWSTR, # _Out_opt_ lpName
LPDWORD, # _Inout_ cchName
wintypes.LPCWSTR, # _Out_opt_ lpReferencedDomainName
LPDWORD, # _Inout_ cchReferencedDomainName
PSID_NAME_USE) # _Out_ peUse
# msdn.microsoft.com/en-us/library/aa446645
advapi32.GetNamedSecurityInfoW.restype = wintypes.DWORD
advapi32.GetNamedSecurityInfoW.argtypes = (
wintypes.LPWSTR, # _In_ pObjectName
SE_OBJECT_TYPE, # _In_ ObjectType
SECURITY_INFORMATION, # _In_ SecurityInfo
ctypes.POINTER(PSID), # _Out_opt_ ppsidOwner
ctypes.POINTER(PSID), # _Out_opt_ ppsidGroup
ctypes.POINTER(PACL), # _Out_opt_ ppDacl
ctypes.POINTER(PACL), # _Out_opt_ ppSacl
ctypes.POINTER(PSECURITY_DESCRIPTOR)) # _Out_opt_ ppSecurityDescriptor
functions
def look_up_account_sid(sid, system_name=None):
SIZE = 256
name = ctypes.create_unicode_buffer(SIZE)
domain = ctypes.create_unicode_buffer(SIZE)
cch_name = wintypes.DWORD(SIZE)
cch_domain = wintypes.DWORD(SIZE)
sid_type = SID_NAME_USE()
advapi32.LookupAccountSidW(system_name, sid, name, ctypes.byref(cch_name),
domain, ctypes.byref(cch_domain), ctypes.byref(sid_type))
return name.value, domain.value, sid_type
def get_file_security(filename, request=_DEFAULT_SECURITY_INFORMATION):
# N.B. This query may fail with ERROR_INVALID_FUNCTION
# for some filesystems.
pSD = PSECURITY_DESCRIPTOR(needs_free=True)
error = advapi32.GetNamedSecurityInfoW(filename, SE_FILE_OBJECT, request,
ctypes.byref(pSD.pOwner), ctypes.byref(pSD.pGroup),
ctypes.byref(pSD.pDacl), ctypes.byref(pSD.pSacl),
ctypes.byref(pSD))
if error != 0:
raise ctypes.WinError(error)
return pSD
example usage
if __name__ == '__main__':
import os, sys
if len(sys.argv) < 2:
script_name = os.path.basename(__file__)
sys.exit('usage: {} filename'.format(script_name))
filename = sys.argv[1]
if isinstance(filename, bytes):
if hasattr(os, 'fsdecode'):
filename = os.fsdecode(filename)
else:
filename = filename.decode(sys.getfilesystemencoding())
pSD = get_file_security(filename)
owner_name, owner_domain, owner_sid_type = pSD.get_owner()
if owner_domain:
owner_name = '{}\\{}'.format(owner_domain, owner_name)
print("Path : {}".format(filename))
print("Owner: {} ({})".format(owner_name, owner_sid_type))
print("SID : {}".format(pSD.pOwner))
example output
Path : C:\Users
Owner: NT AUTHORITY\SYSTEM (WellKnownGroup)
SID : S-1-5-18
Path : C:\ProgramData
Owner: NT AUTHORITY\SYSTEM (WellKnownGroup)
SID : S-1-5-18
Path : C:\Program Files
Owner: NT SERVICE\TrustedInstaller (WellKnownGroup)
SID : S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464
Path : C:\Windows
Owner: NT SERVICE\TrustedInstaller (WellKnownGroup)
SID : S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464
How to get the owner and group of a folder with Python on a Linux machine?
Use os.stat()
to get the uid and gid of the file. Then, use pwd.getpwuid()
and grp.getgrgid()
to get the user and group names respectively.
import grp
import pwd
import os
stat_info = os.stat('/path')
uid = stat_info.st_uid
gid = stat_info.st_gid
print uid, gid
user = pwd.getpwuid(uid)[0]
group = grp.getgrgid(gid)[0]
print user, group
Easy way to get file owner in Windows 7?
I found the solution in this url.
from win32 import win32security
OwnrSecInfo = win32security.GetFileSecurity(inFilePath,
win32security.OWNER_SECURITY_INFORMATION)
SecDscp = OwnrSecInfo.GetSecurityDescriptorOwner()
# returns a tuple (u'owner, u'domain)
ownr = win32security.LookupAccountSid(None,SecDscp)
return str(ownr[0])
Find the current directory and file's directory
To get the full path to the directory a Python file is contained in, write this in that file:
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
(Note that the incantation above won't work if you've already used os.chdir()
to change your current working directory, since the value of the __file__
constant is relative to the current working directory and is not changed by an os.chdir()
call.)
To get the current working directory use
import os
cwd = os.getcwd()
Documentation references for the modules, constants and functions used above:
- The
os
andos.path
modules. - The
__file__
constant os.path.realpath(path)
(returns "the canonical path of the specified filename, eliminating any symbolic links encountered in the path")os.path.dirname(path)
(returns "the directory name of pathnamepath
")os.getcwd()
(returns "a string representing the current working directory")os.chdir(path)
("change the current working directory topath
")
Related Topics
How to Prompt For User Input and Read Command-Line Arguments
Standalone Python Applications in Linux
How to Grab the Color of a Pixel on My Desktop? (Linux)
Running Python Script as a Systemd Service
Runtimeerror: Invalid Display Variable
Why Can't My Post-Receive Hook Run a Virtualenv Source Command
Python - Can't Open Lib 'Libtdsodbc.So':File Not Found
Pandas Read_SQL With Parameters
Multiprocessing: Use Only the Physical Cores
Linux:Python:Clear Input Buffer Before Raw_Input()
Python Memory Debugging with Gdb
Writing to Shared Memory in Python Is Very Slow
How to Delete a Directory Created with Tempfile.Mkdtemp