7500758a95
- Trap failure on write - Rewrite genhomedircon to generate file_context.homedirs - several passes
290 lines
9.7 KiB
Diff
290 lines
9.7 KiB
Diff
diff --exclude-from=exclude -N -u -r nsapolicycoreutils/scripts/genhomedircon policycoreutils-1.21.15/scripts/genhomedircon
|
|
--- nsapolicycoreutils/scripts/genhomedircon 2005-01-28 11:16:36.000000000 -0500
|
|
+++ policycoreutils-1.21.15/scripts/genhomedircon 2005-02-11 00:54:56.000000000 -0500
|
|
@@ -13,38 +13,109 @@
|
|
#
|
|
# ASSUMPTIONS:
|
|
#
|
|
-# If a user has more than one role in FILECONTEXTDIR/users, genhomedircon uses
|
|
+# The file CONTEXTDIR/files/homedir_template exists. This file is used to
|
|
+# set up the home directory context for each real user.
|
|
+#
|
|
+# If a user has more than one role in CONTEXTDIR/local.users, genhomedircon uses
|
|
# the first role in the list.
|
|
#
|
|
-# If a user is not listed in FILECONTEXTDIR/users, genhomedircon assumes that
|
|
-# the user's home dir will be found in one of the HOME_ROOTs.
|
|
+# If a user is not listed in CONTEXTDIR/local.users, he will default to user_u, role user
|
|
#
|
|
# "Real" users (as opposed to system users) are those whose UID is greater than
|
|
# or equal STARTING_UID (usually 500) and whose login is not a member of
|
|
-# EXCLUDE_LOGINS. Users who are explicitly defined in FILECONTEXTDIR/users
|
|
+# EXCLUDE_LOGINS. Users who are explicitly defined in CONTEXTDIR/local.users
|
|
# are always "real" (including root, in the default configuration).
|
|
#
|
|
+#
|
|
|
|
-import commands, sys, os, pwd, string
|
|
+import commands, sys, os, pwd, string, getopt
|
|
+
|
|
+rhplPath="/usr/lib/python%d.%d/site-packages/rhpl" % (sys.version_info[0], sys.version_info[1])
|
|
+if not rhplPath in sys.path:
|
|
+ sys.path.append(rhplPath)
|
|
+
|
|
+rhplPath="/usr/lib64/python%d.%d/site-packages/rhpl" % (sys.version_info[0], sys.version_info[1])
|
|
+if not rhplPath in sys.path:
|
|
+ sys.path.append(rhplPath)
|
|
+
|
|
+from Conf import *
|
|
|
|
EXCLUDE_LOGINS=["/sbin/nologin", "/bin/false"]
|
|
|
|
-def getPrefixes():
|
|
- ulist = pwd.getpwall()
|
|
- prefixes = {}
|
|
- for u in ulist:
|
|
- if u[2] >= STARTING_UID and \
|
|
- not u[6] in EXCLUDE_LOGINS and \
|
|
- u[5] != "/" and \
|
|
- string.count(u[5], "/") > 1:
|
|
- prefix = u[5][:string.rfind(u[5], "/")]
|
|
- if not prefixes.has_key(prefix):
|
|
- prefixes[prefix] = ""
|
|
- return prefixes
|
|
-
|
|
-def getUsers():
|
|
- rc = commands.getstatusoutput("grep ^user %s/users" % FILECONTEXTDIR)
|
|
+def getStartingUID():
|
|
+ conf=Conf("/etc/login.defs")
|
|
+ while conf.findnextcodeline():
|
|
+ if conf.getfields()[0] == "UID_MIN":
|
|
+ return int(conf.getfields()[1])
|
|
+
|
|
+ conf.nextline()
|
|
+ return 500
|
|
+
|
|
+def getDefaultHomeDir():
|
|
+ conf=ConfShellVar("/etc/default/useradd")
|
|
+ if conf.has_key("HOME"):
|
|
+ return conf["HOME"]
|
|
+ else:
|
|
+ return "/home"
|
|
+
|
|
+def usage(error = ""):
|
|
+ if error != "":
|
|
+ sys.stderr.write("%s\n" % (error,))
|
|
+ sys.stderr.write("Usage: %s [ -d selinuxdir ] [-n] [-t selinuxtype ]\n" % sys.argv[0])
|
|
+ sys.stderr.flush()
|
|
+ sys.exit(1)
|
|
+
|
|
+def errorExit(error):
|
|
+ sys.stderr.write("%s exiting for: " % sys.argv[0])
|
|
+ sys.stderr.write("%s\n" % error)
|
|
+ sys.stderr.flush()
|
|
+ sys.exit(1)
|
|
+
|
|
+class selinuxConfig:
|
|
+ def __init__(self, selinuxdir="/etc/selinux", type="targeted", usepwd=1):
|
|
+ self.type=type
|
|
+ self.selinuxdir=selinuxdir +"/"
|
|
+ self.selinuxconfig=self.selinuxdir+"config"
|
|
+ self.contextdir="/contexts"
|
|
+ self.filecontextdir=self.contextdir+"/files"
|
|
+ self.usepwd=usepwd
|
|
+ if os.access(self.selinuxconfig, os.F_OK) == 1:
|
|
+ conf=ConfShellVar(self.selinuxconfig)
|
|
+ if conf.has_key("SELINUXTYPE"):
|
|
+ self.type=conf.vars["SELINUXTYPE"]
|
|
+
|
|
+ def getSelinuxType(self):
|
|
+ return self.type
|
|
+
|
|
+ def getFileContextDir(self):
|
|
+ return self.selinuxdir+self.getSelinuxType()+self.filecontextdir
|
|
+
|
|
+ def getContextDir(self):
|
|
+ return self.selinuxdir+self.getSelinuxType()+self.contextdir
|
|
+
|
|
+ def getHomeDirTemplate(self):
|
|
+ return self.getFileContextDir()+"/homedir_template"
|
|
+
|
|
+ def getHomeRootContext(self):
|
|
+ rc=commands.getstatusoutput("grep HOME_ROOT %s | sed -e \"s|^HOME_ROOT|%s|\"" % ( self.getHomeDirTemplate(), getDefaultHomeDir()))
|
|
+ if rc[0] == 0:
|
|
+ return rc[1]
|
|
+ else:
|
|
+ errorExit(string.join("sed error ", rc[1]))
|
|
+
|
|
+ def getUsersFile(self):
|
|
+ return self.selinuxdir+self.getSelinuxType()+"/users/local.users"
|
|
+
|
|
+
|
|
+ def heading(self):
|
|
+ ret = "\n#\n#\n# User-specific file contexts, generated via %s\n" % sys.argv[0]
|
|
+ ret += "# edit %s to change file_context\n#\n#\n" % self.getUsersFile()
|
|
+ return ret
|
|
+
|
|
+ def getUsers(self):
|
|
+ rc = commands.getstatusoutput("grep ^user %s" % self.getUsersFile())
|
|
udict = {}
|
|
+ prefs = {}
|
|
if rc[0] == 0:
|
|
ulist = rc[1].strip().split("\n")
|
|
for u in ulist:
|
|
@@ -68,72 +139,90 @@
|
|
sys.stderr.write("The user \"%s\" is not present in the passwd file, skipping...\n" % (user[1],))
|
|
return udict
|
|
|
|
-def usage(error = ""):
|
|
- if error != "":
|
|
- sys.stderr.write("%s\n" % (error,))
|
|
- sys.stderr.write("Usage: %s POLICYSOURCEDIR FILE_CONTEXTS\n" % sys.argv[0])
|
|
- sys.stderr.flush()
|
|
- sys.exit(1)
|
|
-
|
|
-def errorExit(error):
|
|
- sys.stderr.write("%s exiting for: " % sys.argv[0])
|
|
- sys.stderr.write("%s\n" % error)
|
|
- sys.stderr.flush()
|
|
- sys.exit(1)
|
|
-
|
|
-def update(filecontext, user, prefs):
|
|
- rc=commands.getstatusoutput("grep -h '^HOME_DIR' %s | grep -v vmware | sed -e 's|HOME_DIR|%s|' -e 's/ROLE/%s/' -e 's/system_u/%s/'" % (filecontext, prefs["home"], prefs["role"], user))
|
|
- if rc[0] == 0:
|
|
- print rc[1]
|
|
- else:
|
|
- errorExit(string.join("grep/sed error ", rc[1]))
|
|
- return rc
|
|
-
|
|
-try:
|
|
- if len(sys.argv) != 3:
|
|
- print len(sys.argv)
|
|
- usage("Incorrect parameters")
|
|
-
|
|
- rc=commands.getstatusoutput("grep -h '^UID_MIN' /etc/login.defs | sed -e 's/^UID_MIN[^0-9]*//'")
|
|
- if rc[0] == 0:
|
|
- STARTING_UID=int(rc[1])
|
|
- else:
|
|
- STARTING_UID=500
|
|
-
|
|
- FILECONTEXTDIR=sys.argv[1]
|
|
- prefixes = getPrefixes()
|
|
-
|
|
- rc=commands.getstatusoutput("grep -h '^HOME' /etc/default/useradd")
|
|
- if rc[0] == 0:
|
|
- homedir = rc[1].split("=")[1]
|
|
- else:
|
|
- sys.stderr.write("%s\n" % (rc[1],))
|
|
- sys.stderr.write("You do not have access to /etc/default/useradd, default /home\n")
|
|
- sys.stderr.flush()
|
|
- homedir = "/home"
|
|
-
|
|
-
|
|
- if not prefixes.has_key(homedir):
|
|
- prefixes[homedir] = ""
|
|
-
|
|
- # There may be a more elegant sed script to expand a macro to multiple lines, but this works
|
|
- sed_root = "h; s|^HOME_ROOT|%s|" % (string.join(prefixes.keys(), "|; p; g; s|^HOME_ROOT|"),)
|
|
- sed_dir = "h; s|^HOME_DIR|%s/[^/]+|; s|ROLE_|user_|" % (string.join(prefixes.keys(), "/[^/]+|; s|ROLE_|user_|; p; g; s|^HOME_DIR|"),)
|
|
-
|
|
- # Fill in HOME_ROOT, HOME_DIR, and ROLE for users not explicitly defined in /etc/security/selinux/src/policy/users
|
|
- rc=commands.getstatusoutput("sed -e \"/^HOME_ROOT/{%s}\" -e \"/^HOME_DIR/{%s}\" %s" % (sed_root, sed_dir, sys.argv[2]))
|
|
- if rc[0] == 0:
|
|
- print rc[1]
|
|
- else:
|
|
- errorExit(string.join("sed error ", rc[1]))
|
|
-
|
|
- users = getUsers()
|
|
- print "\n#\n# User-specific file contexts\n#\n"
|
|
-
|
|
+ def getHomeDirContext(self, user, home, role):
|
|
+ ret="\n\n#\n# Context for user %s\n#\n\n" % user
|
|
+ rc=commands.getstatusoutput("grep -e '^HOME_DIR' %s | sed -e 's|HOME_DIR|%s|' -e 's/ROLE/%s/' -e 's/system_u/%s/'" % (self.getHomeDirTemplate(), home, role, user))
|
|
+ return ret + rc[1] + "\n"
|
|
+
|
|
+
|
|
+ def genHomeDirContext(self):
|
|
+ users = self.getUsers()
|
|
+ ret=""
|
|
# Fill in HOME and ROLE for users that are defined
|
|
for u in users.keys():
|
|
- update(sys.argv[2], u, users[u])
|
|
+ ret += self.getHomeDirContext (u, users[u]["home"], users[u]["role"])
|
|
+ return ret
|
|
+
|
|
+ def getHomeDirs(self):
|
|
+ homedirs = []
|
|
+ homedirs.append(getDefaultHomeDir())
|
|
+ starting_uid=getStartingUID()
|
|
+ if self.usepwd==0:
|
|
+ return homedirs
|
|
+ ulist = pwd.getpwall()
|
|
+ for u in ulist:
|
|
+ if u[2] >= starting_uid and \
|
|
+ not u[6] in EXCLUDE_LOGINS and \
|
|
+ u[5] != "/" and \
|
|
+ string.count(u[5], "/") > 1:
|
|
+ homedir = u[5][:string.rfind(u[5], "/")]
|
|
+ if not homedir in homedirs:
|
|
+ homedirs.append(homedir)
|
|
+
|
|
+ homedirs.sort()
|
|
+ return homedirs
|
|
+
|
|
+ def genoutput(self):
|
|
+ ret= self.heading()
|
|
+ ret += self.getHomeRootContext()
|
|
+ for h in self.getHomeDirs():
|
|
+ ret += self.getHomeDirContext ("user_u" , h+'/[A-z0-9]*', "user")
|
|
+ ret += self.genHomeDirContext()
|
|
+ return ret
|
|
+
|
|
+ def printout(self):
|
|
+ print self.genoutput()
|
|
+
|
|
+ def write(self):
|
|
+ try:
|
|
+ fd = open(self.getFileContextDir()+"/file_contexts.homedirs", "w")
|
|
+ fd.write(self.genoutput())
|
|
+ fd.close()
|
|
+ except IOError, error:
|
|
+ sys.stderr.write("%s: %s\n" % ( sys.argv[0], error ))
|
|
+
|
|
+
|
|
+
|
|
+#
|
|
+# This script will generate home dir file context
|
|
+# based off the homedir_template file, entries in the password file, and
|
|
+#
|
|
+try:
|
|
+ usepwd=1
|
|
+ type="targeted"
|
|
+ directory="/etc/selinux"
|
|
+ gopts, cmds = getopt.getopt(sys.argv[1:], 'nd:t:', ['help',
|
|
+ 'type=',
|
|
+ 'nopasswd',
|
|
+ 'dir='])
|
|
+ for o,a in gopts:
|
|
+ if o == '--type' or o == "-t":
|
|
+ type=a
|
|
+ if o == '--nopasswd' or o == "-n":
|
|
+ usepwd=0
|
|
+ if o == '--dir' or o == "-d":
|
|
+ directory=a
|
|
+ if o == '--help':
|
|
+ usage()
|
|
+
|
|
+
|
|
+ selconf=selinuxConfig(directory, type, usepwd)
|
|
+ selconf.write()
|
|
+
|
|
+except getopt.error, error:
|
|
+ errorExit(string.join("Options Error ", error))
|
|
+
|
|
except ValueError, error:
|
|
- errorExit(string.join("ValueError ", error))
|
|
+ errorExit(string.join("ValueError ", error))
|
|
except IndexError, error:
|
|
- errorExit("IndexError")
|
|
+ errorExit("IndexError")
|