1#!/usr/bin/python 2# 3#Copyright (c) 2006 Olivier Sessink 4#All rights reserved. 5# 6#Redistribution and use in source and binary forms, with or without 7#modification, are permitted provided that the following conditions 8#are met: 9# * Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# * Redistributions in binary form must reproduce the above 12# copyright notice, this list of conditions and the following 13# disclaimer in the documentation and/or other materials provided 14# with the distribution. 15# * The names of its contributors may not be used to endorse or 16# promote products derived from this software without specific 17# prior written permission. 18# 19#THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20#"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21#LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22#FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23#COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24#INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 25#BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26#LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27#CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28#LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 29#ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30#POSSIBILITY OF SUCH DAMAGE. 31# 32 33from __future__ import print_function 34 35import os 36import getopt 37import sys 38import pwd 39import string 40 41users = {} 42 43def getpwuid_cached(uid): 44 if uid in users: 45 return users[uid] 46 else: 47 user = pwd.getpwuid(uid) 48 users[uid] = user 49 return user 50 51class ListResult: 52 pid = None 53 jail = None 54 exe = None 55 uid = None 56 username = None 57 cmdline = None 58 59 60 def __init__(self, pid): 61 self.pid = pid 62 sb = os.stat('/proc/'+pid) 63 self.uid = sb.st_uid 64 pwdret = getpwuid_cached(sb.st_uid) 65 self.username = pwdret[0] 66 self.jail = os.readlink('/proc/'+pid+'/root') 67 self.exe = os.readlink('/proc/'+pid+'/exe') 68 fd = open('/proc/'+pid+'/cmdline') 69 buf = fd.read(4096) 70 self.cmdline = ' '.join(buf.split('\0')[1:]) 71 fd.close() 72 73 def __eq__(self, other): 74 return (self.jail == other.jail) 75 76 def __ne__(self, other): 77 return (self.jail == other.jail) 78 79 def __lt__(self, other): 80 return (self.jail < other.jail) 81 82 def __le__(self, other): 83 return (self.jail <= other.jail) 84 85 def __gt__(self, other): 86 return (self.jail > other.jail) 87 88 def __ge__(self, other): 89 return (self.jail >= other.jail) 90 91# def __cmp__(self, other): 92# ret = cmp(self.jail, other.jail) 93# if(ret ==0): 94# ret = cmp(self.uid, other.uid) 95# if(ret ==0): 96# ret = cmp(self.pid, other.pid) 97# return ret 98 99 def optistr(self,usernamelen,jaillen,cmdlen): 100 formatstring = '%%-06s %%-0%ds %%-0%ds %%-0%ds' % (usernamelen,jaillen,cmdlen) 101 return formatstring % (self.pid, self.username[:usernamelen], self.jail[:jaillen], (self.exe+' '+self.cmdline)[:cmdlen]) 102 103 def __str__(self): 104 return '%-06s %-05s %-011s %-019s %-019s' % (self.pid, self.username, self.jail, self.exe,self.cmdline) 105 106def printResults(results,wide): 107 if (len(results)==0): 108 print('No jailed processes found') 109 return 110 results.sort() 111 usernamelen=4 # User 112 jaillen=4 # Jail 113 cmdlen=7 #Command 114 for result in results: 115 usernamelen = max(usernamelen,len(result.username)) 116 jaillen = max(jaillen,len(result.jail)) 117 cmdlen = max(cmdlen,len(result.cmdline+' '+result.exe)) 118 119 if (not wide): 120 cmdlen = min(cmdlen,80-5-usernamelen-jaillen-4) 121 122 titleformat = '%%-06s %%-0%ds %%-0%ds %%-0%ds' % (usernamelen,jaillen,min(cmdlen,80-5-usernamelen-jaillen-4)) 123 print(titleformat % ('Pid', 'User','Jail','Command')) 124 for result in results: 125 if (wide): 126 mycmdlen = len(result.cmdline+' '+result.exe) 127 else: 128 mycmdlen = cmdlen 129 print(result.optistr(usernamelen,jaillen,mycmdlen)) 130 131 132def runList(verbose,jail): 133 # open /proc/ 134 results = [] 135 dirlist = os.listdir('/proc') 136 try: 137 for entry in dirlist: 138 if (entry.isdigit()): 139 # we have a process, now read the link root 140 ret = os.readlink('/proc/'+entry+'/root') 141 if (ret != '/'): 142 results.append(ListResult(entry)) 143 except OSError as e: 144 if (e.errno == 13): 145 print('Permission denied') 146 return results 147 148def printusage(): 149 print("jk_list, lists pocesses running in a chroot jail") 150 print("-h --help print this message") 151 print("-j --jail=/path list only processes in this jail") 152 print("-w --wide print wide listing") 153 154def main(): 155 try: 156 opts, args = getopt.getopt(sys.argv[1:], "hwj:", ['wide', "help", "jail"]) 157 except getopt.GetoptError: 158 printusage() 159 sys.exit(1) 160 verbose = 0 161 jail = None 162 wide = 0 163 for o, a in opts: 164 if o in ("-h", "--help"): 165 printusage() 166 sys.exit() 167 if o in ("-j", "--jail"): 168 jail = a 169 if o in ("-v", "--verbose"): 170 verbose = 1 171 if o in ("-w", "--wide"): 172 wide = 1 173 results = runList(verbose,jail) 174 printResults(results,wide) 175 176if __name__ == "__main__": 177 main() 178