How to Find the Owner of a File or Directory in Python

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 and os.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 pathname path")
  • os.getcwd() (returns "a string representing the current working directory")
  • os.chdir(path) ("change the current working directory to path")


Related Topics



Leave a reply



Submit