From 25c5202b7e66bbef5b058fd9679070877bc54ed7 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Thu, 6 Aug 2009 20:54:53 +0000 Subject: Bug #280521 - Update selinux support to use the libselinux swig wrapper api instead of python-selinux. Thanks to Chris PeBenito for the initial patch which I've tweaked with whitespace changes and unicode support. svn path=/main/trunk/; revision=13937 --- pym/portage/__init__.py | 25 ++++++------- pym/portage/_selinux.py | 97 +++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 105 insertions(+), 17 deletions(-) (limited to 'pym') diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index af100194d..7fc52a777 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -6706,8 +6706,7 @@ def movefile(src, dest, newmtime=None, sstat=None, mysettings=None, if destexists and not stat.S_ISDIR(dstat[stat.ST_MODE]): os.unlink(dest) if selinux_enabled: - sid = selinux.get_lsid(src) - selinux.secure_symlink(target,dest,sid) + selinux.symlink(target, dest, src) else: os.symlink(target,dest) lchown(dest,sstat[stat.ST_UID],sstat[stat.ST_GID]) @@ -6762,7 +6761,7 @@ def movefile(src, dest, newmtime=None, sstat=None, mysettings=None, if not hardlinked and (selinux_enabled or sstat.st_dev == dstat.st_dev): try: if selinux_enabled: - ret=selinux.secure_rename(src,dest) + ret = selinux.rename(src, dest) else: ret=os.rename(src,dest) renamefailed=0 @@ -6780,8 +6779,8 @@ def movefile(src, dest, newmtime=None, sstat=None, mysettings=None, if stat.S_ISREG(sstat[stat.ST_MODE]): try: # For safety copy then move it over. if selinux_enabled: - selinux.secure_copy(src,dest+"#new") - selinux.secure_rename(dest+"#new",dest) + selinux.copyfile(src, dest + "#new") + selinux.rename(dest + "#new", dest) else: shutil.copyfile(src,dest+"#new") os.rename(dest+"#new",dest) @@ -6794,15 +6793,13 @@ def movefile(src, dest, newmtime=None, sstat=None, mysettings=None, return None else: #we don't yet handle special, so we need to fall back to /bin/mv - if selinux_enabled: - a=commands.getstatusoutput(MOVE_BINARY+" -c -f "+"'"+src+"' '"+dest+"'") - else: - a=commands.getstatusoutput(MOVE_BINARY+" -f "+"'"+src+"' '"+dest+"'") - if a[0]!=0: - print "!!! Failed to move special file:" - print "!!! '"+src+"' to '"+dest+"'" - print "!!!",a - return None # failure + a = commands.getstatusoutput("%s -f %s %s" % \ + (MOVE_BINARY, _shell_quote(src), _shell_quote(dest))) + if a[0] != os.EX_OK: + writemsg("!!! Failed to move special file:\n", noiselevel=-1) + writemsg("!!! '%s' to '%s'\n" % (src, dest), noiselevel=-1) + writemsg("!!! %s\n" % a, noiselevel=-1) + return None # failure try: if didcopy: if stat.S_ISLNK(sstat[stat.ST_MODE]): diff --git a/pym/portage/_selinux.py b/pym/portage/_selinux.py index b5afd9233..2a50f7434 100644 --- a/pym/portage/_selinux.py +++ b/pym/portage/_selinux.py @@ -2,7 +2,98 @@ # Distributed under the terms of the GNU General Public License v2 # $Id$ +import os import selinux -from selinux import is_selinux_enabled -from selinux_aux import setexec, secure_symlink, secure_rename, \ - secure_copy, secure_mkdir, getcontext, get_sid, get_lsid +import shutil +from selinux import is_selinux_enabled, getfilecon, lgetfilecon + +def copyfile(src, dest): + if isinstance(src, unicode): + src = src.encode('utf_8', 'replace') + if isinstance(dest, unicode): + dest = dest.encode('utf_8', 'replace') + (rc, ctx) = selinux.lgetfilecon(src) + if rc < 0: + raise OSError("copyfile: Failed getting context of \"%s\"." % src) + + setfscreate(ctx) + try: + shutil.copyfile(src, dest) + finally: + setfscreate() + +def getcontext(): + (rc, ctx) = selinux.getcon() + if rc < 0: + raise OSError("getcontext: Failed getting current process context.") + + return ctx + +def mkdir(target, refdir): + if isinstance(target, unicode): + target = target.encode('utf_8', 'replace') + if isinstance(refdir, unicode): + refdir = refdir.encode('utf_8', 'replace') + (rc, ctx) = selinux.getfilecon(refdir) + if rc < 0: + raise OSError( + "mkdir: Failed getting context of reference directory \"%s\"." \ + % refdir) + + setfscreatecon(ctx) + try: + os.mkdir(target) + finally: + setfscreatecon() + +def rename(src, dest): + if isinstance(src, unicode): + src = src.encode('utf_8', 'replace') + if isinstance(dest, unicode): + dest = dest.encode('utf_8', 'replace') + (rc, ctx) = selinux.lgetfilecon(src) + if rc < 0: + raise OSError("rename: Failed getting context of \"%s\"." % src) + + setfscreate(ctx) + try: + os.rename(src,dest) + finally: + setfscreate() + +def setexec(ctx="\n"): + if selinux.setexeccon(ctx) < 0: + raise OSError("setexec: Failed setting exec() context \"%s\"." % ctx) + +def setfscreate(ctx="\n"): + if selinux.setfscreatecon(ctx) < 0: + raise OSError( + "setfscreate: Failed setting fs create context \"%s\"." % ctx) + +def spawn(selinux_type, spawn_func, mycommand, opt_name=None, **keywords): + con = getcontext().split(":") + con[2] = selinux_type + setexec(":".join(con)) + try: + return spawn_func(mycommand, opt_name=opt_name, **keywords) + finally: + setexec() + +def symlink(target, link, reflnk): + if isinstance(target, unicode): + target = target.encode('utf_8', 'replace') + if isinstance(link, unicode): + link = link.encode('utf_8', 'replace') + if isinstance(reflnk, unicode): + reflnk = reflnk.encode('utf_8', 'replace') + (rc, ctx) = selinux.lgetfilecon(reflnk) + if rc < 0: + raise OSError( + "symlink: Failed getting context of reference symlink \"%s\"." \ + % reflnk) + + setfscreate(ctx) + try: + os.symlink(target, link) + finally: + setfscreate() -- cgit v1.2.3-1-g7c22