6 from os.path import join
9 def collect_writable_dirs(rootdir, uids, gids):
10 """Returns a list of directories below rootdir (including rootdir) that are writable
11 by the users with the given uids or gids or that are world writable.
12 Normally, uid(s) is the user id of the apache user (e.g. www-data) and gids is a list
13 of group ids this user is member of.
15 :param rootdir: string. directory where the search should start at
16 :param uids: list of integer user ids
17 :param gids: list of integer group ids"""
18 assert isinstance(rootdir, str)
19 assert isinstance(uids, list)
20 for uid in uids: assert isinstance(uid, int)
21 assert isinstance(gids, list)
22 for gid in gids: assert isinstance(gid, int)
24 writable_dirs = [] # dirs with write permissions - this list is filled by this function
26 for root, dirs, files in os.walk(rootdir):
28 dp = join(root, d) # dp is the dir with path
30 if (s.st_mode & stat.S_IFLNK) == stat.S_IFLNK: continue # skip symlinks
31 if s.st_uid in uids and (s.st_mode & stat.S_IWUSR) > 0:
32 writable_dirs.append(dp)
33 elif s.st_gid in gids and (s.st_mode & stat.S_IWGRP) > 0:
34 writable_dirs.append(dp)
35 elif (s.st_mode & stat.S_IWOTH) > 0:
36 writable_dirs.append(dp)
42 def summarize_dirs(writable_dirs):
43 """Takes a list of directories and omits each subdirectory if its parent directory
44 is also included in the list. The modified list is returned.
46 :param writable_dirs: List of directories (strings)."""
47 writable_dirs = sorted(writable_dirs)
50 while i < len(writable_dirs)-1:
51 if writable_dirs[i+1].startswith(writable_dirs[i] + '/'):
52 del writable_dirs[i+1]
60 if __name__ == '__main__':
63 uids = [33] # user ids of the user whos write permissions should be found
64 gids = [33, 42, 121, 127] # group ids of the user whos write permissions should be found
65 rootdir = '/home' # directory where the seach is started
67 # collect and summarize writable directories
68 writable_dirs = collect_writable_dirs(rootdir, uids, gids)
69 writable_dirs = summarize_dirs(writable_dirs)
71 # print writable directories
72 for d in writable_dirs: