#! /usr/bin/python -E
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Red Hat 
# see file 'COPYING' for use and warranty information
#
# semanage is a tool for managing SELinux configuration files
#
#    This program is free software; you can redistribute it and/or
#    modify it under the terms of the GNU General Public License as
#    published by the Free Software Foundation; either version 2 of
#    the License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
#                                        02111-1307  USA
#
#  

import pwd, grp, string, selinux, tempfile, os, re, sys, stat
from semanage import *;
PROGNAME = "policycoreutils"
import sepolgen.module as module

import gettext
gettext.bindtextdomain(PROGNAME, "/usr/share/locale")
gettext.textdomain(PROGNAME)
try:
       gettext.install(PROGNAME, localedir = "/usr/share/locale", unicode = 1)
except IOError:
       import __builtin__
       __builtin__.__dict__['_'] = unicode

import syslog

file_types = {}
file_types[""] = SEMANAGE_FCONTEXT_ALL;
file_types["all files"] = SEMANAGE_FCONTEXT_ALL;
file_types["--"] = SEMANAGE_FCONTEXT_REG;
file_types["regular file"] = SEMANAGE_FCONTEXT_REG;
file_types["-d"] = SEMANAGE_FCONTEXT_DIR;
file_types["directory"] = SEMANAGE_FCONTEXT_DIR;
file_types["-c"] = SEMANAGE_FCONTEXT_CHAR;
file_types["character device"] = SEMANAGE_FCONTEXT_CHAR;
file_types["-b"] = SEMANAGE_FCONTEXT_BLOCK;
file_types["block device"] = SEMANAGE_FCONTEXT_BLOCK;
file_types["-s"] = SEMANAGE_FCONTEXT_SOCK;
file_types["socket"] = SEMANAGE_FCONTEXT_SOCK;
file_types["-l"] = SEMANAGE_FCONTEXT_LINK;
file_types["symbolic link"] = SEMANAGE_FCONTEXT_LINK;
file_types["-p"] = SEMANAGE_FCONTEXT_PIPE;
file_types["named pipe"] = SEMANAGE_FCONTEXT_PIPE;

try:
	import audit
	class logger:
		def __init__(self):
			self.audit_fd = audit.audit_open()

		def log(self, success, msg, name = "", sename = "", serole = "", serange = "", old_sename = "", old_serole = "", old_serange = ""):
			audit.audit_log_semanage_message(self.audit_fd, audit.AUDIT_USER_ROLE_CHANGE, sys.argv[0], str(msg), name, 0, sename, serole, serange, old_sename, old_serole, old_serange, "", "", "", success);
except:
	class logger:
		def log(self, success, msg, name = "", sename = "", serole = "", serange = "", old_sename = "", old_serole = "", old_serange = ""):
			if success == 1:
				message = "Successful: "
			else:
				message = "Failed: "
			message += " %s name=%s" % (msg, name)
			if sename != "":
				message += " sename=" + sename
			if old_sename != "":
				message += " old_sename=" + old_sename
			if serole != "":
				message += " role=" + serole
			if old_serole != "":
				message += " old_role=" + old_serole
			if serange != "" and serange != None:
				message += " MLSRange=" + serange
			if old_serange != "" and old_serange != None:
				message += " old_MLSRange=" + old_serange
			syslog.syslog(message);
			
mylog = logger()		

import xml.etree.ElementTree

booleans_dict = {}
try:
       tree = xml.etree.ElementTree.parse("/usr/share/selinux/devel/policy.xml")
       for l in  tree.findall("layer"):
              for m in  l.findall("module"):
                     for b in  m.findall("tunable"):
                            desc = b.find("desc").find("p").text.strip("\n")
                            desc = re.sub("\n", " ", desc)
                            booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
                     for b in  m.findall("bool"):
                            desc = b.find("desc").find("p").text.strip("\n")
                            desc = re.sub("\n", " ", desc)
                            booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc)
              for i in  tree.findall("bool"):
                     desc = i.find("desc").find("p").text.strip("\n")
                     desc = re.sub("\n", " ", desc)
                     booleans_dict[i.get('name')] = (_("global"), i.get('dftval'), desc)
       for i in  tree.findall("tunable"):
              desc = i.find("desc").find("p").text.strip("\n")
              desc = re.sub("\n", " ", desc)
              booleans_dict[i.get('name')] = (_("global"), i.get('dftval'), desc)
except IOError, e:
       #print _("Failed to translate booleans.\n%s") % e
       pass

def boolean_desc(boolean):
       if boolean in booleans_dict:
              return _(booleans_dict[boolean][2])
       else:
              return boolean

def validate_level(raw):
	sensitivity = "s[0-9]*"
	category = "c[0-9]*"
	cat_range = category + "(\." + category +")?"
	categories = cat_range + "(\," + cat_range + ")*"
	reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?"
	return re.search("^" + reg +"$", raw)

def translate(raw, prepend = 1):
        filler = "a:b:c:"
        if prepend == 1:
		context = "%s%s" % (filler, raw)
	else:
		context = raw
	(rc, trans) = selinux.selinux_raw_to_trans_context(context)
	if rc != 0:
		return raw
	if prepend:
		trans = trans[len(filler):]
	if trans == "":
		return raw
	else:
		return trans
	
def untranslate(trans, prepend = 1):
        filler = "a:b:c:"
 	if prepend == 1:
		context = "%s%s" % (filler, trans)
	else:
		context = trans

	(rc, raw) = selinux.selinux_trans_to_raw_context(context)
	if rc != 0:
		return trans
	if prepend:
		raw = raw[len(filler):]
	if raw == "":
		return trans
	else:
		return raw
	
class semanageRecords:
        transaction = False
        handle = None
        def __init__(self, store):
               global handle
                      
               self.sh = self.get_handle(store)

        def get_handle(self, store):
               global is_mls_enabled

               if semanageRecords.handle:
                      return semanageRecords.handle

               handle = semanage_handle_create()
               if not handle:
                      raise ValueError(_("Could not create semanage handle"))

               if not semanageRecords.transaction and store != "":
                      semanage_select_store(handle, store, SEMANAGE_CON_DIRECT);
                     semanageRecords.store = store

               if not semanage_is_managed(handle):
                      semanage_handle_destroy(handle)
                      raise ValueError(_("SELinux policy is not managed or store cannot be accessed."))

               rc = semanage_access_check(handle)
               if rc < SEMANAGE_CAN_READ:
                      semanage_handle_destroy(handle)
                      raise ValueError(_("Cannot read policy store."))

               rc = semanage_connect(handle)
               if rc < 0:
                      semanage_handle_destroy(handle)
                      raise ValueError(_("Could not establish semanage connection"))

               is_mls_enabled = semanage_mls_enabled(handle)
               if is_mls_enabled < 0:
                      semanage_handle_destroy(handle)
                      raise ValueError(_("Could not test MLS enabled status"))

               semanageRecords.handle = handle
               return semanageRecords.handle

        def deleteall(self):
               raise ValueError(_("Not yet implemented"))

        def start(self):
               if semanageRecords.transaction:
                      raise ValueError(_("Semanage transaction already in progress"))
               self.begin()
               semanageRecords.transaction = True

        def begin(self):
               if semanageRecords.transaction:
                      return
               rc = semanage_begin_transaction(self.sh)
               if rc < 0:
                      raise ValueError(_("Could not start semanage transaction"))
        def commit(self):
               if semanageRecords.transaction:
                      return
               rc = semanage_commit(self.sh) 
               if rc < 0:
                      raise ValueError(_("Could not commit semanage transaction"))

        def finish(self):
               if not semanageRecords.transaction:
                      raise ValueError(_("Semanage transaction not in progress"))
               semanageRecords.transaction = False
               self.commit()

