* Semanage Patch
[not found] <C92C0B59.BBA5F%csellers@tresys.com>
@ 2010-12-14 13:23 ` Daniel J Walsh
0 siblings, 0 replies; 6+ messages in thread
From: Daniel J Walsh @ 2010-12-14 13:23 UTC (permalink / raw)
To: Chad Sellers, SELinux
[-- Attachment #1: Type: text/plain, Size: 649 bytes --]
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
This patch adds handling of modules.
Fixes up lots of --help and man pages to match reality
Adds disable/enable module handling
Lots of bug fixes
If you want to discuss sections we can do that. Breaking it up into
several different patches would be difficult now. But if you take the
easy stuff, We can discuss more difficult sections.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAk0Hb8EACgkQrlYvE4MpobM5qACfY+vmOtJIm7S+k88z7qNfW6EG
5+EAn2FQDnIIobmshGHUrDJAth2Ohm7j
=TBte
-----END PGP SIGNATURE-----
[-- Attachment #2: policycoreutils-semanage.patch --]
[-- Type: text/plain, Size: 51548 bytes --]
diff --git a/policycoreutils/semanage/semanage b/policycoreutils/semanage/semanage
index ffaca5b..75b53e8 100644
--- a/policycoreutils/semanage/semanage
+++ b/policycoreutils/semanage/semanage
@@ -1,4 +1,4 @@
-#! /usr/bin/python -E
+#! /usr/bin/python -Es
# Copyright (C) 2005, 2006, 2007 Red Hat
# see file 'COPYING' for use and warranty information
#
@@ -20,6 +20,7 @@
# 02111-1307 USA
#
#
+import policycoreutils.default_encoding_utf8
import sys, getopt, re
import seobject
import selinux
@@ -32,27 +33,36 @@ gettext.textdomain(PROGNAME)
try:
gettext.install(PROGNAME,
localedir="/usr/share/locale",
- unicode=False,
+ unicode=True,
codeset = 'utf-8')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
if __name__ == '__main__':
-
+ action = False
+ manageditems=[ "boolean", "login", "user", "port", "interface", "node", "fcontext"]
+ def set_action(option):
+ global action
+ if action:
+ raise ValueError(_("%s bad option") % option)
+ action = True
+
def usage(message = ""):
text = _("""
semanage [ -S store ] -i [ input_file | - ]
+semanage [ -S store ] -o [ output_file | - ]
-semanage {boolean|login|user|port|interface|node|fcontext} -{l|D} [-n]
+semanage {boolean|login|user|port|interface|module|node|fcontext} -{l|D|E} [-n]
semanage login -{a|d|m} [-sr] login_name | %groupname
semanage user -{a|d|m} [-LrRP] selinux_name
semanage port -{a|d|m} [-tr] [ -p proto ] port | port_range
semanage interface -{a|d|m} [-tr] interface_spec
+semanage module -{a|d|m} [--enable|--disable] module
semanage node -{a|d|m} [-tr] [ -p protocol ] [-M netmask] addr
-semanage fcontext -{a|d|m} [-frst] file_spec
+semanage fcontext -{a|d|m} [-efrst] file_spec
semanage boolean -{d|m} [--on|--off|-1|-0] -F boolean | boolean_file
-semanage permissive -{d|a} type
+semanage permissive -{d|a|l} type
semanage dontaudit [ on | off ]
Primary Options:
@@ -61,7 +71,9 @@ Primary Options:
-d, --delete Delete a OBJECT record NAME
-m, --modify Modify a OBJECT record NAME
-i, --input Input multiple semange commands in a transaction
+ -o, --output Output current customizations as semange commands
-l, --list List the OBJECTS
+ -E, --extract extract customizable commands
-C, --locallist List OBJECTS local customizations
-D, --deleteall Remove all OBJECTS local customizations
@@ -84,12 +96,15 @@ 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")
-s, --seuser SELinux User Name
-t, --type SELinux Type for the object
-r, --range MLS/MCS Security Range (MLS/MCS Systems only)
+ --enable Enable a module
+ --disable Disable a module
""")
raise ValueError("%s\n%s" % (text, message))
@@ -101,7 +116,7 @@ Object-specific Options (see above):
def get_options():
valid_option={}
- valid_everyone=[ '-a', '--add', '-d', '--delete', '-m', '--modify', '-l', '--list', '-h', '--help', '-n', '--noheading', '-C', '--locallist', '-D', '--deleteall', '-S', '--store' ]
+ valid_everyone=[ '-a', '--add', '-d', '--delete', '-E', '--extract', '-m', '--modify', '-l', '--list', '-h', '--help', '-n', '--noheading', '-C', '--locallist', '-D', '--deleteall', '-S', '--store' ]
valid_option["login"] = []
valid_option["login"] += valid_everyone + [ '-s', '--seuser', '-r', '--range']
valid_option["user"] = []
@@ -112,8 +127,10 @@ Object-specific Options (see above):
valid_option["interface"] += valid_everyone + [ '-t', '--type', '-r', '--range']
valid_option["node"] = []
valid_option["node"] += valid_everyone + [ '-M', '--mask', '-t', '--type', '-r', '--range', '-p', '--protocol']
+ valid_option["module"] = []
+ valid_option["module"] += valid_everyone + [ '--enable', '--disable']
valid_option["fcontext"] = []
- valid_option["fcontext"] += valid_everyone + [ '-f', '--ftype', '-s', '--seuser', '-t', '--type', '-r', '--range']
+ valid_option["fcontext"] += valid_everyone + [ '-e', '--equal', '-f', '--ftype', '-s', '--seuser', '-t', '--type', '-r', '--range']
valid_option["dontaudit"] = [ '-S', '--store' ]
valid_option["boolean"] = []
valid_option["boolean"] += valid_everyone + [ '--on', "--off", "-1", "-0", "-F", "--file"]
@@ -168,6 +185,8 @@ Object-specific Options (see above):
return ret
def process_args(argv):
+ global action
+ action = False
serange = ""
port = ""
proto = ""
@@ -184,11 +203,17 @@ Object-specific Options (see above):
modify = False
delete = False
deleteall = False
+ enable = False
+ extract = False
+ disable = False
list = False
locallist = False
use_file = False
store = ""
+ equal=""
+ if len(argv) == 0:
+ return
object = argv[0]
option_dict=get_options()
if object not in option_dict.keys():
@@ -197,10 +222,14 @@ Object-specific Options (see above):
args = argv[1:]
gopts, cmds = getopt.getopt(args,
- '01adf: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',
+ 'equal=',
+ 'enable',
+ 'extract',
+ 'disable',
'ftype=',
'file',
'help',
@@ -225,29 +254,47 @@ Object-specific Options (see above):
for o, a in gopts:
if o not in option_dict[object]:
sys.stderr.write(_("%s not valid for %s objects\n") % ( o, object) );
+
+ return
for o,a in gopts:
if o == "-a" or o == "--add":
- if modify or delete:
- raise ValueError(_("%s bad option") % o)
+ set_action(o)
add = True
if o == "-d" or o == "--delete":
- if modify or add:
- raise ValueError(_("%s bad option") % o)
+ set_action(o)
delete = True
+
if o == "-D" or o == "--deleteall":
- if modify:
- raise ValueError(_("%s bad option") % o)
+ set_action(o)
deleteall = True
+
+ if o == "-E" or o == "--extract":
+ set_action(o)
+ extract = True
if o == "-f" or o == "--ftype":
ftype=a
+ if o == "-e" or o == "--equal":
+ equal = a
+
+ if o == "--enable":
+ if disable:
+ raise ValueError(_("You can't disable and enable at the same time"))
+
+ enable = True
+
+ if o == "--disable":
+ if enable:
+ raise ValueError(_("You can't disable and enable at the same time"))
+ disable = True
+
if o == "-F" or o == "--file":
use_file = True
if o == "-h" or o == "--help":
- raise ValueError(_("%s bad option") % o)
+ raise usage()
if o == "-n" or o == "--noheading":
heading = False
@@ -256,8 +303,7 @@ Object-specific Options (see above):
locallist = True
if o == "-m"or o == "--modify":
- if delete or add:
- raise ValueError(_("%s bad option") % o)
+ set_action(o)
modify = True
if o == "-S" or o == '--store':
@@ -292,8 +338,10 @@ Object-specific Options (see above):
if o == "--on" or o == "-1":
value = "on"
+ modify = True
if o == "--off" or o == "-0":
value = "off"
+ modify = True
if object == "login":
OBJECT = seobject.loginRecords(store)
@@ -315,6 +363,11 @@ Object-specific Options (see above):
if object == "boolean":
OBJECT = seobject.booleanRecords(store)
+ if use_file:
+ modify=True
+
+ if object == "module":
+ OBJECT = seobject.moduleRecords(store)
if object == "permissive":
OBJECT = seobject.permissiveRecords(store)
@@ -330,65 +383,97 @@ Object-specific Options (see above):
OBJECT.deleteall()
return
+ if extract:
+ for i in OBJECT.customized():
+ print "%s %s" % (object, str(i))
+ return
+
if len(cmds) != 1:
- raise ValueError(_("%s bad option") % o)
+ raise ValueError(_("bad option"))
target = cmds[0]
-
if object == "dontaudit":
- OBJECT = seobject.dontauditClass(store)
- OBJECT.toggle(target)
- return
+ OBJECT = seobject.dontauditClass(store)
+ OBJECT.toggle(target)
+ return
if add:
if object == "login":
OBJECT.add(target, seuser, serange)
+ return
if object == "user":
OBJECT.add(target, roles.split(), selevel, serange, prefix)
+ return
if object == "port":
OBJECT.add(target, proto, serange, setype)
+ return
if object == "interface":
OBJECT.add(target, serange, setype)
+ return
+
+ if object == "module":
+ OBJECT.add(target)
+ return
if object == "node":
OBJECT.add(target, mask, proto, serange, setype)
+ 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":
OBJECT.add(target)
+ return
- return
-
if modify:
if object == "boolean":
OBJECT.modify(target, value, use_file)
+ return
if object == "login":
OBJECT.modify(target, seuser, serange)
+ return
if object == "user":
rlist = roles.split()
OBJECT.modify(target, rlist, selevel, serange, prefix)
+ return
+
+ if object == "module":
+ if enable:
+ OBJECT.enable(target)
+ elif disable:
+ OBJECT.disable(target)
+ else:
+ OBJECT.modify(target)
+ return
if object == "port":
OBJECT.modify(target, proto, serange, setype)
+ return
if object == "interface":
OBJECT.modify(target, serange, setype)
+ return
if object == "node":
OBJECT.modify(target, mask, proto, serange, setype)
+ return
if object == "fcontext":
- OBJECT.modify(target, setype, ftype, serange, seuser)
-
- return
-
+ if equal == "":
+ OBJECT.modify(target, setype, ftype, serange, seuser)
+ else:
+ OBJECT.modify_equal(target, equal)
+ return
if delete:
if object == "port":
OBJECT.delete(target, proto)
@@ -401,15 +486,14 @@ Object-specific Options (see above):
else:
OBJECT.delete(target)
-
return
-
- raise ValueError(_("Invalid command") % " ".join(argv))
+ raise ValueError(_("Invalid command: semanage %s") % " ".join(argv))
#
#
#
try:
+ output = None
input = None
store = ""
@@ -417,7 +501,7 @@ Object-specific Options (see above):
usage(_("Requires 2 or more arguments"))
gopts, cmds = getopt.getopt(sys.argv[1:],
- '01adf:i:lhmnp:s:FCDR:L:r:t:T:P:S:',
+ '01adf:i:lhmno:p:s:FCDR:L:r:t:T:P:S:',
['add',
'delete',
'deleteall',
@@ -431,6 +515,7 @@ Object-specific Options (see above):
'localist',
'off',
'on',
+ 'output=',
'proto=',
'seuser=',
'store=',
@@ -438,6 +523,7 @@ Object-specific Options (see above):
'level=',
'roles=',
'type=',
+ 'trans=',
'prefix='
])
for o, a in gopts:
@@ -445,6 +531,16 @@ Object-specific Options (see above):
store = a
if o == "-i" or o == '--input':
input = a
+ if o == "-o" or o == '--output':
+ output = a
+
+ if output != None:
+ if output != "-":
+ sys.stdout = open(output, 'w')
+ for i in manageditems:
+ print "%s -D" % i
+ process_args([i, "-E"])
+ sys.exit(0)
if input != None:
if input == "-":
@@ -467,3 +563,5 @@ Object-specific Options (see above):
errorExit(_("Invalid value %s") % error.args[0])
except IOError, error:
errorExit(error.args[1])
+ except OSError, error:
+ errorExit(error.args[1])
diff --git a/policycoreutils/semanage/semanage.8 b/policycoreutils/semanage/semanage.8
index 70d1a20..fb6a79b 100644
--- a/policycoreutils/semanage/semanage.8
+++ b/policycoreutils/semanage/semanage.8
@@ -1,29 +1,69 @@
-.TH "semanage" "8" "2005111103" "" ""
+.TH "semanage" "8" "20100223" "" ""
.SH "NAME"
semanage \- SELinux Policy Management tool
.SH "SYNOPSIS"
-.B semanage {boolean|login|user|port|interface|node|fcontext} \-{l|D} [\-n] [\-S store]
+Output local customizations
.br
-.B semanage boolean \-{d|m} [\-\-on|\-\-off|\-1|\-0] -F boolean | boolean_file
+.B semanage [ -S store ] -o [ output_file | - ]
+
+Input local customizations
+.br
+.B semanage [ -S store ] -i [ input_file | - ]
+
+Manage booleans. Booleans allow the administrator to modify the confinement of
+processes based on his configuration.
+.br
+.B semanage boolean [\-S store] \-{d|m|l|n|D} \-[\-on|\-off|\1|0] -F boolean | boolean_file
+
+Manage SELinux confined users (Roles and levels for an SELinux user)
+.br
+.B semanage user [\-S store] \-{a|d|m|l|n|D} [\-LrRP] selinux_name
+
+Manage login mappings between linux users and SELinux confined users.
+.br
+.B semanage login [\-S store] \-{a|d|m|l|n|D} [\-sr] login_name | %groupname
+
+Manage policy modules.
+.br
+.B semanage module [\-S store] \-{a|d|l} [-m [--enable | --disable] ] module_name
+
+Manage network port type definitions
.br
-.B semanage login \-{a|d|m} [\-sr] login_name | %groupname
+.B semanage port [\-S store] \-{a|d|m|l|n|D} [\-tr] [\-p proto] port | port_range
.br
-.B semanage user \-{a|d|m} [\-LrRP] selinux_name
+
+Manage network interface type definitions
+.br
+.B semanage interface [\-S store] \-{a|d|m|l|n|D} [\-tr] interface_spec
+
+Manage network node type definitions
.br
-.B semanage port \-{a|d|m} [\-tr] [\-p proto] port | port_range
+.B semanage node [\-S store] -{a|d|m|l|n|D} [-tr] [ -p protocol ] [-M netmask] address
.br
-.B semanage interface \-{a|d|m} [\-tr] interface_spec
+
+Manage file context mapping definitions
+.br
+.B semanage fcontext [\-S store] \-{a|d|m|l|n|D} [\-frst] file_spec
.br
-.B semanage node -{a|d|m} [-tr] [ -p protocol ] [-M netmask] address
+.B semanage fcontext [\-S store] \-{a|d|m|l|n|D} \-e replacement target
.br
-.B semanage fcontext \-{a|d|m} [\-frst] file_spec
+
+Manage processes type enforcement mode
.br
-.B semanage permissive \-{a|d} type
+.B semanage permissive [\-S store] \-{a|d|l|n|D} type
.br
-.B semanage dontaudit [ on | off ]
+
+Disable/Enable dontaudit rules in policy
+.br
+.B semanage dontaudit [\-S store] [ on | off ]
.P
+Execute multiple commands within a single transaction.
+.br
+.B semanage [\-S store] \-i command-file
+.br
+
.SH "DESCRIPTION"
semanage is used to configure certain elements of
SELinux policy without requiring modification to or recompilation
@@ -52,6 +92,22 @@ Delete a OBJECT record NAME
.I \-D, \-\-deleteall
Remove all OBJECTS local customizations
.TP
+.I \-\-disable
+Disable a policy module, requires -m option
+
+Currently modules only.
+.TP
+.I \-\-enable
+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.
+.TP
.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.
@@ -60,6 +116,7 @@ Requires a file type as shown in the mode field by ls, e.g. use -d to match only
Set multiple records from the input file. When used with the \-l \-\-list, it will output the current settings to stdout in the proper format.
Currently booleans only.
+
.TP
.I \-h, \-\-help
display this message
@@ -76,6 +133,9 @@ Default SELinux Level for SELinux use, s0 Default. (MLS/MCS Systems only)
.I \-m, \-\-modify
Modify a OBJECT record NAME
.TP
+.I \-M, \-\-mask
+Network Mask
+.TP
.I \-n, \-\-noheading
Do not print heading when listing OBJECTS.
.TP
@@ -99,26 +159,67 @@ Select and alternate SELinux store to manage
.TP
.I \-t, \-\-type
SELinux Type for the object
+.TP
+.I \-i, \-\-input
+Take a set of commands from a specified file and load them in a single
+transaction.
.SH EXAMPLE
.nf
-# View SELinux user mappings
-$ semanage user -l
-# Allow joe to login as staff_u
-$ 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(/.*)?"
-# Allow Apache to listen on port 81
-$ semanage port -a -t http_port_t -p tcp 81
-# Change apache to a permissive domain
-$ semanage permissive -a httpd_t
-# Turn off dontaudit rules
-$ semanage dontaudit off
+.B SELinux user
+List SELinux users
+# semanage user -l
+
+.B SELinux login
+Change joe to login as staff_u
+# semanage login -a -s staff_u joe
+Change the group clerks to login as user_u
+# semanage login -a -s user_u %clerks
+
+.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
+
+.B Port contexts
+Allow Apache to listen on tcp port 81
+# semanage port -a -t http_port_t -p tcp 81
+
+.B Change apache to a permissive domain
+# semanage permissive -a httpd_t
+
+.B Turn off dontaudit rules
+# semanage dontaudit off
+
+.B Managing multiple machines
+Multiple machines that need the same customizations.
+Extract customizations off first machine, copy them
+to second and import them.
+
+# semanage -o /tmp/local.selinux
+# scp /tmp/local.selinux secondmachine:/tmp
+# ssh secondmachine
+# semanage -i /tmp/local.selinux
+
+If these customizations include file context, you need to apply the
+context using restorecon.
+
.fi
.SH "AUTHOR"
-This man page was written by Daniel Walsh <dwalsh@redhat.com> and
-Russell Coker <rcoker@redhat.com>.
+This man page was written by Daniel Walsh <dwalsh@redhat.com>
+.br
+and Russell Coker <rcoker@redhat.com>.
+.br
Examples by Thomas Bleher <ThomasBleher@gmx.de>.
diff --git a/policycoreutils/semanage/seobject.py b/policycoreutils/semanage/seobject.py
index b7d257b..40e57e9 100644
--- a/policycoreutils/semanage/seobject.py
+++ b/policycoreutils/semanage/seobject.py
@@ -29,47 +29,12 @@ 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
-
-handle = None
-
-def get_handle(store):
- global handle
- global is_mls_enabled
-
- handle = semanage_handle_create()
- if not handle:
- raise ValueError(_("Could not create semanage handle"))
-
- if store != "":
- semanage_select_store(handle, store, SEMANAGE_CON_DIRECT);
-
- 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"))
+import gettext
+translation=gettext.translation(PROGNAME, localedir = "/usr/share/locale", fallback=True)
+_=translation.ugettext
- return handle
+import syslog
file_types = {}
file_types[""] = SEMANAGE_FCONTEXT_ALL;
@@ -194,45 +159,154 @@ def untranslate(trans, prepend = 1):
return trans
else:
return raw
-
+
class semanageRecords:
- def __init__(self, store):
+ transaction = False
+ handle = None
+ store = None
+
+ def __init__(self, store):
global handle
- if handle != None:
- self.sh = handle
- else:
- self.sh = get_handle(store)
- self.transaction = False
+ 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 self.transaction:
+ if semanageRecords.transaction:
raise ValueError(_("Semanage transaction already in progress"))
self.begin()
- self.transaction = True
-
+ semanageRecords.transaction = True
def begin(self):
- if self.transaction:
+ if semanageRecords.transaction:
return
rc = semanage_begin_transaction(self.sh)
if rc < 0:
raise ValueError(_("Could not start semanage transaction"))
+ def customized(self):
+ raise ValueError(_("Not yet implemented"))
+
def commit(self):
- if self.transaction:
+ if semanageRecords.transaction:
return
rc = semanage_commit(self.sh)
if rc < 0:
raise ValueError(_("Could not commit semanage transaction"))
def finish(self):
- if not self.transaction:
+ if not semanageRecords.transaction:
raise ValueError(_("Semanage transaction not in progress"))
- self.transaction = False
+ semanageRecords.transaction = False
self.commit()
+class moduleRecords(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)
+ l.append((semanage_module_get_name(mod), semanage_module_get_version(mod), semanage_module_get_enabled(mod)))
+ return l
+
+ def list(self, heading = 1, locallist = 0):
+ if heading:
+ print "\n%-25s%-10s\n" % (_("Modules Name"), _("Version"))
+ for t in self.get_all():
+ if t[2] == 0:
+ disabled = _("Disabled")
+ else:
+ disabled = ""
+ print "%-25s%-10s%s" % (t[0], t[1], disabled)
+
+ def add(self, file):
+ rc = semanage_module_install_file(self.sh, file);
+ if rc >= 0:
+ self.commit()
+
+ def disable(self, module):
+ need_commit = False
+ for m in module.split():
+ rc = semanage_module_disable(self.sh, m)
+ if rc < 0 and rc != -3:
+ raise ValueError(_("Could not disable module %s (remove failed)") % m)
+ if rc != -3:
+ need_commit = True
+ if need_commit:
+ self.commit()
+
+ def enable(self, module):
+ need_commit = False
+ for m in module.split():
+ rc = semanage_module_enable(self.sh, m)
+ if rc < 0 and rc != -3:
+ raise ValueError(_("Could not enable module %s (remove failed)") % m)
+ if rc != -3:
+ need_commit = True
+ if need_commit:
+ self.commit()
+
+ def modify(self, file):
+ rc = semanage_module_update_file(self.sh, file);
+ if rc >= 0:
+ self.commit()
+
+ def delete(self, module):
+ for m in module.split():
+ rc = semanage_module_remove(self.sh, m)
+ if rc < 0 and rc != -2:
+ raise ValueError(_("Could not remove module %s (remove failed)") % m)
+
+ self.commit()
+
+ def deleteall(self):
+ l = self.get_all()
+ if len(l) > 0:
+ all = " ".join(l[0])
+ self.delete(all)
+
class dontauditClass(semanageRecords):
def __init__(self, store):
semanageRecords.__init__(self, store)
@@ -259,14 +333,23 @@ class permissiveRecords(semanageRecords):
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
+ import setools
+ all = map(lambda y: y["name"], filter(lambda x: x["permissive"], setools.seinfo(setools.TYPE)))
+ if heading:
+ print "\n%-25s\n" % (_("Builtin Permissive Types"))
+ customized = self.get_all()
+ for t in all:
+ if t not in customized:
+ print t
+ if heading:
+ print "\n%-25s\n" % (_("Customized Permissive Types"))
+ for t in customized:
+ print t
def add(self, type):
import glob
@@ -343,7 +426,9 @@ class loginRecords(semanageRecords):
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)
+ semanage_seuser_key_free(k)
+ return self.__modify(name, sename, serange)
+
if name[0] == '%':
try:
grp.getgrnam(name[1:])
@@ -475,6 +560,16 @@ class loginRecords(semanageRecords):
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:
@@ -489,6 +584,15 @@ class loginRecords(semanageRecords):
ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u))
return ddict
+ def customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k))
+ return l
+
def list(self,heading = 1, locallist = 0):
ddict = self.get_all(locallist)
keys = ddict.keys()
@@ -531,7 +635,8 @@ class seluserRecords(semanageRecords):
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)
+ semanage_user_key_free(k)
+ return self.__modify(name, roles, selevel, serange, prefix)
(rc, u) = semanage_user_create(self.sh)
if rc < 0:
@@ -682,6 +787,16 @@ class seluserRecords(semanageRecords):
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:
@@ -702,6 +817,15 @@ class seluserRecords(semanageRecords):
return ddict
+ def customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ l.append("-a -r %s -R '%s' %s" % (ddict[k][2], ddict[k][3], k))
+ return l
+
def list(self, heading = 1, locallist = 0):
ddict = self.get_all(locallist)
keys = ddict.keys()
@@ -740,12 +864,16 @@ class portRecords(semanageRecords):
low = int(ports[0])
high = int(ports[1])
+ if high > 65536:
+ 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"
@@ -808,6 +936,7 @@ class portRecords(semanageRecords):
self.commit()
def __modify(self, port, proto, serange, setype):
+
if serange == "" and setype == "":
if is_mls_enabled == 1:
raise ValueError(_("Requires setype or serange"))
@@ -942,6 +1071,18 @@ class portRecords(semanageRecords):
ddict[(ctype,proto_str)].append("%d-%d" % (low, high))
return ddict
+ def customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ if k[0] == k[1]:
+ l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], k[0]))
+ else:
+ l.append("-a -t %s -p %s %s-%s" % (ddict[k][0], k[2], k[0], k[1]))
+ return l
+
def list(self, heading = 1, locallist = 0):
if heading:
print "%-30s %-8s %s\n" % (_("SELinux Port Type"), _("Proto"), _("Port Number"))
@@ -958,7 +1099,8 @@ class portRecords(semanageRecords):
class nodeRecords(semanageRecords):
def __init__(self, store = ""):
semanageRecords.__init__(self,store)
-
+ self.protocol = ["ipv4", "ipv6"]
+
def __add(self, addr, mask, proto, serange, ctype):
if addr == "":
raise ValueError(_("Node Address is required"))
@@ -966,14 +1108,11 @@ class nodeRecords(semanageRecords):
if mask == "":
raise ValueError(_("Node Netmask is required"))
- if proto == "ipv4":
- proto = 0
- elif proto == "ipv6":
- proto = 1
- else:
+ try:
+ proto = self.protocol.index(proto)
+ except:
raise ValueError(_("Unknown or missing protocol"))
-
if is_mls_enabled == 1:
if serange == "":
serange = "s0"
@@ -991,11 +1130,13 @@ class nodeRecords(semanageRecords):
(rc, exists) = semanage_node_exists(self.sh, k)
if exists:
- raise ValueError(_("Addr %s already defined") % addr)
+ semanage_node_key_free(k)
+ return self.__modify(addr, mask, self.protocol[proto], serange, ctype)
(rc, node) = semanage_node_create(self.sh)
if rc < 0:
raise ValueError(_("Could not create addr for %s") % addr)
+ semanage_node_set_proto(node, proto)
rc = semanage_node_set_addr(self.sh, node, proto, addr)
(rc, con) = semanage_context_create(self.sh)
@@ -1005,8 +1146,7 @@ class nodeRecords(semanageRecords):
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)
@@ -1047,13 +1187,10 @@ class nodeRecords(semanageRecords):
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"))
-
+ try:
+ proto = self.protocol.index(proto)
+ except:
+ raise ValueError(_("Unknown or missing protocol"))
if serange == "" and setype == "":
raise ValueError(_("Requires setype or serange"))
@@ -1068,12 +1205,11 @@ class nodeRecords(semanageRecords):
if not exists:
raise ValueError(_("Addr %s is not defined") % addr)
- (rc, node) = semanage_node_query(self.sh, k)
+ (rc, node) = semanage_node_query_local(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 != "":
@@ -1098,11 +1234,9 @@ class nodeRecords(semanageRecords):
if mask == "":
raise ValueError(_("Node Netmask is required"))
- if proto == "ipv4":
- proto = 0
- elif proto == "ipv6":
- proto = 1
- else:
+ try:
+ proto = self.protocol.index(proto)
+ except:
raise ValueError(_("Unknown or missing protocol"))
(rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
@@ -1132,6 +1266,16 @@ class nodeRecords(semanageRecords):
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 :
@@ -1145,15 +1289,20 @@ class nodeRecords(semanageRecords):
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"
+ proto = self.protocol[semanage_node_get_proto(node)]
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 customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2],ddict[k][2], k[0]))
+ return l
+
def list(self, heading = 1, locallist = 0):
if heading:
print "%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context")
@@ -1193,7 +1342,8 @@ class interfaceRecords(semanageRecords):
if rc < 0:
raise ValueError(_("Could not check if interface %s is defined") % interface)
if exists:
- raise ValueError(_("Interface %s already defined") % interface)
+ semanage_iface_key_free(k)
+ return self.__modify(interface, serange, ctype)
(rc, iface) = semanage_iface_create(self.sh)
if rc < 0:
@@ -1307,6 +1457,16 @@ class interfaceRecords(semanageRecords):
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:
@@ -1322,6 +1482,15 @@ class interfaceRecords(semanageRecords):
return ddict
+ def customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ l.append("-a -t %s %s" % (ddict[k][2], k))
+ return l
+
def list(self, heading = 1, locallist = 0):
if heading:
print "%-30s %s\n" % (_("SELinux Interface"), _("Context"))
@@ -1338,6 +1507,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)
@@ -1364,6 +1575,8 @@ class fcontextRecords(semanageRecords):
def validate(self, target):
if target == "" or target.find("\n") >= 0:
raise ValueError(_("Invalid file specification"))
+ if target.find(" ") != -1:
+ raise ValueError(_("File specification can not include spaces"))
def __add(self, target, type, ftype = "", serange = "", seuser = "system_u"):
self.validate(target)
@@ -1388,7 +1601,8 @@ class fcontextRecords(semanageRecords):
raise ValueError(_("Could not check if file context for %s is defined") % target)
if exists:
- raise ValueError(_("File context for %s already defined") % target)
+ semanage_fcontext_key_free(k)
+ return self.__modify(target, type, ftype, serange, seuser)
(rc, fcontext) = semanage_fcontext_create(self.sh)
if rc < 0:
@@ -1504,9 +1718,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)
@@ -1561,12 +1782,22 @@ class fcontextRecords(semanageRecords):
return ddict
+ def customized(self):
+ l = []
+ fcon_dict = self.get_all(True)
+ keys = fcon_dict.keys()
+ keys.sort()
+ for k in keys:
+ if fcon_dict[k]:
+ l.append("-a -f '%s' -t %s '%s'" % (k[1], fcon_dict[k][2], k[0]))
+ return l
+
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()
+ if len(keys) > 0 and heading:
+ print "%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context"))
for k in keys:
if fcon_dict[k]:
if is_mls_enabled:
@@ -1575,6 +1806,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 = ""):
@@ -1587,6 +1824,18 @@ class booleanRecords(semanageRecords):
self.dict["1"] = 1
self.dict["0"] = 0
+ try:
+ rc, self.current_booleans = selinux.security_get_boolean_names()
+ rc, ptype = selinux.selinux_getpolicytype()
+ except:
+ self.current_booleans = []
+ ptype = None
+
+ if self.store == None or self.store == ptype:
+ self.modify_local = True
+ else:
+ self.modify_local = False
+
def __mod(self, name, value):
(rc, k) = semanage_bool_key_create(self.sh, name)
if rc < 0:
@@ -1606,9 +1855,10 @@ class booleanRecords(semanageRecords):
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)
+ if self.modify_local and name in self.current_booleans:
+ 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)
@@ -1691,8 +1941,12 @@ class booleanRecords(semanageRecords):
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))
+ if self.modify_local and boolean in self.current_booleans:
+ value.append(selinux.security_get_boolean_pending(name))
+ value.append(selinux.security_get_boolean_active(name))
+ else:
+ value.append(value[0])
+ value.append(value[0])
ddict[name] = value
return ddict
@@ -1706,6 +1960,16 @@ class booleanRecords(semanageRecords):
else:
return _("unknown")
+ def customized(self):
+ l = []
+ ddict = self.get_all(True)
+ keys = ddict.keys()
+ keys.sort()
+ for k in keys:
+ if ddict[k]:
+ l.append("-%s %s" % (ddict[k][2], k))
+ return l
+
def list(self, heading = True, locallist = False, use_file = False):
on_off = (_("off"), _("on"))
if use_file:
[-- Attachment #3: policycoreutils-semanage.patch.sig --]
[-- Type: application/pgp-signature, Size: 72 bytes --]
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: semanage patch
2006-04-15 3:49 ` Russell Coker
@ 2006-04-15 13:05 ` Steve Grubb
0 siblings, 0 replies; 6+ messages in thread
From: Steve Grubb @ 2006-04-15 13:05 UTC (permalink / raw)
To: russell; +Cc: Stephen Smalley, SE-Linux, Daniel J Walsh
On Friday 14 April 2006 23:49, Russell Coker wrote:
> It might be worth considering splitting auditctl into two programs, one for
> adding/removing rules and another for the rest.
Auditctl is a focused application that does only one job - configure the
kernel side of the audit system. It doesn't do anything else.
-Steve
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: semanage patch
2006-04-14 17:08 ` Stephen Smalley
@ 2006-04-15 3:49 ` Russell Coker
2006-04-15 13:05 ` Steve Grubb
0 siblings, 1 reply; 6+ messages in thread
From: Russell Coker @ 2006-04-15 3:49 UTC (permalink / raw)
To: Stephen Smalley; +Cc: SE-Linux, Daniel J Walsh, Steve Grubb
On Saturday 15 April 2006 03:08, Stephen Smalley <sds@tycho.nsa.gov> wrote:
> On Fri, 2006-04-14 at 21:08 +1000, Russell Coker wrote:
> > The attached patch against the semanage utility in rawhide allows it to
> > create and modify prefixes.
>
> Thanks, merged as of policycoreutils 1.30.6. Note that adding further
> examples in the man page to the EXAMPLES section introduced by Thomas
> Bleher would be helpful.
Updating the man page is the next stage.
> > Also when testing semanage I noticed that it let me remove a SE Linux
> > user when a login still referred to it. After doing so it then wouldn't
> > let me recreate the user (with a confusing error message). But as that
> > bug didn't stop me from doing my work I haven't taken the time to fix it.
> >
> > As the complexity of the semanage utility continues to increase I think
> > that we need to split it into separate programs selogin, seuser, seport,
> > seinterface, sefcontext, and setranslation. This will make the man page
> > easier to understand and generally increase ease of use. It will also
> > allow shell command-completion to do more of the work for the sysadmin.
> > What do you think?
>
> Not clear to me whether this will ultimately be helpful to users or more
> confusing. iptables, auditctl, etc. don't split up the interface like
> this. More useful to users would likely just be a more extensive
> description in the man page and more examples there.
iptables doesn't split the interface because there are two main functions,
adding/removing rules from tables and setting table policy for built-in
tables. The latter being such a small part of iptables functionality that it
doesn't justify a separate program.
It might be worth considering splitting auditctl into two programs, one for
adding/removing rules and another for the rest.
There are other examples of the benefits and problems of the two approaches.
The best example I can think of is raidtools2 vs mdadm. With raidtools2
there was a separate program for each operation, to add a device to a
degraded array it was "raidhotadd /dev/mdX /dev/hdcX", to remove a device
from an array that was complete it was "raidsetfaulty /dev/mdX /dev/hdcX ;
raidhotremove /dev/mdX /dev/hdcX". The fact that I can still remember all
the old raidtools2 commands but can't remember any of the mdadm commands is
noteworthy.
But back to semanage, most of the classes of operations have different
parameters. The -r option to specify range is the most commonly used
parameter (used in all classes of operations apart from translation). The
next most common option is -t which is used in 3/6 of the operation classes.
I think that the great divergance of functionality between the different
operations that semanage performs is justification for separate programs.
The user and login sections could be kept in the same program because they
are tightly linked (in fact having a single command that creates both a user
and a login at the same time along with an optional Unix account would be
beneficial). But the other four are different enough that I think they
deserve separate programs.
--
http://www.coker.com.au/selinux/ My NSA Security Enhanced Linux packages
http://www.coker.com.au/bonnie++/ Bonnie++ hard drive benchmark
http://www.coker.com.au/postal/ Postal SMTP/POP benchmark
http://www.coker.com.au/~russell/ My home page
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: semanage patch
2006-04-14 11:08 semanage patch Russell Coker
@ 2006-04-14 17:08 ` Stephen Smalley
2006-04-15 3:49 ` Russell Coker
0 siblings, 1 reply; 6+ messages in thread
From: Stephen Smalley @ 2006-04-14 17:08 UTC (permalink / raw)
To: russell; +Cc: SE-Linux, Daniel J Walsh
On Fri, 2006-04-14 at 21:08 +1000, Russell Coker wrote:
> The attached patch against the semanage utility in rawhide allows it to create
> and modify prefixes.
Thanks, merged as of policycoreutils 1.30.6. Note that adding further
examples in the man page to the EXAMPLES section introduced by Thomas
Bleher would be helpful.
> Also when testing semanage I noticed that it let me remove a SE Linux user
> when a login still referred to it. After doing so it then wouldn't let me
> recreate the user (with a confusing error message). But as that bug didn't
> stop me from doing my work I haven't taken the time to fix it.
>
> As the complexity of the semanage utility continues to increase I think that
> we need to split it into separate programs selogin, seuser, seport,
> seinterface, sefcontext, and setranslation. This will make the man page
> easier to understand and generally increase ease of use. It will also allow
> shell command-completion to do more of the work for the sysadmin. What do
> you think?
Not clear to me whether this will ultimately be helpful to users or more
confusing. iptables, auditctl, etc. don't split up the interface like
this. More useful to users would likely just be a more extensive
description in the man page and more examples there.
--
Stephen Smalley
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 6+ messages in thread
* semanage patch
@ 2006-04-14 11:08 Russell Coker
2006-04-14 17:08 ` Stephen Smalley
0 siblings, 1 reply; 6+ messages in thread
From: Russell Coker @ 2006-04-14 11:08 UTC (permalink / raw)
To: SE-Linux; +Cc: Daniel J Walsh
[-- Attachment #1: Type: text/plain, Size: 1035 bytes --]
The attached patch against the semanage utility in rawhide allows it to create
and modify prefixes.
Also when testing semanage I noticed that it let me remove a SE Linux user
when a login still referred to it. After doing so it then wouldn't let me
recreate the user (with a confusing error message). But as that bug didn't
stop me from doing my work I haven't taken the time to fix it.
As the complexity of the semanage utility continues to increase I think that
we need to split it into separate programs selogin, seuser, seport,
seinterface, sefcontext, and setranslation. This will make the man page
easier to understand and generally increase ease of use. It will also allow
shell command-completion to do more of the work for the sysadmin. What do
you think?
--
http://www.coker.com.au/selinux/ My NSA Security Enhanced Linux packages
http://www.coker.com.au/bonnie++/ Bonnie++ hard drive benchmark
http://www.coker.com.au/postal/ Postal SMTP/POP benchmark
http://www.coker.com.au/~russell/ My home page
[-- Attachment #2: diff --]
[-- Type: text/x-diff, Size: 4170 bytes --]
--- seobject.py 2006-04-14 20:36:08.000000000 +1000
+++ /usr/lib/python2.4/site-packages/seobject.py 2006-04-14 20:56:04.000000000 +1000
@@ -381,7 +381,7 @@
def __init__(self):
semanageRecords.__init__(self)
- def add(self, name, roles, selevel, serange):
+ def add(self, name, roles, selevel, serange, prefix):
if is_mls_enabled == 1:
if serange == "":
serange = "s0"
@@ -427,6 +427,9 @@
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)
@@ -451,13 +454,13 @@
semanage_user_key_free(k)
semanage_user_free(u)
- def modify(self, name, roles = [], selevel = "", serange = ""):
+ def modify(self, name, roles = [], selevel = "", serange = "", prefix = ""):
try:
- if len(roles) == 0 and serange == "" and selevel == "":
+ if prefix == "" and len(roles) == 0 and serange == "" and selevel == "":
if is_mls_enabled == 1:
- raise ValueError("Requires roles, level or range")
+ raise ValueError("Requires prefix, roles, level or range")
else:
- raise ValueError("Requires roles")
+ raise ValueError("Requires prefix or roles")
(rc,k) = semanage_user_key_create(self.sh, name)
if rc < 0:
@@ -478,6 +481,9 @@
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 roles:
semanage_user_add_role(self.sh, u, r)
--- semanage 2006-04-14 20:46:23.000000000 +1000
+++ /usr/sbin/semanage 2006-04-14 20:56:56.000000000 +1000
@@ -32,7 +32,7 @@
print '\
semanage {login|user|port|interface|fcontext|translation} -l [-n] \n\
semanage login -{a|d|m} [-sr] login_name\n\
-semanage user -{a|d|m} [-LrR] selinux_name\n\
+semanage user -{a|d|m} [-LrRP] selinux_name\n\
semanage port -{a|d|m} [-tr] [ -p protocol ] port | port_range\n\
semanage interface -{a|d|m} [-tr] interface_spec\n\
semanage fcontext -{a|d|m} [-frst] file_spec\n\
@@ -60,6 +60,7 @@
-p (named pipe) \n\n\
\
-p, --proto Port protocol (tcp or udp)\n\
+ -P, --prefix Prefix for home directory labeling\n\
-L, --level Default SELinux Level (MLS/MCS Systems only)\n\
-R, --roles SELinux Roles (ex: "sysadm_r staff_r")\n\
-T, --trans SELinux Level Translation (MLS/MCS Systems only)\n\n\
@@ -83,7 +84,7 @@
valid_option["login"] = []
valid_option["login"] += valid_everyone + [ '-s', '--seuser', '-r', '--range']
valid_option["user"] = []
- valid_option["user"] += valid_everyone + [ '-L', '--level', '-r', '--range', '-R', '--roles' ]
+ valid_option["user"] += valid_everyone + [ '-L', '--level', '-r', '--range', '-R', '--roles', '-P', '--prefix' ]
valid_option["port"] = []
valid_option["port"] += valid_everyone + [ '-t', '--type', '-r', '--range', '-p', '--protocol' ]
valid_option["interface"] = []
@@ -109,6 +110,7 @@
setrans = ""
roles = ""
seuser = ""
+ prefix = ""
heading=1
add = 0
@@ -126,7 +128,7 @@
args = sys.argv[2:]
gopts, cmds = getopt.getopt(args,
- 'adf:lhmnp:s:R:L:r:t:T:',
+ 'adf:lhmnp:s:R:L:r:t:T:P:',
['add',
'delete',
'ftype=',
@@ -140,7 +142,8 @@
'level=',
'roles=',
'type=',
- 'trans='
+ 'trans=',
+ 'prefix='
])
for o, a in gopts:
if o not in option_dict[object]:
@@ -185,6 +188,9 @@
if o == "-p" or o == '--proto':
proto = a
+ if o == "-P" or o == '--prefix':
+ prefix = a
+
if o == "-R" or o == '--roles':
roles = roles + " " + a
@@ -235,7 +241,7 @@
rlist = roles.split()
if len(rlist) == 0:
raise ValueError("You must specify a role")
- OBJECT.add(target, rlist, selevel, serange)
+ OBJECT.add(target, rlist, selevel, serange, prefix)
if object == "port":
OBJECT.add(target, proto, serange, setype)
^ permalink raw reply [flat|nested] 6+ messages in thread
* semanage patch
@ 2006-01-14 11:19 Russell Coker
0 siblings, 0 replies; 6+ messages in thread
From: Russell Coker @ 2006-01-14 11:19 UTC (permalink / raw)
To: SE-Linux, Daniel Walsh
[-- Attachment #1: Type: text/plain, Size: 649 bytes --]
The attached patch fixes a bug in a check for user existence that prevented
adding a new user, allows specifying the default level for users via the -L
option, and fixes a mis-spelling of "delete" in code.
Also attached a re-written man page that uses better formatting and more
precision in the SYNOPSIS section. The changes were significant enough that
diff wouldn't do anything useful.
--
http://www.coker.com.au/selinux/ My NSA Security Enhanced Linux packages
http://www.coker.com.au/bonnie++/ Bonnie++ hard drive benchmark
http://www.coker.com.au/postal/ Postal SMTP/POP benchmark
http://www.coker.com.au/~russell/ My home page
[-- Attachment #2: diff --]
[-- Type: text/x-diff, Size: 1233 bytes --]
--- seobject.py.orig 2006-01-15 07:06:59.000000000 +1100
+++ seobject.py 2006-01-15 07:07:03.000000000 +1100
@@ -134,7 +134,7 @@
raise ValueError("Could not create a key for %s" % name)
(rc,exists) = semanage_user_exists(self.sh, k)
- if not exists:
+ if exists:
raise ValueError("SELinux user %s is already defined." % name)
(rc,u) = semanage_user_create(self.sh)
--- semanage.orig 2006-01-15 07:03:30.000000000 +1100
+++ semanage 2006-01-15 07:08:52.000000000 +1100
@@ -84,7 +84,7 @@
args = sys.argv[2:]
gopts, cmds = getopt.getopt(args,
- 'adf:lhmnp:P:s:R:r:t:v',
+ 'adf:lhmnp:P:s:R:L:r:t:v',
['add',
'delete',
'ftype=',
@@ -96,6 +96,7 @@
'proto=',
'seuser=',
'range=',
+ 'level=',
'roles=',
'type=',
'verbose'
@@ -106,7 +107,7 @@
usage()
add = 1
- if o == "-d" or o == "--delese":
+ if o == "-d" or o == "--delete":
if modify or add:
usage()
delete = 1
@@ -126,6 +127,9 @@
if o == "-r" or o == '--range':
serange = a
+ if o == "-L" or o == '--level':
+ selevel = a
+
if o == "-P" or o == '--proto':
proto = a
[-- Attachment #3: semanage.8 --]
[-- Type: application/x-troff, Size: 1299 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-12-14 13:23 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <C92C0B59.BBA5F%csellers@tresys.com>
2010-12-14 13:23 ` Semanage Patch Daniel J Walsh
2006-04-14 11:08 semanage patch Russell Coker
2006-04-14 17:08 ` Stephen Smalley
2006-04-15 3:49 ` Russell Coker
2006-04-15 13:05 ` Steve Grubb
-- strict thread matches above, loose matches on Subject: below --
2006-01-14 11:19 Russell Coker
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.