policycoreutils: semanage: introduce file context equivalencies

This adds a new -e options to semanage fcontext which allows one to
specify filesystem equivalancies.  An example would be if an admin were
to run out of space and to start putting home directories in /home1.
They can use the equivalencies to specify that /home1 is labeled exactly
like /home.

Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Dan Walsh <dwalsh@redhat.com>
This commit is contained in:
Eric Paris 2011-07-19 14:21:08 -04:00
parent f78aa2f81b
commit d01c33c90e
3 changed files with 99 additions and 8 deletions

View File

@ -60,7 +60,7 @@ semanage port -{a|d|m|D|E} [-tr] [ -p proto ] port | port_range
semanage interface -{a|d|m|D|E} [-tr] interface_spec
semanage module -{a|d|m} [--enable|--disable] module
semanage node -{a|d|m|D|E} [-tr] [ -p protocol ] [-M netmask] addr
semanage fcontext -{a|d|m|D|E} [-frst] file_spec
semanage fcontext -{a|d|m|D|E} [-efrst] file_spec
semanage boolean -{d|m|D} [--on|--off|-1|-0] -F boolean | boolean_file
semanage permissive -{d|a} type
semanage dontaudit [ on | off ]
@ -96,6 +96,7 @@ Object-specific Options (see above):
-F, --file Treat target as an input file for command, change multiple settings
-p, --proto Port protocol (tcp or udp) or internet protocol version of node (ipv4 or ipv6)
-M, --mask Netmask
-e, --equal Substitue source path for dest path when labeling
-P, --prefix Prefix for home directory labeling
-L, --level Default SELinux Level (MLS/MCS Systems only)
-R, --roles SELinux Roles (ex: "sysadm_r staff_r")
@ -130,7 +131,7 @@ Object-specific Options (see above):
valid_option["module"] = []
valid_option["module"] += valid_everyone + [ '--enable', '--disable']
valid_option["fcontext"] = []
valid_option["fcontext"] += valid_everyone + valid_local + [ '-f', '--ftype', '-s', '--seuser', '-t', '--type', '-r', '--range']
valid_option["fcontext"] += valid_everyone + valid_local + [ '-e', '--equal', '-f', '--ftype', '-s', '--seuser', '-t', '--type', '-r', '--range']
valid_option["dontaudit"] = [ '-S', '--store' ]
valid_option["boolean"] = []
valid_option["boolean"] += valid_everyone + valid_local + [ '--on', "--off", "-1", "-0", "-F", "--file"]
@ -210,6 +211,7 @@ Object-specific Options (see above):
locallist = False
use_file = False
store = ""
equal = ""
if len(argv) == 0:
return
@ -222,11 +224,12 @@ Object-specific Options (see above):
try:
gopts, cmds = getopt.getopt(args,
'01adEf:i:lhmnp:s:FCDR:L:r:t:P:S:M:',
'01adEe:f:i:lhmnp:s:FCDR:L:r:t:P:S:M:',
['add',
'delete',
'deleteall',
'enable',
'equal=',
'extract',
'disable',
'ftype=',
@ -277,6 +280,9 @@ Object-specific Options (see above):
if o == "-f" or o == "--ftype":
ftype=a
if o == "-e" or o == "--equal":
equal = a
if o == "--enable":
set_action(o)
enable = True
@ -417,7 +423,10 @@ Object-specific Options (see above):
return
if object == "fcontext":
OBJECT.add(target, setype, ftype, serange, seuser)
if equal == "":
OBJECT.add(target, setype, ftype, serange, seuser)
else:
OBJECT.add_equal(target, equal)
return
if object == "permissive":
@ -460,7 +469,10 @@ Object-specific Options (see above):
return
if object == "fcontext":
OBJECT.modify(target, setype, ftype, serange, seuser)
if equal == "":
OBJECT.modify(target, setype, ftype, serange, seuser)
else:
OBJECT.modify_equal(target, equal)
return
if delete:

View File

@ -28,8 +28,12 @@ Manage policy modules.
.B semanage interface \-{a|d|m|D} [\-tr] interface_spec
.br
.B semanage node -{a|d|m|D} [-tr] [ -p protocol ] [-M netmask] address
Manage file context mapping definitions
.br
.B semanage fcontext \-{a|d|m|D} [\-frst] file_spec
.B semanage fcontext [\-S store] \-{a|d|m|l|n|D} [\-frst] file_spec
.br
.B semanage fcontext [\-S store] \-{a|d|m|l|n|D} \-e replacement target
.br
.B semanage permissive \-{a|d} type
.br
@ -74,6 +78,11 @@ Enable a disabled policy module, requires -m option
Currently modules only.
.TP
.I \-e, \-\-equal
Substitute target path with sourcepath when generating default label. This is used with
fcontext. Requires source and target path arguments. The context
labeling for the target subtree is made equivalent to that
defined for the source.
.I \-f, \-\-ftype
File Type. This is used with fcontext.
Requires a file type as shown in the mode field by ls, e.g. use -d to match only directories or -- to match only regular files.
@ -134,8 +143,23 @@ $ semanage user -l
$ semanage login -a -s staff_u joe
# Allow the group clerks to login as user_u
$ semanage login -a -s user_u %clerks
# Add file-context for everything under /web (used by restorecon)
$ semanage fcontext -a -t httpd_sys_content_t "/web(/.*)?"
.B File contexts
.i remember to run restorecon after you set the file context
Add file-context for everything under /web
# semanage fcontext -a -t httpd_sys_content_t "/web(/.*)?"
# restorecon -R -v /web
Substitute /home1 with /home when setting file context
# semanage fcontext -a -e /home /home1
# restorecon -R -v /home1
For home directories under top level directory, for example /disk6/home,
execute the following commands.
# semanage fcontext -a -t home_root_t "/disk6"
# semanage fcontext -a -e /home /disk6/home
# restorecon -R -v /disk6
# Allow Apache to listen on port 81
$ semanage port -a -t http_port_t -p tcp 81
# Change apache to a permissive domain

View File

@ -1498,6 +1498,48 @@ class interfaceRecords(semanageRecords):
class fcontextRecords(semanageRecords):
def __init__(self, store = ""):
semanageRecords.__init__(self, store)
self.equiv = {}
self.equal_ind = False
try:
fd = open(selinux.selinux_file_context_subs_path(), "r")
for i in fd.readlines():
src, dst = i.split()
self.equiv[src] = dst
fd.close()
except IOError:
pass
def commit(self):
if self.equal_ind:
subs_file = selinux.selinux_file_context_subs_path()
tmpfile = "%s.tmp" % subs_file
fd = open(tmpfile, "w")
for src in self.equiv.keys():
fd.write("%s %s\n" % (src, self.equiv[src]))
fd.close()
try:
os.chmod(tmpfile, os.stat(subs_file)[stat.ST_MODE])
except:
pass
os.rename(tmpfile,subs_file)
self.equal_ind = False
semanageRecords.commit(self)
def add_equal(self, src, dst):
self.begin()
if src in self.equiv.keys():
raise ValueError(_("Equivalence class for %s already exists") % src)
self.equiv[src] = dst
self.equal_ind = True
self.commit()
def modify_equal(self, src, dst):
self.begin()
if src not in self.equiv.keys():
raise ValueError(_("Equivalence class for %s does not exists") % src)
self.equiv[src] = dst
self.equal_ind = True
self.commit()
def createcon(self, target, seuser = "system_u"):
(rc, con) = semanage_context_create(self.sh)
@ -1666,9 +1708,16 @@ class fcontextRecords(semanageRecords):
raise ValueError(_("Could not delete the file context %s") % target)
semanage_fcontext_key_free(k)
self.equiv = {}
self.equal_ind = True
self.commit()
def __delete(self, target, ftype):
if target in self.equiv.keys():
self.equiv.pop(target)
self.equal_ind = True
return
(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)
@ -1747,6 +1796,12 @@ class fcontextRecords(semanageRecords):
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])
if len(self.equiv.keys()) > 0:
if heading:
print _("\nSELinux fcontext Equivalence \n")
for src in self.equiv.keys():
print "%s = %s" % (src, self.equiv[src])
class booleanRecords(semanageRecords):
def __init__(self, store = ""):