class dontauditClass(semanageRecords):
	def __init__(self, store):
               semanageRecords.__init__(self, store)

	def toggle(self, dontaudit):
               if dontaudit not in [ "on", "off" ]:
                      raise ValueError(_("dontaudit requires either 'on' or 'off'"))
               self.begin()
               rc = semanage_set_disable_dontaudit(self.sh, dontaudit == "off")
               self.commit()
               
class permissiveRecords(semanageRecords):
	def __init__(self, store):
               semanageRecords.__init__(self, store)

	def get_all(self):
               l = []
               (rc, mlist, number) = semanage_module_list(self.sh)
               if rc < 0:
                      raise ValueError(_("Could not list SELinux modules"))

               for i in range(number):
                      mod = semanage_module_list_nth(mlist, i)
                      name = semanage_module_get_name(mod)
                      if name and name.startswith("permissive_"):
                             l.append(name.split("permissive_")[1])
               return l

	def list(self, heading = 1, locallist = 0):
		if heading:
			print "\n%-25s\n" % (_("Permissive Types"))
                for t in self.get_all():
                       print t


	def add(self, type):
               import glob
               name = "permissive_%s" % type
               dirname = "/var/lib/selinux"
               os.chdir(dirname)
               filename = "%s.te" % name
               modtxt = """
module %s 1.0;

require {
          type %s;
}

permissive %s;
""" % (name, type, type)
               fd = open(filename, 'w')
               fd.write(modtxt)
               fd.close()
               mc = module.ModuleCompiler()
               mc.create_module_package(filename, 1)
               fd = open("permissive_%s.pp" % type)
               data = fd.read()
               fd.close()

               rc = semanage_module_install(self.sh, data, len(data));
               if rc >= 0:
                      self.commit()

               for root, dirs, files in os.walk("tmp", topdown = False):
                      for name in files:
                             os.remove(os.path.join(root, name))
                      for name in dirs:
                             os.rmdir(os.path.join(root, name))
               os.removedirs("tmp")
               for i in glob.glob("permissive_%s.*" % type):
                      os.remove(i)
               if rc < 0:
			raise ValueError(_("Could not set permissive domain %s (module installation failed)") % name)

	def delete(self, name):
               for n in name.split():
                      rc = semanage_module_remove(self.sh, "permissive_%s" % n)
                      if rc < 0:
                             raise ValueError(_("Could not remove permissive domain %s (remove failed)") % name)
                      
               self.commit()
			
	def deleteall(self):
               l = self.get_all()
               if len(l) > 0:
                      all = " ".join(l)
                      self.delete(all)

class loginRecords(semanageRecords):
	def __init__(self, store = ""):
		semanageRecords.__init__(self, store)

	def __add(self, name, sename, serange):
		if is_mls_enabled == 1:
			if serange == "":
				serange = "s0"
			else:
				serange = untranslate(serange)
			
		if sename == "":
			sename = "user_u"
			
		(rc, k) = semanage_seuser_key_create(self.sh, name)
		if rc < 0:
			raise ValueError(_("Could not create a key for %s") % name)

		(rc, exists) = semanage_seuser_exists(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if login mapping for %s is defined") % name)
		if exists:
			raise ValueError(_("Login mapping for %s is already defined") % name)
                if name[0] == '%':
                       try:
                              grp.getgrnam(name[1:])
                       except:
                              raise ValueError(_("Linux Group %s does not exist") % name[1:])
                else:
                       try:
                              pwd.getpwnam(name)
                       except:
                              raise ValueError(_("Linux User %s does not exist") % name)

                (rc, u) = semanage_seuser_create(self.sh)
                if rc < 0:
                       raise ValueError(_("Could not create login mapping for %s") % name)

                rc = semanage_seuser_set_name(self.sh, u, name)
                if rc < 0:
                       raise ValueError(_("Could not set name for %s") % name)

                if serange != "":
                       rc = semanage_seuser_set_mlsrange(self.sh, u, serange)
                       if rc < 0:
                              raise ValueError(_("Could not set MLS range for %s") % name)

                rc = semanage_seuser_set_sename(self.sh, u, sename)
                if rc < 0:
                       raise ValueError(_("Could not set SELinux user for %s") % name)

                rc = semanage_seuser_modify_local(self.sh, k, u)
                if rc < 0:
                       raise ValueError(_("Could not add login mapping for %s") % name)

		semanage_seuser_key_free(k)
		semanage_seuser_free(u)

	def add(self, name, sename, serange):
		try:
                        self.begin()
                        self.__add(name, sename, serange)
                        self.commit()

		except ValueError, error:
			mylog.log(0, _("add SELinux user mapping"), name, sename, "", serange);
			raise error
		
		mylog.log(1, _("add SELinux user mapping"), name, sename, "", serange);

	def __modify(self, name, sename = "", serange = ""):
               if sename == "" and serange == "":
                      raise ValueError(_("Requires seuser or serange"))

               (rc, k) = semanage_seuser_key_create(self.sh, name)
               if rc < 0:
                      raise ValueError(_("Could not create a key for %s") % name)

               (rc, exists) = semanage_seuser_exists(self.sh, k)
               if rc < 0:
                      raise ValueError(_("Could not check if login mapping for %s is defined") % name)
               if not exists:
                      raise ValueError(_("Login mapping for %s is not defined") % name)

               (rc, u) = semanage_seuser_query(self.sh, k)
               if rc < 0:
                      raise ValueError(_("Could not query seuser for %s") % name)

               oldserange = semanage_seuser_get_mlsrange(u)
               oldsename = semanage_seuser_get_sename(u)
               if serange != "":
                      semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange))
               else:
                      serange = oldserange

               if sename != "":
                      semanage_seuser_set_sename(self.sh, u, sename)
               else:
                      sename = oldsename

               rc = semanage_seuser_modify_local(self.sh, k, u)
               if rc < 0:
                      raise ValueError(_("Could not modify login mapping for %s") % name)

               semanage_seuser_key_free(k)
               semanage_seuser_free(u)

               mylog.log(1, "modify selinux user mapping", name, sename, "", serange, oldsename, "", oldserange);

	def modify(self, name, sename = "", serange = ""):
		try:
                        self.begin()
                        self.__modify(name, sename, serange)
                        self.commit()

		except ValueError, error:
			mylog.log(0, "modify selinux user mapping", name, sename, "", serange, "", "", "");
			raise error
		
	def __delete(self, name):
               (rc, k) = semanage_seuser_key_create(self.sh, name)
               if rc < 0:
                      raise ValueError(_("Could not create a key for %s") % name)

               (rc, exists) = semanage_seuser_exists(self.sh, k)
               if rc < 0:
                      raise ValueError(_("Could not check if login mapping for %s is defined") % name)
               if not exists:
                      raise ValueError(_("Login mapping for %s is not defined") % name)

               (rc, exists) = semanage_seuser_exists_local(self.sh, k)
               if rc < 0:
                      raise ValueError(_("Could not check if login mapping for %s is defined") % name)
               if not exists:
                      raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name)

               rc = semanage_seuser_del_local(self.sh, k)
               if rc < 0:
                      raise ValueError(_("Could not delete login mapping for %s") % name)

               semanage_seuser_key_free(k)

	def delete(self, name):
		try:
                       self.begin()
                       self.__delete(name)
                       self.commit()

		except ValueError, error:
			mylog.log(0, "delete SELinux user mapping", name);
			raise error
		
		mylog.log(1, "delete SELinux user mapping", name);

	def deleteall(self):
		(rc, ulist) = semanage_seuser_list_local(self.sh)
		if rc < 0:
			raise ValueError(_("Could not list login mappings"))

                self.begin()
		for u in ulist:
			self.__delete(semanage_seuser_get_name(u))
                self.commit()

	def get_all(self, locallist = 0):
		ddict = {}
                if locallist:
                       (rc, self.ulist) = semanage_seuser_list_local(self.sh)
                else:
                       (rc, self.ulist) = semanage_seuser_list(self.sh)
		if rc < 0:
			raise ValueError(_("Could not list login mappings"))

		for u in self.ulist:
			name = semanage_seuser_get_name(u)
			ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u))
		return ddict

	def list(self,heading = 1, locallist = 0):
		ddict = self.get_all(locallist)
		keys = ddict.keys()
		keys.sort()
		if is_mls_enabled == 1:
			if heading:
				print "\n%-25s %-25s %-25s\n" % (_("Login Name"), _("SELinux User"), _("MLS/MCS Range"))
			for k in keys:
				print "%-25s %-25s %-25s" % (k, ddict[k][0], translate(ddict[k][1]))
		else:
			if heading:
				print "\n%-25s %-25s\n" % (_("Login Name"), _("SELinux User"))
			for k in keys:
				print "%-25s %-25s" % (k, ddict[k][0])

