mirror of https://github.com/BOINC/boinc.git
141 lines
4.3 KiB
Plaintext
141 lines
4.3 KiB
Plaintext
|
#!/usr/bin/env python
|
||
|
|
||
|
# $Id$
|
||
|
'''
|
||
|
Checks project permissions, etc.
|
||
|
|
||
|
This script is designed to run AFTER make_project is executed.
|
||
|
'''
|
||
|
|
||
|
import functools, argparse
|
||
|
import grp, pwd
|
||
|
import os, socket, sys
|
||
|
|
||
|
#-----------------------------------------------------------
|
||
|
# 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 "ERREOR: project directory %s does not exst, 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
|
||
|
|
||
|
|
||
|
#-----------------------------------------------------------
|
||
|
# Main program
|
||
|
|
||
|
parser = argparse.ArgumentParser(description="Checks BOINC project directory permissions.")
|
||
|
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',]
|
||
|
|
||
|
# Run the check_permissions function on all directories
|
||
|
map(functools.partial(check_permissions, APACHE_USER), [os.path.join(PROJECT_DIR,p) for p in PATHS])
|
||
|
|
||
|
sys.exit(0)
|