-
Notifications
You must be signed in to change notification settings - Fork 452
/
check_project
executable file
·203 lines (161 loc) · 6.29 KB
/
check_project
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/usr/bin/env python
'''
Checks project permissions and php modules.
This script is designed to run AFTER make_project is executed.
'''
import functools, argparse
import grp, pwd
import os, socket, sys
import subprocess
import shlex
#-----------------------------------------------------------
# Functions
def gethostname():
try:
return socket.getfqdn().split('.')[0]
except:
return 'localhost'
#gethostname
def check_user(user):
try:
mypwdb = pwd.getpwnam(user)
except KeyError as e:
print("ERROR: ", e)
print("ERROR: Specified apache user (%s) not found, Aborting"%(user))
sys.exit(1)
#try
# check_user
def check_dir(dir):
if not os.path.isdir(dir):
print("ERROR: project directory %s does not exist, Aborting"%(dir))
sys.exit(1)
#try
return dir
#check_dir
def determineapacheuser(user):
'''Attempts to determine the apache Web server user from the password
database. Checks a few possibilities that are linux defaults. If
one user matches, it is returned, otherwise an error created.
Known Issue: if the system has multiple users defined from the list below,
the script will abort.
'''
possibleapacheusers = [ 'apache',
'apache2',
'http',
'httpd',
'web-data',
'www-data']
if user=="FINDOUT":
allusernames = [x.pw_name for x in pwd.getpwall()]
out1 = set(allusernames).intersection(possibleapacheusers)
if len(out1)==1:
return out1.pop()
print("WARNING: Script could not determine which user runs apache Web server. Aborting")
print(" You should specify the apache user with the -a/--apache_user flag")
print(" Try running the following command with apache Web server running:")
print(" ps -ef | egrep '(httpd|apache2|apache)' | grep -v `whoami` | grep -v root")
sys.exit(1)
else:
check_user(user)
return user
#endif
#determineapacheuser
def check_permissions(user, fpath):
mypwdb = pwd.getpwnam(user)
try:
mystat = os.stat(fpath)
except OSError as e:
print("ERROR: ", e)
return 1
#try
owner_permissions = oct(mystat.st_mode)[4:5]
group_permissions = oct(mystat.st_mode)[5:6]
file_owner = pwd.getpwuid(mystat.st_uid).pw_name
group_members = grp.getgrgid(mystat.st_gid).gr_mem
'''Three checks:
1) if file owner is the user and owner's permissions allow for writing
2) if user is in group_members and group's permissions allow for writing
3) if user's gid is the same as the file's gid, and group's permissions allow for writing
The last condition is required because group_members (from gr_mem) does not
contain the primary user of the group.
'''
if (file_owner == user and owner_permissions >=5) or (user in group_members and group_permissions >=5) or (mypwdb.pw_gid==mystat.st_gid and group_permissions >=5) :
print("Info: User %s can write to file/dir %s"%(user, fpath))
return 0
#end if
print("WARNING: User %s can NOT write to %s"%(user, fpath))
return 2
#check_permissions
def check_php_modules(modulestocheck):
'''Uses php -m and checks to see if certain php modules are installed.
'''
phpcmd = ['php','-m']
try:
phpout = subprocess.check_output(phpcmd)
except Exception as e:
print("ERROR: ",e)
print("ERROR: Can't execute %s"%(" ".join(phpcmd)))
#try
phpout = str(phpout)
phpmodules = phpout.split("\n")
modulesnotfound = set(modulestocheck).difference(phpmodules)
if len(modulesnotfound)>0:
print("WARNING: The following php modules were not found on your system: %s"%(" ".join(modulesnotfound)))
return 1
print("Info: All required/recommended php modules found.")
return 0
#check_php_modules
# Checks the given command if it is executable
# can also check output (not implemented yet)
def check_tool(command):
# make sure command is a valid list to pass to subprocess.call()
if not isinstance(command, list):
command = shlex.split(command)
try:
cmdout = subprocess.check_output(command,stderr=subprocess.STDOUT)
except OSError as e:
print("WARNING: The following tool was not found on your system: %s"%(command[0]))
if e.errno != os.errno.ENOENT:
print("ERROR: ",e)
print("ERROR: Can't execute %s"%(" ".join(command)))
return 1
except subprocess.CalledProcessError as cpe:
print("WARNING: The following tool reported a non-zero returncode: %s"%(" ".join(command)))
return 2
return 0
#check_tool
#-----------------------------------------------------------
# Main program
parser = argparse.ArgumentParser(description="Checks BOINC project directory permissions and php modules.")
parser.add_argument("-p","--project_dir", action="store", dest="project_dir", required=True, help="Full path to the project root directory.")
parser.add_argument("-a","--apache_user", action="store", dest="apache_user", default="FINDOUT", help="User which apache runs. Typically www-data (Debian based), httpd (Redhat based), or apache. If not specified, the script will automatically try to determine.")
try:
args = parser.parse_args()
except Exception as e:
print("ERROR: command-line parser error", e)
sys.exit(1)
#try
# Define global variables
S_HOSTNAME = gethostname()
APACHE_USER = determineapacheuser(args.apache_user)
PROJECT_DIR = check_dir(args.project_dir)
PATHS = ['log_'+S_HOSTNAME,
'html',
'html/cache',
'html/inc',
'html/languages',
'html/languages/compiled',
'upload',]
MODULES = ["curl","gd","mysqli","xml"]
TOOLS = ['curl --version']
# Run the check_permissions function on all directories
rcperm = map(functools.partial(check_permissions, APACHE_USER), [os.path.join(PROJECT_DIR,p) for p in PATHS])
# Check for php modules
rcphp = check_php_modules(MODULES)
# Check for tools
rctools = map(check_tool,TOOLS)
if sum(rcperm)+rcphp+sum(rctools) == 0:
print("---All permissions checks passed, necessary php modules and tools installed. Your BOINC project should be ready to start.---")
else:
print("WARNING: Some problems were found with your BOINC installation, please check the messages above for details.")
sys.exit(0)