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 08:22:00.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+'/[^/]*', "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")