10b8af757b67ee795deef9523f1fd72ca28721e22Eric Paris#! /usr/bin/python -Es
213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# Copyright (C) 2005 Red Hat 
313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle# see file 'COPYING' for use and warranty information
413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    chcat is a script that allows you modify the Security label on a file
613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#`   Author: Daniel Walsh <dwalsh@redhat.com>
813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    This program is free software; you can redistribute it and/or
1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    modify it under the terms of the GNU General Public License as
1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    published by the Free Software Foundation; either version 2 of
1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    the License, or (at your option) any later version.
1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    This program is distributed in the hope that it will be useful,
1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    but WITHOUT ANY WARRANTY; without even the implied warranty of
1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    GNU General Public License for more details.
1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    You should have received a copy of the GNU General Public License
2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    along with this program; if not, write to the Free Software
2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#                                        02111-1307  USA
2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#
2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#  
2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimport commands, sys, os, pwd, string, getopt, selinux
2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimport seobject
2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleimport gettext
2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletry:
3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    gettext.install('policycoreutils')
3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleexcept IOError:
3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle       import __builtin__
3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle       __builtin__.__dict__['_'] = unicode
3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef errorExit(error):
3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    sys.stderr.write("%s: " % sys.argv[0])
3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    sys.stderr.write("%s\n" % error)
3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    sys.stderr.flush()
3913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    sys.exit(1)
4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef verify_users(users):
4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for u in users:
4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        try:
4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            pwd.getpwnam(u)
4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        except KeyError:
4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            error( "User %s does not exist" % u)
4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef chcat_user_add(newcat, users):
4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    errors = 0
5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    logins = seobject.loginRecords()
5113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    seusers = logins.get_all()
5213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    add_ind = 0
5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    verify_users(users)
5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for u in users:
5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if u in seusers.keys():
5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            user = seusers[u]
5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            add_ind = 1
5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            user = seusers["__default__"]
6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        serange = user[1].split("-")
6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        cats = []
6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        top = ["s0"]
6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(serange) > 1:
6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            top = serange[1].split(":")
6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if len(top) > 1:
6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                cats.append(top[1])
6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                cats = expandCats(cats)
6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for i in newcat[1:]:
7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if i not in cats:
7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                cats.append(i)
7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            
7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(cats) > 0:
7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            new_serange = "%s-%s:%s" % (serange[0], top[0], ",".join(cats))
7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            new_serange = "%s-%s" % (serange[0], top[0])
7813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            
7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if add_ind:
8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
8113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
8213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
8313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        rc = commands.getstatusoutput(cmd)
8413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if rc[0] != 0:
8513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            print rc[1]
8613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            errors += 1
8713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
8813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    return errors
8913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        
9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef chcat_add(orig, newcat, objects,login_ind):
9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if len(newcat) == 1:
9213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        raise ValueError(_("Requires at least one category"))
9313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if login_ind == 1:
9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return chcat_user_add(newcat, objects)
9613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    
9713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    errors = 0
9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    sensitivity = newcat[0]
9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    cat = newcat[1]
10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    cmd = 'chcon -l %s' % sensitivity
10113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for f in objects:
10213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        (rc, c) = selinux.getfilecon(f)
10313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        con = c.split(":")[3:]
10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        clist  =  translate(con)
10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if sensitivity != clist[0]:
10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                print(_("Can not modify sensitivity levels using '+' on %s") % f)
10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
10813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(clist) > 1:
10913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if cat in clist[1:]:
11013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                print _("%s is already in %s") % (f, orig)
11113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                continue
11213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            clist.append(cat)
11313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cats = clist[1:]
11413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cats.sort()
11513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cat_string = cats[0]
11613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            for c in cats[1:]:
11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                cat_string = "%s,%s" % (cat_string, c)
11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cat_string = cat
12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        cmd = 'chcon -l %s:%s %s' % (sensitivity, cat_string, f)
12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        rc = commands.getstatusoutput(cmd)
12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if rc[0] != 0:
12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            print rc[1]
12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            errors += 1
12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    return errors
12613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
12713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef chcat_user_remove(newcat, users):
12813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    errors = 0
12913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    logins = seobject.loginRecords()
13013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    seusers = logins.get_all()
13113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    add_ind = 0
13213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    verify_users(users)
13313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for u in users:
13413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if u in seusers.keys():
13513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            user = seusers[u]
13613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
13713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            add_ind = 1
13813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            user = seusers["__default__"]
13913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        serange = user[1].split("-")
14013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        cats = []
14113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        top = ["s0"]
14213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(serange) > 1:
14313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            top = serange[1].split(":")
14413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if len(top) > 1:
14513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                cats.append(top[1])
14613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                cats = expandCats(cats)
14713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
14813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for i in newcat[1:]:
14913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if i in cats:
15013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                cats.remove(i)
15113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
15213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(cats) > 0:
15313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            new_serange = "%s-%s:%s" % (serange[0], top[0], ",".join(cats))
15413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
15513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            new_serange = "%s-%s" % (serange[0], top[0])
15613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            
15713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if add_ind:
15813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
15913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
16013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
16113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        rc = commands.getstatusoutput(cmd)
16213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if rc[0] != 0:
16313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            print rc[1]
16413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            errors += 1
16513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    return errors
16613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        
16713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef chcat_remove(orig, newcat, objects, login_ind):
16813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if len(newcat) == 1:
16913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        raise ValueError(_("Requires at least one category"))
17013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if login_ind == 1:
17213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return chcat_user_remove(newcat, objects)
17313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    errors = 0
17513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    sensitivity = newcat[0]
17613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    cat = newcat[1]
17713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
17813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for f in objects:
17913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        (rc, c) = selinux.getfilecon(f)
18013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        con = c.split(":")[3:]
18113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        clist = translate(con)
18213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if sensitivity != clist[0]:
18313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                print(_("Can not modify sensitivity levels using '+' on %s") % f)
18413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                continue
18513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            
18613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(clist) > 1:
18713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if cat not in clist[1:]:
18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                print _("%s is not in %s") % (f, orig)
18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                continue
19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            clist.remove(cat)
19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if len(clist) > 1:
19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                cat = clist[1]
19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                for c in clist[2:]:
19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    cat = "%s,%s" % (cat, c)
19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            else:
19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                cat = ""
19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                print _("%s is not in %s") % (f, orig)
19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                continue
20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        
20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(cat) == 0: 
20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cmd = 'chcon -l %s %s' % (sensitivity, f)
20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cmd = 'chcon -l %s:%s %s' % (sensitivity,cat, f)
20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        rc = commands.getstatusoutput(cmd)
20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if rc[0] != 0:
20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            print rc[1]
20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            errors += 1
20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    return errors
21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef chcat_user_replace(newcat, users):
21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    errors = 0
21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    logins = seobject.loginRecords()
21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    seusers = logins.get_all()
21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    add_ind = 0
21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    verify_users(users)
21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for u in users:
21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if u in seusers.keys():
21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            user = seusers[u]
22013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            add_ind = 1
22213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            user = seusers["__default__"]
22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        serange = user[1].split("-")
22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        new_serange = "%s-%s:%s" % (serange[0],newcat[0], string.join(newcat[1:], ","))
22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if new_serange[-1:] == ":":
22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            new_serange = new_serange[:-1]
22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if add_ind:
22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cmd = "semanage login -a -r %s -s %s %s" % (new_serange, user[0], u)
23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cmd = "semanage login -m -r %s -s %s %s" % (new_serange, user[0], u)
23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        rc = commands.getstatusoutput(cmd)
23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if rc[0] != 0:
23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            print rc[1]
23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            errors += 1
23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    return errors
23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    
23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef chcat_replace(newcat, objects, login_ind):
23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if login_ind == 1:
24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return chcat_user_replace(newcat, objects)
24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    errors = 0
24213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if len(newcat) == 1:
24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        sensitivity = newcat[0]
24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        cmd = 'chcon -l %s ' % newcat[0]
24513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    else:
24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        sensitivity = newcat[0]
24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        cmd = 'chcon -l %s:%s' % (sensitivity, newcat[1])
24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for cat in newcat[2:]:
24913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            cmd = '%s,%s' % (cmd, cat)
25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        
25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for f in objects:
25213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        cmd = "%s %s" % (cmd, f)
25313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    rc = commands.getstatusoutput(cmd)
25513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if rc[0] != 0:
25613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        print rc[1]
25713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        errors += 1
25813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
25913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    return errors
26013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
26113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef check_replace(cats):
26213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    plus_ind = 0
26313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    replace_ind = 0
26413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for c in cats:
26513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(c) > 0 and ( c[0] == "+" or c[0] == "-" ):
26613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if replace_ind:
26713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                raise ValueError(_("Can not combine +/- with other types of categories"))
26813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            plus_ind = 1
26913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
27013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            replace_ind = 1
27113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if plus_ind:
27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                raise ValueError(_("Can not combine +/- with other types of categories"))
27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    return replace_ind
27413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef isSensitivity(sensitivity):
27613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if sensitivity[0] == "s" and sensitivity[1:].isdigit() and int(sensitivity[1:]) in range(0,16):
27713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return 1
27813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    else:
27913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return 0
28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    
28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef expandCats(cats):
28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    newcats = []
28313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for c in cats:
2845467587bcc83ad5db022fcadf251c7ab317b37b3Daniel J Walsh        for i in c.split(","):
2855467587bcc83ad5db022fcadf251c7ab317b37b3Daniel J Walsh            if i.find(".") != -1:
2865467587bcc83ad5db022fcadf251c7ab317b37b3Daniel J Walsh                j = i.split(".")
2875467587bcc83ad5db022fcadf251c7ab317b37b3Daniel J Walsh                for k in range(int(j[0][1:]), int(j[1][1:]) + 1):
2885467587bcc83ad5db022fcadf251c7ab317b37b3Daniel J Walsh                    x = ("c%d" % k)
2895467587bcc83ad5db022fcadf251c7ab317b37b3Daniel J Walsh                    if x not in newcats:
2905467587bcc83ad5db022fcadf251c7ab317b37b3Daniel J Walsh                        newcats.append(x)
2915467587bcc83ad5db022fcadf251c7ab317b37b3Daniel J Walsh            else:
29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                if i not in newcats:
29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    newcats.append(i)
2948b092bade5f4c8114841118030e2aacf25c7ce6fJoshua Brindle    if len(newcats) > 25:
2958b092bade5f4c8114841118030e2aacf25c7ce6fJoshua Brindle        return cats
29613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    return newcats
29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef translate(cats):
29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    newcat = []
30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if len(cats) == 0:
30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        newcat.append("s0")
30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        return newcat
30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for c in cats:
30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        (rc, raw) = selinux.selinux_trans_to_raw_context("a:b:c:%s" % c)
30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        rlist = raw.split(":")[3:]
30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        tlist = []
30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if isSensitivity(rlist[0]) == 0:
30813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            tlist.append("s0")
30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            for i in expandCats(rlist):
31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                tlist.append(i)
31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            tlist.append(rlist[0])
31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            for i in expandCats(rlist[1:]):
31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                tlist.append(i)
31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(newcat) == 0:
31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            newcat.append(tlist[0])
31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if newcat[0] != tlist[0]:
31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                raise ValueError(_("Can not have multiple sensitivities"))
32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for i in tlist[1:]:
32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            newcat.append(i)
32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    return newcat
32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    
32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef usage():
32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	print _("Usage %s CATEGORY File ...") % sys.argv[0]
32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	print _("Usage %s -l CATEGORY user ...") % sys.argv[0]
32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	print _("Usage %s [[+|-]CATEGORY],...]q File ...") % sys.argv[0]
32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	print _("Usage %s -l [[+|-]CATEGORY],...]q user ...") % sys.argv[0]
32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	print _("Usage %s -d File ...") % sys.argv[0]
33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	print _("Usage %s -l -d user ...") % sys.argv[0]
33113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	print _("Usage %s -L") % sys.argv[0]
33213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	print _("Usage %s -L -l user") % sys.argv[0]
33313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        print _("Use -- to end option list.  For example")
33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        print _("chcat -- -CompanyConfidential /docs/businessplan.odt")
33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        print _("chcat -l +CompanyConfidential juser")
33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle	sys.exit(1)
33713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
33813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef listcats():
33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    fd = open(selinux.selinux_translations_path())
34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for l in fd.read().split("\n"):
34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if l.startswith("#"):
34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            continue
34313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if l.find("=") != -1:
34413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            rec = l.split("=")
34513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            print "%-30s %s" % tuple(rec)
34613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    fd.close()
34713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    return 0
34813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    
34913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
35013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef listusercats(users):
35113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if len(users) == 0:
35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        users.append(os.getlogin())
35313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    verify_users(users)
35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    for u in users:
35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        cats = seobject.translate(selinux.getseuserbyname(u)[2])
35713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        cats = cats.split("-")
35813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if len(cats) > 1 and cats[1] != "s0":
35913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            print "%s: %s" % (u, cats[1])
36013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
36113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            print "%s: %s" % (u, cats[0])
36213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            
36313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledef error(msg):
36413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    print "%s: %s" % (sys.argv[0], msg)
36513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    sys.exit(1)
36613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    
36713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleif __name__ == '__main__':
36813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if selinux.is_selinux_mls_enabled() != 1:
36913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        error("Requires a mls enabled system")
37013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        
37113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if selinux.is_selinux_enabled() != 1:
37213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        error("Requires an SELinux enabled system")
37313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        
37413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    delete_ind = 0
37513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    list_ind = 0
37613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    login_ind = 0
37713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    try:
37813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        gopts, cmds = getopt.getopt(sys.argv[1:],
37913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                    'dhlL',
38013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                    ['list',
38113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                     'login',
38213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                     'help',
38313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                                     'delete'])
38413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
38513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        for o,a in gopts:
38613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if o == "-h" or o == "--help":
38713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                usage()
38813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if o == "-d" or o == "--delete":
38913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                delete_ind = 1
39013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if o == "-L" or o == "--list":
39113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                list_ind = 1
39213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if o == "-l" or o == "--login":
39313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                login_ind = 1
39413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
39513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if list_ind == 0 and len(cmds) < 1:
39613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            usage()
39713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
39813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    except getopt.error, error:
39913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        errorExit(_("Options Error %s ") % error.msg)
40013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
40113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    except ValueError, e:
40213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        usage()
40313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
40413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if delete_ind:
40513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        sys.exit(chcat_replace(["s0"], cmds, login_ind))
40613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
40713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if list_ind:
40813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if login_ind:
40913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            sys.exit(listusercats(cmds))
41013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
41113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            if len(cmds) > 0:
41213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                usage()
41313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            sys.exit(listcats())
41413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
41513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    if len(cmds) < 2:
41613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        usage()
41713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    
41813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    set_ind = 0
41913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    cats = cmds[0].split(",")
42013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    mod_ind = 0
42113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    errors = 0
42213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    objects = cmds[1:]
42313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    try:
42413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        if check_replace(cats):
42513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            errors = chcat_replace(translate(cats), objects, login_ind)
42613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        else:
42713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle            for c in cats:
42813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                l = []
42913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                l.append(c[1:])
43013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                if len(c) > 0 and c[0] == "+":
43113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    errors += chcat_add(c[1:],translate(l), objects, login_ind)
43213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    continue
43313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                if len(c) > 0 and c[0] == "-":
43413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    errors += chcat_remove(c[1:],translate(l), objects, login_ind)
43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle                    continue
43613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    except ValueError, e:
43713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle        error(e)
4380e84ca614a4a53e3b52bb7ea45422583cf334a31Daniel J Walsh    except OSError, e:
4390e84ca614a4a53e3b52bb7ea45422583cf334a31Daniel J Walsh        error(e)
44013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    
44113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    sys.exit(errors)
44213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle    
44313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
44413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle
445