class seluserRecords(semanageRecords):
	def __init__(self, store = ""):
		semanageRecords.__init__(self, store)

	def __add(self, name, roles, selevel, serange, prefix):
		if is_mls_enabled == 1:
			if serange == "":
				serange = "s0"
			else:
				serange = untranslate(serange)
			
			if selevel == "":
				selevel = "s0"
			else:
				selevel = untranslate(selevel)
			
                if len(roles) < 1:
                       raise ValueError(_("You must add at least one role for %s") % name)
                       
                (rc, k) = semanage_user_key_create(self.sh, name)
                if rc < 0:
                       raise ValueError(_("Could not create a key for %s") % name)

                (rc, exists) = semanage_user_exists(self.sh, k)
                if rc < 0:
                       raise ValueError(_("Could not check if SELinux user %s is defined") % name)
                if exists:
                       raise ValueError(_("SELinux user %s is already defined") % name)

                (rc, u) = semanage_user_create(self.sh)
                if rc < 0:
                       raise ValueError(_("Could not create SELinux user for %s") % name)

                rc = semanage_user_set_name(self.sh, u, name)
                if rc < 0:
                       raise ValueError(_("Could not set name for %s") % name)

                for r in roles:
                       rc = semanage_user_add_role(self.sh, u, r)
                       if rc < 0:
                              raise ValueError(_("Could not add role %s for %s") % (r, name))

                if is_mls_enabled == 1:
                       rc = semanage_user_set_mlsrange(self.sh, u, serange)
                       if rc < 0:
                              raise ValueError(_("Could not set MLS range for %s") % name)

                       rc = semanage_user_set_mlslevel(self.sh, u, selevel)
                       if rc < 0:
                              raise ValueError(_("Could not set MLS level for %s") % name)
                rc = semanage_user_set_prefix(self.sh, u, prefix)
                if rc < 0:
                       raise ValueError(_("Could not add prefix %s for %s") % (r, prefix))
                (rc, key) = semanage_user_key_extract(self.sh,u)
                if rc < 0:
                       raise ValueError(_("Could not extract key for %s") % name)

                rc = semanage_user_modify_local(self.sh, k, u)
                if rc < 0:
                       raise ValueError(_("Could not add SELinux user %s") % name)

                semanage_user_key_free(k)
                semanage_user_free(u)

	def add(self, name, roles, selevel, serange, prefix):
		seroles = " ".join(roles)
                try:
                       self.begin()
                       self.__add( name, roles, selevel, serange, prefix)
                       self.commit()
		except ValueError, error:
			mylog.log(0,"add SELinux user record", name, name, seroles, serange)
			raise error
		
		mylog.log(1,"add SELinux user record", name, name, seroles, serange)

        def __modify(self, name, roles = [], selevel = "", serange = "", prefix = ""):
		oldroles = ""
		oldserange = ""
		newroles = string.join(roles, ' ');
                if prefix == "" and len(roles) == 0  and serange == "" and selevel == "":
                       if is_mls_enabled == 1:
                              raise ValueError(_("Requires prefix, roles, level or range"))
                       else:
                              raise ValueError(_("Requires prefix or roles"))

                (rc, k) = semanage_user_key_create(self.sh, name)
                if rc < 0:
                       raise ValueError(_("Could not create a key for %s") % name)

                (rc, exists) = semanage_user_exists(self.sh, k)
                if rc < 0:
                       raise ValueError(_("Could not check if SELinux user %s is defined") % name)
                if not exists:
                       raise ValueError(_("SELinux user %s is not defined") % name)

                (rc, u) = semanage_user_query(self.sh, k)
                if rc < 0:
                       raise ValueError(_("Could not query user for %s") % name)

                oldserange = semanage_user_get_mlsrange(u)
                (rc, rlist) = semanage_user_get_roles(self.sh, u)
                if rc >= 0:
                       oldroles = string.join(rlist, ' ');
                       newroles = newroles + ' ' + oldroles;


                if serange != "":
                       semanage_user_set_mlsrange(self.sh, u, untranslate(serange))
                if selevel != "":
                       semanage_user_set_mlslevel(self.sh, u, untranslate(selevel))

                if prefix != "":
                       semanage_user_set_prefix(self.sh, u, prefix)

                if len(roles) != 0:
                       for r in rlist:
                              if r not in roles:
                                     semanage_user_del_role(u, r)
                       for r in roles:
                              if r not in rlist:
                                     semanage_user_add_role(self.sh, u, r)

                rc = semanage_user_modify_local(self.sh, k, u)
                if rc < 0:
                       raise ValueError(_("Could not modify SELinux user %s") % name)

		semanage_user_key_free(k)
		semanage_user_free(u)
		
		mylog.log(1,"modify SELinux user record", name, "", newroles, serange, "", oldroles, oldserange)


	def modify(self, name, roles = [], selevel = "", serange = "", prefix = ""):
		try:
                        self.begin()
                        self.__modify(name, roles, selevel, serange, prefix)
                        self.commit()

		except ValueError, error:
			mylog.log(0,"modify SELinux user record", name, "", " ".join(roles), serange, "", "", "")
			raise error

	def __delete(self, name):
               (rc, k) = semanage_user_key_create(self.sh, name)
               if rc < 0:
                      raise ValueError(_("Could not create a key for %s") % name)
			
               (rc, exists) = semanage_user_exists(self.sh, k)
               if rc < 0:
                      raise ValueError(_("Could not check if SELinux user %s is defined") % name)		
               if not exists:
                      raise ValueError(_("SELinux user %s is not defined") % name)

               (rc, exists) = semanage_user_exists_local(self.sh, k)
               if rc < 0:
                      raise ValueError(_("Could not check if SELinux user %s is defined") % name)
               if not exists:
                      raise ValueError(_("SELinux user %s is defined in policy, cannot be deleted") % name)
			
               rc = semanage_user_del_local(self.sh, k)
               if rc < 0:
                      raise ValueError(_("Could not delete SELinux user %s") % name)

               semanage_user_key_free(k)		

	def delete(self, name):
		try:
                        self.begin()
                        self.__delete(name)
                        self.commit()

		except ValueError, error:
			mylog.log(0,"delete SELinux user record", name)
			raise error
		
		mylog.log(1,"delete SELinux user record", name)

	def deleteall(self):
		(rc, ulist) = semanage_user_list_local(self.sh)
		if rc < 0:
			raise ValueError(_("Could not list login mappings"))

                self.begin()
		for u in ulist:
			self.__delete(semanage_user_get_name(u))
                self.commit()

	def get_all(self, locallist = 0):
		ddict = {}
                if locallist:
                       (rc, self.ulist) = semanage_user_list_local(self.sh)
                else:
                       (rc, self.ulist) = semanage_user_list(self.sh)
		if rc < 0:
			raise ValueError(_("Could not list SELinux users"))

		for u in self.ulist:
			name = semanage_user_get_name(u)
			(rc, rlist) = semanage_user_get_roles(self.sh, u)
			if rc < 0:
				raise ValueError(_("Could not list roles for user %s") % name)

			roles = string.join(rlist, ' ');
			ddict[semanage_user_get_name(u)] = (semanage_user_get_prefix(u), semanage_user_get_mlslevel(u), semanage_user_get_mlsrange(u), roles)

		return ddict

	def list(self, heading = 1, locallist = 0):
		ddict = self.get_all(locallist)
		keys = ddict.keys()
		keys.sort()
		if is_mls_enabled == 1:
			if heading:
				print "\n%-15s %-10s %-10s %-30s" % ("", _("Labeling"), _("MLS/"), _("MLS/"))
				print "%-15s %-10s %-10s %-30s %s\n" % (_("SELinux User"), _("Prefix"), _("MCS Level"), _("MCS Range"), _("SELinux Roles"))
			for k in keys:
				print "%-15s %-10s %-10s %-30s %s" % (k, ddict[k][0], translate(ddict[k][1]), translate(ddict[k][2]), ddict[k][3])
		else:
			if heading:
				print "%-15s %s\n" % (_("SELinux User"), _("SELinux Roles"))
			for k in keys:
				print "%-15s %s" % (k, ddict[k][3])

