Viewing file: chcat (12.91 KB) -rwxr-xr-x Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
#! /usr/bin/python -E
# Copyright (C) 2005 Red Hat
# see file 'COPYING' for use and warranty information
#
# chcat is a script that allows you modify the Security label on a file
#
#` Author: Daniel Walsh
#
# 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 commands, sys, os, pwd, string, getopt, selinux
import seobject
import gettext
try:
gettext.install('policycoreutils')
except IOError:
import __builtin__
__builtin__.__dict__['_'] = unicode
def errorExit(error):
sys.stderr.write("%s: " % sys.argv[0])
sys.stderr.write("%s\n" % error)
sys.stderr.flush()
sys.exit(1)
def verify_users(users):
for u in users:
try:
pwd.getpwnam(u)
except KeyError:
error( "User %s does not exist" % u)
def chcat_user_add(newcat, users):
errors = 0
logins = seobject.loginRecords()
seusers = logins.get_all()
add_ind = 0
verify_users(users)
for u in users:
if u in seusers.keys():
user = seusers[u]
else:
add_ind = 1
user = seusers["__default__"]
serange = user[1].split("-")
cats = []
top = ["s0"]
if len(serange) > 1:
top = serange[1].split(":")
if len(top) > 1:
cats.append(top[1])
cats = expandCats(cats)
for i in newcat[1:]:
if i not in cats:
cats.append(i)
if len(cats) > 0:
new_serange = "%s-%s:%s" % (serange[0], top[0], ",".join(cats))
else:
new_serange = "%s-%s" % (serange[0], top[0])
if add_ind:
cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
else:
cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
rc = commands.getstatusoutput(cmd)
if rc[0] != 0:
print rc[1]
errors += 1
return errors
def chcat_add(orig, newcat, objects,login_ind):
if len(newcat) == 1:
raise ValueError(_("Requires at least one category"))
if login_ind == 1:
return chcat_user_add(newcat, objects)
errors = 0
sensitivity = newcat[0]
cat = newcat[1]
cmd = 'chcon -l %s' % sensitivity
for f in objects:
(rc, c) = selinux.getfilecon(f)
con = c.split(":")[3:]
clist = translate(con)
if sensitivity != clist[0]:
print(_("Can not modify sensitivity levels using '+' on %s") % f)
if len(clist) > 1:
if cat in clist[1:]:
print _("%s is already in %s") % (f, orig)
continue
clist.append(cat)
cats = clist[1:]
cats.sort()
cat_string = cats[0]
for c in cats[1:]:
cat_string = "%s,%s" % (cat_string, c)
else:
cat_string = cat
cmd = 'chcon -l %s:%s %s' % (sensitivity, cat_string, f)
rc = commands.getstatusoutput(cmd)
if rc[0] != 0:
print rc[1]
errors += 1
return errors
def chcat_user_remove(newcat, users):
errors = 0
logins = seobject.loginRecords()
seusers = logins.get_all()
add_ind = 0
verify_users(users)
for u in users:
if u in seusers.keys():
user = seusers[u]
else:
add_ind = 1
user = seusers["__default__"]
serange = user[1].split("-")
cats = []
top = ["s0"]
if len(serange) > 1:
top = serange[1].split(":")
if len(top) > 1:
cats.append(top[1])
cats = expandCats(cats)
for i in newcat[1:]:
if i in cats:
cats.remove(i)
if len(cats) > 0:
new_serange = "%s-%s:%s" % (serange[0], top[0], ",".join(cats))
else:
new_serange = "%s-%s" % (serange[0], top[0])
if add_ind:
cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
else:
cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
rc = commands.getstatusoutput(cmd)
if rc[0] != 0:
print rc[1]
errors += 1
return errors
def chcat_remove(orig, newcat, objects, login_ind):
if len(newcat) == 1:
raise ValueError(_("Requires at least one category"))
if login_ind == 1:
return chcat_user_remove(newcat, objects)
errors = 0
sensitivity = newcat[0]
cat = newcat[1]
for f in objects:
(rc, c) = selinux.getfilecon(f)
con = c.split(":")[3:]
clist = translate(con)
if sensitivity != clist[0]:
print(_("Can not modify sensitivity levels using '+' on %s") % f)
continue
if len(clist) > 1:
if cat not in clist[1:]:
print _("%s is not in %s") % (f, orig)
continue
clist.remove(cat)
if len(clist) > 1:
cat = clist[1]
for c in clist[2:]:
cat = "%s,%s" % (cat, c)
else:
cat = ""
else:
print _("%s is not in %s") % (f, orig)
continue
if len(cat) == 0:
cmd = 'chcon -l %s %s' % (sensitivity, f)
else:
cmd = 'chcon -l %s:%s %s' % (sensitivity,cat, f)
rc = commands.getstatusoutput(cmd)
if rc[0] != 0:
print rc[1]
errors += 1
return errors
def chcat_user_replace(newcat, users):
errors = 0
logins = seobject.loginRecords()
seusers = logins.get_all()
add_ind = 0
verify_users(users)
for u in users:
if u in seusers.keys():
user = seusers[u]
else:
add_ind = 1
user = seusers["__default__"]
serange = user[1].split("-")
new_serange = "%s:%s" % (newcat[0],string.join(newcat[1:], ","))
if new_serange[-1:] == ":":
new_serange = new_serange[:-1]
if add_ind:
cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
else:
cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
rc = commands.getstatusoutput(cmd)
if rc[0] != 0:
print rc[1]
errors += 1
return errors
def chcat_replace(newcat, objects, login_ind):
if login_ind == 1:
return chcat_user_replace(newcat, objects)
errors = 0
if len(newcat) == 1:
sensitivity = newcat[0]
cmd = 'chcon -l %s ' % newcat[0]
else:
sensitivity = newcat[0]
cmd = 'chcon -l %s:%s' % (sensitivity, newcat[1])
for cat in newcat[2:]:
cmd = '%s,%s' % (cmd, cat)
for f in objects:
cmd = "%s %s" % (cmd, f)
rc = commands.getstatusoutput(cmd)
if rc[0] != 0:
print rc[1]
errors += 1
return errors
def check_replace(cats):
plus_ind = 0
replace_ind = 0
for c in cats:
if len(c) > 0 and ( c[0] == "+" or c[0] == "-" ):
if replace_ind:
raise ValueError(_("Can not combine +/- with other types of categories"))
plus_ind = 1
else:
replace_ind = 1
if plus_ind:
raise ValueError(_("Can not combine +/- with other types of categories"))
return replace_ind
def isSensitivity(sensitivity):
if sensitivity[0] == "s" and sensitivity[1].isdigit() and int(sensitivity[1]) in range(0,16):
return 1
else:
return 0
def expandCats(cats):
newcats = []
for c in cats:
for i in c.split(","):
if i.find(".") != -1:
j = i.split(".")
for k in range(int(j[0][1:]), int(j[1][1:]) + 1):
x = ("c%d" % k)
if x not in newcats:
newcats.append(x)
else:
if i not in newcats:
newcats.append(i)
if len(newcats) > 25:
return cats
return newcats
def translate(cats):
newcat = []
if len(cats) == 0:
newcat.append("s0")
return newcat
for c in cats:
(rc, raw) = selinux.selinux_trans_to_raw_context("a:b:c:%s" % c)
rlist = raw.split(":")[3:]
tlist = []
if isSensitivity(rlist[0]) == 0:
tlist.append("s0")
for i in expandCats(rlist):
tlist.append(i)
else:
tlist.append(rlist[0])
for i in expandCats(rlist[1:]):
tlist.append(i)
if len(newcat) == 0:
newcat.append(tlist[0])
else:
if newcat[0] != tlist[0]:
raise ValueError(_("Can not have multiple sensitivities"))
for i in tlist[1:]:
newcat.append(i)
return newcat
def usage():
print _("Usage %s CATEGORY File ...") % sys.argv[0]
print _("Usage %s -l CATEGORY user ...") % sys.argv[0]
print _("Usage %s [[+ bool(false)
|