Python watch for file changes and identify user

Viewed 397

I need to produce a small script that will watch for accidental changes made by users to a large shared file structure.

I have found I can get the change events using the ReadDirectoryChanges API as per http://timgolden.me.uk/python/win32_how_do_i/watch_directory_for_changes.html

However I cant see how I can identify the user account that has made the changes so that I can send out a notification.

Is it possible to get the name of the user account that moved the file/directory.

2 Answers

Tricky question, I'll get you an answer in two ways:

First, as optional part, you can to watch file modifications themselves, and add custom actions.

Example of file modification tracking, working on Windows / Linux / Mac / BSD

import time
import watchdog.events
import watchdog.observers

class StateHandler(watchdog.events.PatternMatchingEventHandler):

    def on_modified(self, event):
        print(event.event_type)
        print(event.key)
        print(event.src_path)
        # Add your code here to do whatever you want on file modification

    def on_created(self, event):
        pass

    def on_moved(self, event):
        pass

    def on_deleted(self, event):
        pass
    
fs_event_handler = StateHandler()
fs_observer = watchdog.observers.Observer()
fs_observer.schedule(fs_event_handler, r'C:\Users\SomeUser\SomeFolder', recursive=True)


fs_observer.start()
try:
    while True:
        time.sleep(2)
except KeyboardInterrupt:
    fs_observer.stop()
fs_observer.join()

Using the above filesystem observer, you can trigger security event log reviews. You might also trigger them as scheduled task, but it's more fun to trigger them on file system modifications.

In order for security event logs to contain file modification information, you need to enable file auditing for the required directories using SACL lists (right click on your folder, security, auditing). Then you can go through the security logs on file events.

Going through security logs can be done with windows_tools. Get it installed with python -m pip install windows_tools.wmi_queries (obviously only works under Windows)

Then do the following:

from windows_tools.wmi_queries import *

result = query_wmi('SELECT * FROM Win32_NTLogEvent WHERE Logfile="Security" AND TimeGenerated > "{}"'.format(create_current_cim_timestamp(hour_offset=1)))
for r in result:
    print(r)

You can add WHERE clauses like EventCode={integer} in order to filter only the events (file modifications or else) you need. Usually the event codes you're searching are 4656, 4660, 4663, 4670 (open delete, edit, create).

See This microsoft article in order to know what WHERE clauses the event log class accepts.

DISCLAIMER: I'm the author of windows_tools package.

On an UNIX environment you can use os and pwd to retrieve the user account that has changed the file.

import os
import pwd

file_stat = os.stat("<changed_file>")
user_name = pwd.getpwuid(file_stat.st_uid).pw_name
Related