class portRecords(semanageRecords):
	def __init__(self, store = ""):
		semanageRecords.__init__(self, store)

	def __genkey(self, port, proto):
		if proto == "tcp":
			proto_d = SEMANAGE_PROTO_TCP
		else:
			if proto == "udp":
				proto_d = SEMANAGE_PROTO_UDP
			else:
				raise ValueError(_("Protocol udp or tcp is required"))
		if port == "":
			raise ValueError(_("Port is required"))
			
		ports = port.split("-")
		if len(ports) == 1:
			high = low = int(ports[0])
		else:
			low = int(ports[0])
			high = int(ports[1])

		if high > 65535:
			raise ValueError(_("Invalid Port"))

		(rc, k) = semanage_port_key_create(self.sh, low, high, proto_d)
		if rc < 0:
			raise ValueError(_("Could not create a key for %s/%s") % (proto, port))
		return ( k, proto_d, low, high )

	def __add(self, port, proto, serange, type):
		if is_mls_enabled == 1:
			if serange == "":
				serange = "s0"
			else:
				serange = untranslate(serange)
			
		if type == "":
			raise ValueError(_("Type is required"))

		( k, proto_d, low, high ) = self.__genkey(port, proto)			

		(rc, exists) = semanage_port_exists(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
		if exists:
			raise ValueError(_("Port %s/%s already defined") % (proto, port))

		(rc, p) = semanage_port_create(self.sh)
		if rc < 0:
			raise ValueError(_("Could not create port for %s/%s") % (proto, port))
		
		semanage_port_set_proto(p, proto_d)
		semanage_port_set_range(p, low, high)
		(rc, con) = semanage_context_create(self.sh)
		if rc < 0:
			raise ValueError(_("Could not create context for %s/%s") % (proto, port))

		rc = semanage_context_set_user(self.sh, con, "system_u")
		if rc < 0:
			raise ValueError(_("Could not set user in port context for %s/%s") % (proto, port))

		rc = semanage_context_set_role(self.sh, con, "object_r")
		if rc < 0:
			raise ValueError(_("Could not set role in port context for %s/%s") % (proto, port))

		rc = semanage_context_set_type(self.sh, con, type)
		if rc < 0:
			raise ValueError(_("Could not set type in port context for %s/%s") % (proto, port))

		if serange != "":
			rc = semanage_context_set_mls(self.sh, con, serange)
			if rc < 0:
				raise ValueError(_("Could not set mls fields in port context for %s/%s") % (proto, port))

		rc = semanage_port_set_con(self.sh, p, con)
		if rc < 0:
			raise ValueError(_("Could not set port context for %s/%s") % (proto, port))

		rc = semanage_port_modify_local(self.sh, k, p)
		if rc < 0:
			raise ValueError(_("Could not add port %s/%s") % (proto, port))
	
		semanage_context_free(con)
		semanage_port_key_free(k)
		semanage_port_free(p)

	def add(self, port, proto, serange, type):
                self.begin()
                self.__add(port, proto, serange, type)
                self.commit()

	def __modify(self, port, proto, serange, setype):
		if serange == "" and setype == "":
			if is_mls_enabled == 1:
				raise ValueError(_("Requires setype or serange"))
			else:
				raise ValueError(_("Requires setype"))

		( k, proto_d, low, high ) = self.__genkey(port, proto)

		(rc, exists) = semanage_port_exists(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
		if not exists:
			raise ValueError(_("Port %s/%s is not defined") % (proto,port))
	
		(rc, p) = semanage_port_query(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not query port %s/%s") % (proto, port))

		con = semanage_port_get_con(p)
			
		if serange != "":
			semanage_context_set_mls(self.sh, con, untranslate(serange))
		if setype != "":
			semanage_context_set_type(self.sh, con, setype)

		rc = semanage_port_modify_local(self.sh, k, p)
		if rc < 0:
			raise ValueError(_("Could not modify port %s/%s") % (proto, port))

		semanage_port_key_free(k)
		semanage_port_free(p)

	def modify(self, port, proto, serange, setype):
                self.begin()
                self.__modify(port, proto, serange, setype)
                self.commit()

	def deleteall(self):
		(rc, plist) = semanage_port_list_local(self.sh)
		if rc < 0:
			raise ValueError(_("Could not list the ports"))

                self.begin()

		for port in plist:
                       proto = semanage_port_get_proto(port)
                       proto_str = semanage_port_get_proto_str(proto)
                       low = semanage_port_get_low(port)
                       high = semanage_port_get_high(port)
                       port_str = "%s-%s" % (low, high)
                       ( k, proto_d, low, high ) = self.__genkey(port_str , proto_str)
                       if rc < 0:
                              raise ValueError(_("Could not create a key for %s") % port_str)

                       rc = semanage_port_del_local(self.sh, k)
                       if rc < 0:
                              raise ValueError(_("Could not delete the port %s") % port_str)
                       semanage_port_key_free(k)
	
                self.commit()

	def __delete(self, port, proto):
		( k, proto_d, low, high ) = self.__genkey(port, proto)
		(rc, exists) = semanage_port_exists(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
		if not exists:
			raise ValueError(_("Port %s/%s is not defined") % (proto, port))
		
		(rc, exists) = semanage_port_exists_local(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
		if not exists:
			raise ValueError(_("Port %s/%s is defined in policy, cannot be deleted") % (proto, port))

		rc = semanage_port_del_local(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not delete port %s/%s") % (proto, port))

		semanage_port_key_free(k)

	def delete(self, port, proto):
                self.begin()
                self.__delete(port, proto)
                self.commit()

	def get_all(self, locallist = 0):
		ddict = {}
                if locallist:
                       (rc, self.plist) = semanage_port_list_local(self.sh)
                else:
                       (rc, self.plist) = semanage_port_list(self.sh)
		if rc < 0:
			raise ValueError(_("Could not list ports"))

		for port in self.plist:
			con = semanage_port_get_con(port)
			ctype = semanage_context_get_type(con)
			if ctype == "reserved_port_t":
				continue
			level = semanage_context_get_mls(con)
			proto = semanage_port_get_proto(port)
			proto_str = semanage_port_get_proto_str(proto)
			low = semanage_port_get_low(port)
			high = semanage_port_get_high(port)
			ddict[(low, high, proto_str)] = (ctype, level)
		return ddict

	def get_all_by_type(self, locallist = 0):
		ddict = {}
                if locallist:
                       (rc, self.plist) = semanage_port_list_local(self.sh)
                else:
                       (rc, self.plist) = semanage_port_list(self.sh)
		if rc < 0:
			raise ValueError(_("Could not list ports"))

		for port in self.plist:
			con = semanage_port_get_con(port)
			ctype = semanage_context_get_type(con)
			if ctype == "reserved_port_t":
				continue
			proto = semanage_port_get_proto(port)
			proto_str = semanage_port_get_proto_str(proto)
			low = semanage_port_get_low(port)
			high = semanage_port_get_high(port)
			if (ctype, proto_str) not in ddict.keys():
				ddict[(ctype,proto_str)] = []
			if low == high:
				ddict[(ctype,proto_str)].append("%d" % low)
			else:
				ddict[(ctype,proto_str)].append("%d-%d" % (low, high))
		return ddict

	def list(self, heading = 1, locallist = 0):
		if heading:
			print "%-30s %-8s %s\n" % (_("SELinux Port Type"), _("Proto"), _("Port Number"))
		ddict = self.get_all_by_type(locallist)
		keys = ddict.keys()
		keys.sort()
		for i in keys:
			rec = "%-30s %-8s " % i
			rec += "%s" % ddict[i][0]
			for p in ddict[i][1:]:
				rec += ", %s" % p
			print rec

class nodeRecords(semanageRecords):
       def __init__(self, store = ""):
               semanageRecords.__init__(self,store)

       def __add(self, addr, mask, proto, serange, ctype):
               if addr == "":
                       raise ValueError(_("Node Address is required"))

               if mask == "":
                       raise ValueError(_("Node Netmask is required"))

	       if proto == "ipv4":
                       proto = 0
               elif proto == "ipv6":
                       proto = 1
               else:
                      raise ValueError(_("Unknown or missing protocol"))


               if is_mls_enabled == 1:
                       if serange == "":
                               serange = "s0"
                       else:
                               serange = untranslate(serange)

               if ctype == "":
                       raise ValueError(_("SELinux Type is required"))

               (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
               if rc < 0:
                       raise ValueError(_("Could not create key for %s") % addr)
               if rc < 0:
                       raise ValueError(_("Could not check if addr %s is defined") % addr)

               (rc, exists) = semanage_node_exists(self.sh, k)
               if exists:
                       raise ValueError(_("Addr %s already defined") % addr)

               (rc, node) = semanage_node_create(self.sh)
               if rc < 0:
                       raise ValueError(_("Could not create addr for %s") % addr)

               rc = semanage_node_set_addr(self.sh, node, proto, addr)
               (rc, con) = semanage_context_create(self.sh)
               if rc < 0:
                       raise ValueError(_("Could not create context for %s") % addr)

               rc = semanage_node_set_mask(self.sh, node, proto, mask)
               if rc < 0:
                       raise ValueError(_("Could not set mask for %s") % addr)


               rc = semanage_context_set_user(self.sh, con, "system_u")
               if rc < 0:
                       raise ValueError(_("Could not set user in addr context for %s") % addr)

               rc = semanage_context_set_role(self.sh, con, "object_r")
               if rc < 0:
                       raise ValueError(_("Could not set role in addr context for %s") % addr)

               rc = semanage_context_set_type(self.sh, con, ctype)
               if rc < 0:
                       raise ValueError(_("Could not set type in addr context for %s") % addr)

               if serange != "":
                       rc = semanage_context_set_mls(self.sh, con, serange)
                       if rc < 0:
                               raise ValueError(_("Could not set mls fields in addr context for %s") % addr)

               rc = semanage_node_set_con(self.sh, node, con)
               if rc < 0:
                       raise ValueError(_("Could not set addr context for %s") % addr)

               rc = semanage_node_modify_local(self.sh, k, node)
               if rc < 0:
                       raise ValueError(_("Could not add addr %s") % addr)

               semanage_context_free(con)
               semanage_node_key_free(k)
               semanage_node_free(node)

       def add(self, addr, mask, proto, serange, ctype):
                self.begin()
                self.__add(addr, mask, proto, serange, ctype)
                self.commit()

       def __modify(self, addr, mask, proto, serange, setype):
               if addr == "":
                       raise ValueError(_("Node Address is required"))

               if mask == "":
                       raise ValueError(_("Node Netmask is required"))
               if proto == "ipv4":
                       proto = 0
               elif proto == "ipv6":
                       proto = 1
	       else:
		      raise ValueError(_("Unknown or missing protocol"))


               if serange == "" and setype == "":
                       raise ValueError(_("Requires setype or serange"))

               (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
               if rc < 0:
                       raise ValueError(_("Could not create key for %s") % addr)

               (rc, exists) = semanage_node_exists(self.sh, k)
               if rc < 0:
                       raise ValueError(_("Could not check if addr %s is defined") % addr)
               if not exists:
                       raise ValueError(_("Addr %s is not defined") % addr)

               (rc, node) = semanage_node_query(self.sh, k)
               if rc < 0:
                       raise ValueError(_("Could not query addr %s") % addr)

               con = semanage_node_get_con(node)

               if serange != "":
                       semanage_context_set_mls(self.sh, con, untranslate(serange))
               if setype != "":
                       semanage_context_set_type(self.sh, con, setype)

               rc = semanage_node_modify_local(self.sh, k, node)
               if rc < 0:
                       raise ValueError(_("Could not modify addr %s") % addr)

               semanage_node_key_free(k)
               semanage_node_free(node)

       def modify(self, addr, mask, proto, serange, setype):
                self.begin()
                self.__modify(addr, mask, proto, serange, setype)
                self.commit()

       def __delete(self, addr, mask, proto):
               if addr == "":
                       raise ValueError(_("Node Address is required"))

               if mask == "":
                       raise ValueError(_("Node Netmask is required"))

	       if proto == "ipv4":
                       proto = 0
               elif proto == "ipv6":
                       proto = 1
               else:
                      raise ValueError(_("Unknown or missing protocol"))

               (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
               if rc < 0:
                       raise ValueError(_("Could not create key for %s") % addr)

               (rc, exists) = semanage_node_exists(self.sh, k)
               if rc < 0:
                       raise ValueError(_("Could not check if addr %s is defined") % addr)
               if not exists:
                       raise ValueError(_("Addr %s is not defined") % addr)

               (rc, exists) = semanage_node_exists_local(self.sh, k)
               if rc < 0:
                       raise ValueError(_("Could not check if addr %s is defined") % addr)
               if not exists:
                       raise ValueError(_("Addr %s is defined in policy, cannot be deleted") % addr)

               rc = semanage_node_del_local(self.sh, k)
               if rc < 0:
                       raise ValueError(_("Could not delete addr %s") % addr)

               semanage_node_key_free(k)

       def delete(self, addr, mask, proto):
              self.begin()
              self.__delete(addr, mask, proto)
              self.commit()
		
       def deleteall(self):
              (rc, nlist) = semanage_node_list_local(self.sh)
              if rc < 0:
                     raise ValueError(_("Could not deleteall node mappings"))

              self.begin()
              for node in nlist:
                     self.__delete(semanage_node_get_addr(self.sh, node)[1], semanage_node_get_mask(self.sh, node)[1], self.protocol[semanage_node_get_proto(node)])
              self.commit()

       def get_all(self, locallist = 0):
               ddict = {}
	       if locallist :
			(rc, self.ilist) = semanage_node_list_local(self.sh)
	       else:
	                (rc, self.ilist) = semanage_node_list(self.sh)
               if rc < 0:
                       raise ValueError(_("Could not list addrs"))

               for node in self.ilist:
                       con = semanage_node_get_con(node)
                       addr = semanage_node_get_addr(self.sh, node)
                       mask = semanage_node_get_mask(self.sh, node)
                       proto = semanage_node_get_proto(node)
		       if proto == 0:
				proto = "ipv4"
		       elif proto == 1:
				proto = "ipv6"
                       ddict[(addr[1], mask[1], proto)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))

               return ddict

       def list(self, heading = 1, locallist = 0):
               if heading:
                       print "%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context")
               ddict = self.get_all(locallist)
               keys = ddict.keys()
               keys.sort()
               if is_mls_enabled:
			for k in keys:
				val = ''
				for fields in k:
					val = val + '\t' + str(fields)
                                print "%-18s %-18s %-5s %s:%s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2], translate(ddict[k][3], False))
               else:
                       for k in keys:
                               print "%-18s %-18s %-5s %s:%s:%s " % (k[0],k[1],k[2],ddict[k][0], ddict[k][1],ddict[k][2])


class interfaceRecords(semanageRecords):
	def __init__(self, store = ""):
		semanageRecords.__init__(self, store)

	def __add(self, interface, serange, ctype):
		if is_mls_enabled == 1:
			if serange == "":
				serange = "s0"
			else:
				serange = untranslate(serange)
			
		if ctype == "":
			raise ValueError(_("SELinux Type is required"))

		(rc, k) = semanage_iface_key_create(self.sh, interface)
		if rc < 0:
			raise ValueError(_("Could not create key for %s") % interface)

		(rc, exists) = semanage_iface_exists(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if interface %s is defined") % interface)
		if exists:
			raise ValueError(_("Interface %s already defined") % interface)

		(rc, iface) = semanage_iface_create(self.sh)
		if rc < 0:
			raise ValueError(_("Could not create interface for %s") % interface)
		
		rc = semanage_iface_set_name(self.sh, iface, interface)
		(rc, con) = semanage_context_create(self.sh)
		if rc < 0:
			raise ValueError(_("Could not create context for %s") % interface)

		rc = semanage_context_set_user(self.sh, con, "system_u")
		if rc < 0:
			raise ValueError(_("Could not set user in interface context for %s") % interface)

		rc = semanage_context_set_role(self.sh, con, "object_r")
		if rc < 0:
			raise ValueError(_("Could not set role in interface context for %s") % interface)

		rc = semanage_context_set_type(self.sh, con, ctype)
		if rc < 0:
			raise ValueError(_("Could not set type in interface context for %s") % interface)

		if serange != "":
			rc = semanage_context_set_mls(self.sh, con, serange)
			if rc < 0:
				raise ValueError(_("Could not set mls fields in interface context for %s") % interface)

		rc = semanage_iface_set_ifcon(self.sh, iface, con)
		if rc < 0:
			raise ValueError(_("Could not set interface context for %s") % interface)

		rc = semanage_iface_set_msgcon(self.sh, iface, con)
		if rc < 0:
			raise ValueError(_("Could not set message context for %s") % interface)

		rc = semanage_iface_modify_local(self.sh, k, iface)
		if rc < 0:
			raise ValueError(_("Could not add interface %s") % interface)

		semanage_context_free(con)
		semanage_iface_key_free(k)
		semanage_iface_free(iface)

	def add(self, interface, serange, ctype):
                self.begin()
                self.__add(interface, serange, ctype)
                self.commit()

	def __modify(self, interface, serange, setype):
		if serange == "" and setype == "":
			raise ValueError(_("Requires setype or serange"))

		(rc, k) = semanage_iface_key_create(self.sh, interface)
		if rc < 0:
			raise ValueError(_("Could not create key for %s") % interface)

		(rc, exists) = semanage_iface_exists(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if interface %s is defined") % interface)
		if not exists:
			raise ValueError(_("Interface %s is not defined") % interface)
	
		(rc, iface) = semanage_iface_query(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not query interface %s") % interface)

		con = semanage_iface_get_ifcon(iface)
			
		if serange != "":
			semanage_context_set_mls(self.sh, con, untranslate(serange))
		if setype != "":
			semanage_context_set_type(self.sh, con, setype)

		rc = semanage_iface_modify_local(self.sh, k, iface)
		if rc < 0:
			raise ValueError(_("Could not modify interface %s") % interface)
		
		semanage_iface_key_free(k)
		semanage_iface_free(iface)

	def modify(self, interface, serange, setype):
                self.begin()
                self.__modify(interface, serange, setype)
                self.commit()

	def __delete(self, interface):
		(rc, k) = semanage_iface_key_create(self.sh, interface)
		if rc < 0:
			raise ValueError(_("Could not create key for %s") % interface)

		(rc, exists) = semanage_iface_exists(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if interface %s is defined") % interface)
		if not exists:
			raise ValueError(_("Interface %s is not defined") % interface)

		(rc, exists) = semanage_iface_exists_local(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if interface %s is defined") % interface)
		if not exists:
			raise ValueError(_("Interface %s is defined in policy, cannot be deleted") % interface)

		rc = semanage_iface_del_local(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not delete interface %s") % interface)

		semanage_iface_key_free(k)

	def delete(self, interface):
                self.begin()
                self.__delete(interface)
                self.commit()
		
        def deleteall(self):
		(rc, ulist) = semanage_iface_list_local(self.sh)
		if rc < 0:
			raise ValueError(_("Could not delete all interface  mappings"))

                self.begin()
		for i in ulist:
			self.__delete(semanage_iface_get_name(i))
                self.commit()

	def get_all(self, locallist = 0):
		ddict = {}
                if locallist:
                       (rc, self.ilist) = semanage_iface_list_local(self.sh)
                else:
                       (rc, self.ilist) = semanage_iface_list(self.sh)
		if rc < 0:
			raise ValueError(_("Could not list interfaces"))

		for interface in self.ilist:
			con = semanage_iface_get_ifcon(interface)
			ddict[semanage_iface_get_name(interface)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))

		return ddict
			
	def list(self, heading = 1, locallist = 0):
		if heading:
			print "%-30s %s\n" % (_("SELinux Interface"), _("Context"))
		ddict = self.get_all(locallist)
		keys = ddict.keys()
		keys.sort()
		if is_mls_enabled:
			for k in keys:
				print "%-30s %s:%s:%s:%s " % (k,ddict[k][0], ddict[k][1],ddict[k][2], translate(ddict[k][3], False))
		else:
			for k in keys:
				print "%-30s %s:%s:%s " % (k,ddict[k][0], ddict[k][1],ddict[k][2])
			
class fcontextRecords(semanageRecords):
	def __init__(self, store = ""):
		semanageRecords.__init__(self, store)

        def createcon(self, target, seuser = "system_u"):
                (rc, con) = semanage_context_create(self.sh)
                if rc < 0:
                       raise ValueError(_("Could not create context for %s") % target)
		if seuser == "":
			seuser = "system_u"

                rc = semanage_context_set_user(self.sh, con, seuser)
                if rc < 0:
                       raise ValueError(_("Could not set user in file context for %s") % target)
		
                rc = semanage_context_set_role(self.sh, con, "object_r")
                if rc < 0:
                       raise ValueError(_("Could not set role in file context for %s") % target)

		if is_mls_enabled == 1:
                       rc = semanage_context_set_mls(self.sh, con, "s0")
                       if rc < 0:
                              raise ValueError(_("Could not set mls fields in file context for %s") % target)

                return con
               
        def validate(self, target):
               if target == "" or target.find("\n") >= 0:
                      raise ValueError(_("Invalid file specification"))
                      
	def __add(self, target, type, ftype = "", serange = "", seuser = "system_u"):
                self.validate(target)

		if is_mls_enabled == 1:
                       serange = untranslate(serange)
			
		if type == "":
			raise ValueError(_("SELinux Type is required"))

		(rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
		if rc < 0:
			raise ValueError(_("Could not create key for %s") % target)

		(rc, exists) = semanage_fcontext_exists(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if file context for %s is defined") % target)

		if not exists:
                       (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
                       if rc < 0:
                              raise ValueError(_("Could not check if file context for %s is defined") % target)

                if exists:
                       raise ValueError(_("File context for %s already defined") % target)

		(rc, fcontext) = semanage_fcontext_create(self.sh)
		if rc < 0:
			raise ValueError(_("Could not create file context for %s") % target)
		
		rc = semanage_fcontext_set_expr(self.sh, fcontext, target)
                if type != "<<none>>":
                       con = self.createcon(target, seuser)

                       rc = semanage_context_set_type(self.sh, con, type)
                       if rc < 0:
                              raise ValueError(_("Could not set type in file context for %s") % target)

                       if serange != "":
                              rc = semanage_context_set_mls(self.sh, con, serange)
                              if rc < 0:
                                     raise ValueError(_("Could not set mls fields in file context for %s") % target)
                       rc = semanage_fcontext_set_con(self.sh, fcontext, con)
                       if rc < 0:
                              raise ValueError(_("Could not set file context for %s") % target)

		semanage_fcontext_set_type(fcontext, file_types[ftype])

		rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
		if rc < 0:
			raise ValueError(_("Could not add file context for %s") % target)

                if type != "<<none>>":
                       semanage_context_free(con)
		semanage_fcontext_key_free(k)
		semanage_fcontext_free(fcontext)

	def add(self, target, type, ftype = "", serange = "", seuser = "system_u"):
                self.begin()
                self.__add(target, type, ftype, serange, seuser)
                self.commit()

	def __modify(self, target, setype, ftype, serange, seuser):
		if serange == "" and setype == "" and seuser == "":
			raise ValueError(_("Requires setype, serange or seuser"))
                self.validate(target)

		(rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
		if rc < 0:
			raise ValueError(_("Could not create a key for %s") % target)

		(rc, exists) = semanage_fcontext_exists(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if file context for %s is defined") % target)
		if not exists:
                       (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
                       if not exists:
                              raise ValueError(_("File context for %s is not defined") % target)
		
		(rc, fcontext) = semanage_fcontext_query_local(self.sh, k)
		if rc < 0:
                       (rc, fcontext) = semanage_fcontext_query(self.sh, k)
                       if rc < 0:
                              raise ValueError(_("Could not query file context for %s") % target)

                if setype != "<<none>>":
                       con = semanage_fcontext_get_con(fcontext)
			
                       if con == None:
                              con = self.createcon(target)
                              
                       if serange != "":
                              semanage_context_set_mls(self.sh, con, untranslate(serange))
                       if seuser != "":
                              semanage_context_set_user(self.sh, con, seuser)
                              
                       if setype != "":
                              semanage_context_set_type(self.sh, con, setype)

                       rc = semanage_fcontext_set_con(self.sh, fcontext, con)
                       if rc < 0:
                              raise ValueError(_("Could not set file context for %s") % target)
                else:
                       rc = semanage_fcontext_set_con(self.sh, fcontext, None)
                       if rc < 0:
                              raise ValueError(_("Could not set file context for %s") % target)
                       
		rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
		if rc < 0:
			raise ValueError(_("Could not modify file context for %s") % target)

		semanage_fcontext_key_free(k)
		semanage_fcontext_free(fcontext)

	def modify(self, target, setype, ftype, serange, seuser):
                self.begin()
                self.__modify(target, setype, ftype, serange, seuser)
                self.commit()
		

	def deleteall(self):
		(rc, flist) = semanage_fcontext_list_local(self.sh)
		if rc < 0:
			raise ValueError(_("Could not list the file contexts"))

                self.begin()

		for fcontext in flist:
                       target = semanage_fcontext_get_expr(fcontext)
                       ftype = semanage_fcontext_get_type(fcontext)
                       ftype_str = semanage_fcontext_get_type_str(ftype)
                       (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype_str])
                       if rc < 0:
                              raise ValueError(_("Could not create a key for %s") % target)

                       rc = semanage_fcontext_del_local(self.sh, k)
                       if rc < 0:
                              raise ValueError(_("Could not delete the file context %s") % target)
                       semanage_fcontext_key_free(k)
	
                self.commit()

	def __delete(self, target, ftype):
		(rc,k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
		if rc < 0:
			raise ValueError(_("Could not create a key for %s") % target)

		(rc, exists) = semanage_fcontext_exists_local(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if file context for %s is defined") % target)
		if not exists:
			(rc, exists) = semanage_fcontext_exists(self.sh, k)
			if rc < 0:
				raise ValueError(_("Could not check if file context for %s is defined") % target)
			if exists:
				raise ValueError(_("File context for %s is defined in policy, cannot be deleted") % target)
			else:
				raise ValueError(_("File context for %s is not defined") % target)

		rc = semanage_fcontext_del_local(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not delete file context for %s") % target)

		semanage_fcontext_key_free(k)		

	def delete(self, target, ftype):
                self.begin()
                self.__delete( target, ftype)
                self.commit()

	def get_all(self, locallist = 0):
                if locallist:
                       (rc, self.flist) = semanage_fcontext_list_local(self.sh)
                else:
                       (rc, self.flist) = semanage_fcontext_list(self.sh)
                       if rc < 0:
                              raise ValueError(_("Could not list file contexts"))

                       (rc, fclocal) = semanage_fcontext_list_local(self.sh)
                       if rc < 0:
                              raise ValueError(_("Could not list local file contexts"))

                       self.flist += fclocal

                ddict = {}
		for fcontext in self.flist:
			expr = semanage_fcontext_get_expr(fcontext)
			ftype = semanage_fcontext_get_type(fcontext)
			ftype_str = semanage_fcontext_get_type_str(ftype)
			con = semanage_fcontext_get_con(fcontext)
			if con:
                               ddict[(expr, ftype_str)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
			else:
				ddict[(expr, ftype_str)] = con

		return ddict
			
	def list(self, heading = 1, locallist = 0 ):
		if heading:
			print "%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context"))
		fcon_dict = self.get_all(locallist)
                keys = fcon_dict.keys()
                keys.sort()
		for k in keys:
			if fcon_dict[k]:
				if is_mls_enabled:
					print "%-50s %-18s %s:%s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2], translate(fcon_dict[k][3],False))
				else:
					print "%-50s %-18s %s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1],fcon_dict[k][2])
			else:
				print "%-50s %-18s <<None>>" % (k[0], k[1])
				
class booleanRecords(semanageRecords):
	def __init__(self, store = ""):
		semanageRecords.__init__(self, store)
                self.dict = {}
                self.dict["TRUE"] = 1
                self.dict["FALSE"] = 0
                self.dict["ON"] = 1
                self.dict["OFF"] = 0
                self.dict["1"] = 1
                self.dict["0"] = 0

	def __mod(self, name, value):
                (rc, k) = semanage_bool_key_create(self.sh, name)
                if rc < 0:
                       raise ValueError(_("Could not create a key for %s") % name)
                (rc, exists) = semanage_bool_exists(self.sh, k)
                if rc < 0:
                       raise ValueError(_("Could not check if boolean %s is defined") % name)
                if not exists:
                       raise ValueError(_("Boolean %s is not defined") % name)	
                
                (rc, b) = semanage_bool_query(self.sh, k)
                if rc < 0:
                       raise ValueError(_("Could not query file context %s") % name)

                if value.upper() in self.dict:
                       semanage_bool_set_value(b, self.dict[value.upper()])
                else:
                       raise ValueError(_("You must specify one of the following values: %s") % ", ".join(self.dict.keys()) )
                
                rc = semanage_bool_set_active(self.sh, k, b)
                if rc < 0:
                       raise ValueError(_("Could not set active value of boolean %s") % name)
                rc = semanage_bool_modify_local(self.sh, k, b)
                if rc < 0:
                       raise ValueError(_("Could not modify boolean %s") % name)
		semanage_bool_key_free(k)
		semanage_bool_free(b)

	def modify(self, name, value = None, use_file = False):
                
                self.begin()

                if use_file:
                       fd = open(name)
                       for b in fd.read().split("\n"):
                              b = b.strip()
                              if len(b) == 0:
                                     continue

                              try:
                                     boolname, val = b.split("=")
                              except ValueError:
                                     raise ValueError(_("Bad format %s: Record %s" % ( name, b) ))
                              self.__mod(boolname.strip(), val.strip())
                       fd.close()
                else:
                       self.__mod(name, value)

                self.commit()
		
	def __delete(self, name):

                (rc, k) = semanage_bool_key_create(self.sh, name)
                if rc < 0:
                      raise ValueError(_("Could not create a key for %s") % name)
		(rc, exists) = semanage_bool_exists(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if boolean %s is defined") % name)
		if not exists:
			raise ValueError(_("Boolean %s is not defined") % name)
	
		(rc, exists) = semanage_bool_exists_local(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not check if boolean %s is defined") % name)
		if not exists:
			raise ValueError(_("Boolean %s is defined in policy, cannot be deleted") % name)

		rc = semanage_bool_del_local(self.sh, k)
		if rc < 0:
			raise ValueError(_("Could not delete boolean %s") % name)
	
		semanage_bool_key_free(k)

	def delete(self, name):
                self.begin()
                self.__delete(name)
                self.commit()

	def deleteall(self):
		(rc, self.blist) = semanage_bool_list_local(self.sh)
		if rc < 0:
			raise ValueError(_("Could not list booleans"))

                self.begin()

		for boolean in self.blist:
                       name = semanage_bool_get_name(boolean)
                       self.__delete(name)

                self.commit()
	
	def get_all(self, locallist = 0):
		ddict = {}
                if locallist:
                       (rc, self.blist) = semanage_bool_list_local(self.sh)
                else:
                       (rc, self.blist) = semanage_bool_list(self.sh)
		if rc < 0:
			raise ValueError(_("Could not list booleans"))

		for boolean in self.blist:
                       value = []
                       name = semanage_bool_get_name(boolean)
                       value.append(semanage_bool_get_value(boolean))
                       value.append(selinux.security_get_boolean_pending(name))
                       value.append(selinux.security_get_boolean_active(name))
                       ddict[name] = value

		return ddict
			
        def get_desc(self, boolean):
               return boolean_desc(boolean)

        def get_category(self, boolean):
               if boolean in booleans_dict:
                      return _(booleans_dict[boolean][0])
               else:
                      return _("unknown")

	def list(self, heading = True, locallist = False, use_file = False):
                on_off = (_("off"), _("on")) 
		if use_file:
                       ddict = self.get_all(locallist)
                       keys = ddict.keys()
                       for k in keys:
                              if ddict[k]:
                                     print "%s=%s" %  (k, ddict[k][2])
                       return
		if heading:
			print "%-40s %s\n" % (_("SELinux boolean"), _("Description"))
		ddict = self.get_all(locallist)
		keys = ddict.keys()
		for k in keys:
			if ddict[k]:
				print "%-30s -> %-5s %s" %  (k, on_off[ddict[k][2]], self.get_desc(k))

