Dan Walsh 05c3d9
#! /usr/bin/python -Es
Dan Walsh 05c3d9
# Copyright (C) 2012 Red Hat 
Dan Walsh 05c3d9
# AUTHOR: Dan Walsh <dwalsh@redhat.com>
Dan Walsh 05c3d9
# see file 'COPYING' for use and warranty information
Dan Walsh 05c3d9
#
Dan Walsh 05c3d9
# semanage is a tool for managing SELinux configuration files
Dan Walsh 05c3d9
#
Dan Walsh 05c3d9
#    This program is free software; you can redistribute it and/or
Dan Walsh 05c3d9
#    modify it under the terms of the GNU General Public License as
Dan Walsh 05c3d9
#    published by the Free Software Foundation; either version 2 of
Dan Walsh 05c3d9
#    the License, or (at your option) any later version.
Dan Walsh 05c3d9
#
Dan Walsh 05c3d9
#    This program is distributed in the hope that it will be useful,
Dan Walsh 05c3d9
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
Dan Walsh 05c3d9
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Dan Walsh 05c3d9
#    GNU General Public License for more details.
Dan Walsh 05c3d9
#
Dan Walsh 05c3d9
#    You should have received a copy of the GNU General Public License
Dan Walsh 05c3d9
#    along with this program; if not, write to the Free Software
Dan Walsh 05c3d9
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     
Dan Walsh 05c3d9
#                                        02111-1307  USA
Dan Walsh 05c3d9
#
Dan Walsh 05c3d9
#  
Dan Walsh 05c3d9
import seobject
Dan Walsh 05c3d9
import selinux
Dan Walsh 05c3d9
import datetime
Dan Walsh 05c3d9
import setools
Dan Walsh 05c3d9
import sys
Dan Walsh 05c3d9
Miroslav Grepl 9c9358
all_attributes = map(lambda x: x['name'], setools.seinfo(setools.ATTRIBUTE))
Dan Walsh 05c3d9
entrypoints =  setools.seinfo(setools.ATTRIBUTE,"entry_type")[0]["types"]
Dan Walsh 05c3d9
alldomains =  setools.seinfo(setools.ATTRIBUTE,"domain")[0]["types"]
Dan Walsh 05c3d9
domains = []
Miroslav Grepl 9c9358
Dan Walsh 05c3d9
for d in alldomains:
Dan Walsh 05c3d9
    found = False
Dan Walsh 05c3d9
    if d[:-2] + "_exec_t" not in entrypoints:
Dan Walsh 05c3d9
        continue
Dan Walsh 05c3d9
    name = d.split("_")[0]
Dan Walsh 05c3d9
    if name in domains or name == "pam":
Dan Walsh 05c3d9
        continue
Dan Walsh 05c3d9
    domains.append(name)
Dan Walsh 05c3d9
Dan Walsh 05c3d9
domains.sort()
Dan Walsh 05c3d9
Dan Walsh 05c3d9
file_types =  setools.seinfo(setools.ATTRIBUTE,"file_type")[0]["types"]
Dan Walsh 05c3d9
file_types.sort()
Dan Walsh 05c3d9
Dan Walsh 05c3d9
port_types =  setools.seinfo(setools.ATTRIBUTE,"port_type")[0]["types"]
Dan Walsh 05c3d9
port_types.sort()
Dan Walsh 05c3d9
Dan Walsh 05c3d9
portrecs = seobject.portRecords().get_all_by_type()
Dan Walsh 05c3d9
filerecs = seobject.fcontextRecords()
Dan Walsh 05c3d9
files_dict = {}
Dan Walsh 05c3d9
fdict = filerecs.get_all()
Dan Walsh 05c3d9
for i in fdict:
Dan Walsh 05c3d9
    if fdict[i]:
Dan Walsh 05c3d9
        if fdict[i][2] in files_dict:
Dan Walsh 05c3d9
            files_dict[fdict[i][2]].append(i)
Dan Walsh 05c3d9
        else:
Dan Walsh 05c3d9
            files_dict[fdict[i][2]] = [i]
Dan Walsh 05c3d9
boolrecs = seobject.booleanRecords()
Dan Walsh 05c3d9
bools = seobject.booleans_dict.keys()
Dan Walsh 05c3d9
Dan Walsh 05c3d9
man = {}
Dan Walsh 05c3d9
date = datetime.datetime.now().strftime("%d %b %Y")
Dan Walsh 05c3d9
def prettyprint(f,trim):
Dan Walsh 05c3d9
    return " ".join(f[:-len(trim)].split("_"))
Dan Walsh 05c3d9
Dan Walsh 05c3d9
class ManPage:
Dan Walsh 05c3d9
    def __init__(self, domainname, path="/tmp"):
Dan Walsh 05c3d9
        self.domainname = domainname
Dan Walsh 05c3d9
        if self.domainname[-1]=='d':
Dan Walsh 05c3d9
            self.short_name = self.domainname[:-1]
Dan Walsh 05c3d9
        else:
Dan Walsh 05c3d9
            self.short_name = domainname
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        self.anon_list = []
Dan Walsh 05c3d9
        self.fd = open("%s/%s_selinux.8" % (path, domainname), 'w')
Dan Walsh 05c3d9
Miroslav Grepl 9c9358
        self.attributes = {}
Miroslav Grepl 9c9358
        self.ptypes = []
Miroslav Grepl 9c9358
        self.get_ptypes()
Miroslav Grepl 9c9358
Miroslav Grepl 9c9358
        for domain_type in self.ptypes:
Miroslav Grepl 9c9358
            self.attributes[domain_type] = setools.seinfo(setools.TYPE,("%s") % domain_type)[0]["attributes"]
Miroslav Grepl 9c9358
Dan Walsh 05c3d9
        self.header()
Dan Walsh 05c3d9
        self.booleans()
Miroslav Grepl 9c9358
        self.nsswitch_domain()
Dan Walsh 05c3d9
        self.public_content()
Dan Walsh 05c3d9
        self.file_context()
Dan Walsh 05c3d9
        self.port_types()
Dan Walsh 05c3d9
        self.process_types()
Dan Walsh 05c3d9
        self.footer()
Dan Walsh 05c3d9
        self.fd.close()
Dan Walsh 05c3d9
Miroslav Grepl 9c9358
    def get_ptypes(self):
Miroslav Grepl 9c9358
        for f in alldomains:
Miroslav Grepl 9c9358
            if f.startswith(self.short_name):
Miroslav Grepl 9c9358
                self.ptypes.append(f)
Miroslav Grepl 9c9358
Dan Walsh 05c3d9
    def header(self):
Dan Walsh 05c3d9
        self.fd.write('.TH  "%(domainname)s_selinux"  "8"  "%(domainname)s" "dwalsh@redhat.com" "%(domainname)s SELinux Policy documentation"'
Dan Walsh 05c3d9
                 % {'domainname':self.domainname})
Dan Walsh 05c3d9
        self.fd.write(r"""
Dan Walsh 05c3d9
.SH "NAME"
Dan Walsh 05c3d9
%(domainname)s_selinux \- Security Enhanced Linux Policy for the %(domainname)s processes
Dan Walsh 05c3d9
.SH "DESCRIPTION"
Dan Walsh 05c3d9
Dan Walsh 05c3d9
Security-Enhanced Linux secures the %(domainname)s processes via flexible mandatory access
Dan Walsh 05c3d9
control.  
Dan Walsh 05c3d9
""" % {'domainname':self.domainname})
Dan Walsh 05c3d9
Dan Walsh 05c3d9
Dan Walsh 05c3d9
    def explain(self, f):
Dan Walsh 05c3d9
        if f.endswith("_var_run_t"):
Dan Walsh 05c3d9
            return "store the %s files under the /run directory." % prettyprint(f, "_var_run_t")
Dan Walsh 05c3d9
        if f.endswith("_pid_t"):
Dan Walsh 05c3d9
            return "store the %s files under the /run directory." % prettyprint(f, "_pid_t")
Dan Walsh 05c3d9
        if f.endswith("_var_lib_t"):
Dan Walsh 05c3d9
            return "store the %s files under the /var/lib directory."  % prettyprint(f, "_var_lib_t")
Dan Walsh 05c3d9
        if f.endswith("_var_t"):
Dan Walsh 05c3d9
            return "store the %s files under the /var directory."  % prettyprint(f, "_var_lib_t")
Dan Walsh 05c3d9
        if f.endswith("_var_spool_t"):
Dan Walsh 05c3d9
            return "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
Dan Walsh 05c3d9
        if f.endswith("_spool_t"):
Dan Walsh 05c3d9
            return "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t")
Dan Walsh 05c3d9
        if f.endswith("_cache_t") or f.endswith("_var_cache_t"):
Dan Walsh 05c3d9
            return "store the files under the /var/cache directory."
Dan Walsh 05c3d9
        if f.endswith("_keytab_t"):
Dan Walsh 05c3d9
            return "treat the files as kerberos keytab files."
Dan Walsh 05c3d9
        if f.endswith("_lock_t"):
Dan Walsh 05c3d9
            return "treat the files as %s lock data, stored under the /var/lock directory" % prettyprint(f,"_lock_t")
Dan Walsh 05c3d9
        if f.endswith("_log_t"):
Dan Walsh 05c3d9
            return "treat the data as %s log data, usually stored under the /var/log directory." % prettyprint(f,"_log_t")
Dan Walsh 05c3d9
        if f.endswith("_config_t"):
Dan Walsh 05c3d9
            return "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_config_t")
Dan Walsh 05c3d9
        if f.endswith("_conf_t"):
Dan Walsh 05c3d9
            return "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_conf_t")
Dan Walsh 05c3d9
        if f.endswith("_exec_t"):
Dan Walsh 05c3d9
            return "transition an executable to the %s_t domain." % f[:-len("_exec_t")]
Dan Walsh 05c3d9
        if f.endswith("_cgi_content_t"):
Dan Walsh 05c3d9
            return "treat the files as %s cgi content." % prettyprint(f, "_cgi_content_t")
Dan Walsh 05c3d9
        if f.endswith("_rw_content_t"):
Dan Walsh 05c3d9
            return "treat the files as %s read/write content." % prettyprint(f,"_rw_content_t")
Dan Walsh 05c3d9
        if f.endswith("_rw_t"):
Dan Walsh 05c3d9
            return "treat the files as %s read/write content." % prettyprint(f,"_rw_t")
Dan Walsh 05c3d9
        if f.endswith("_write_t"):
Dan Walsh 05c3d9
            return "treat the files as %s read/write content." % prettyprint(f,"_write_t")
Dan Walsh 05c3d9
        if f.endswith("_db_t"):
Dan Walsh 05c3d9
            return "treat the files as %s database content." % prettyprint(f,"_db_t")
Dan Walsh 05c3d9
        if f.endswith("_ra_content_t"):
Dan Walsh 05c3d9
            return "treat the files as %s read/append content." % prettyprint(f,"_ra_conten_t")
Dan Walsh 05c3d9
        if f.endswith("_cert_t"):
Dan Walsh 05c3d9
            return "treat the files as %s certificate data." % prettyprint(f,"_cert_t")
Dan Walsh 05c3d9
        if f.endswith("_key_t"):
Dan Walsh 05c3d9
            return "treat the files as %s key data." % prettyprint(f,"_key_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if f.endswith("_secret_t"):
Dan Walsh 05c3d9
            return "treat the files as %s secret data." % prettyprint(f,"_key_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if f.endswith("_ra_t"):
Dan Walsh 05c3d9
            return "treat the files as %s read/append content." % prettyprint(f,"_ra_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if f.endswith("_ro_t"):
Dan Walsh 05c3d9
            return "treat the files as %s read/only content." % prettyprint(f,"_ro_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if f.endswith("_modules_t"):
Dan Walsh 05c3d9
            return "treat the files as %s modules." % prettyprint(f, "_modules_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if f.endswith("_content_t"):
Dan Walsh 05c3d9
            return "treat the files as %s content." % prettyprint(f, "_content_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if f.endswith("_state_t"):
Dan Walsh 05c3d9
            return "treat the files as %s state data." % prettyprint(f, "_state_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if f.endswith("_files_t"):
Dan Walsh 05c3d9
            return "treat the files as %s content." % prettyprint(f, "_files_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if f.endswith("_file_t"):
Dan Walsh 05c3d9
            return "treat the files as %s content." % prettyprint(f, "_file_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if f.endswith("_data_t"):
Dan Walsh 05c3d9
            return "treat the files as %s content." % prettyprint(f, "_data_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if f.endswith("_file_t"):
Dan Walsh 05c3d9
            return "treat the data as %s content." % prettyprint(f, "_file_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if f.endswith("_tmp_t"):
Dan Walsh 05c3d9
            return "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t")
Dan Walsh 05c3d9
        if f.endswith("_etc_t"):
Dan Walsh 05c3d9
            return "store %s files in the /etc directories." % prettyprint(f, "_tmp_t")
Dan Walsh 05c3d9
        if f.endswith("_home_t"):
Dan Walsh 05c3d9
            return "store %s files in the users home directory." % prettyprint(f, "_home_t")
Dan Walsh 05c3d9
        if f.endswith("_tmpfs_t"):
Dan Walsh 05c3d9
            return "store %s files on a tmpfs file system." % prettyprint(f, "_tmpfs_t")
Dan Walsh 05c3d9
        if f.endswith("_unit_file_t"):
Dan Walsh 05c3d9
            return "treat files as a systemd unit file." 
Dan Walsh 05c3d9
        if f.endswith("_htaccess_t"):
Dan Walsh 05c3d9
            return "treat the file as a %s access file." % prettyprint(f, "_htaccess_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        return "treat the files as %s data." % prettyprint(f,"_t")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
    def booleans(self):
Dan Walsh 05c3d9
        self.booltext = ""
Dan Walsh 05c3d9
        for b in bools:
Dan Walsh 05c3d9
            if b.find(self.short_name) >= 0:
Dan Walsh 05c3d9
                if b.endswith("anon_write"):
Dan Walsh 05c3d9
                    self.anon_list.append(b)
Dan Walsh 05c3d9
                else:
Dan Walsh 03f80a
                    desc = seobject.booleans_dict[b][2][0].lower() + seobject.booleans_dict[b][2][1:]
Dan Walsh 03f80a
                    if desc[-1] == ".":
Dan Walsh 03f80a
                        desc = desc[:-1]
Dan Walsh 05c3d9
                    self.booltext += """
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
If you want to %s, you must turn on the %s boolean.
Dan Walsh 05c3d9
Dan Walsh 05c3d9
.EX
Dan Walsh 05c3d9
.B setsebool -P %s 1
Dan Walsh 05c3d9
.EE
Dan Walsh 05c3d9
""" % (desc, b, b)
Dan Walsh 05c3d9
    
Dan Walsh 05c3d9
        if self.booltext != "":        
Dan Walsh 05c3d9
            self.fd.write("""
Dan Walsh 05c3d9
.SH BOOLEANS
Dan Walsh 05c3d9
SELinux policy is customizable based on least access required.  %s policy is extremely flexible and has several booleans that allow you to manipulate the policy and run %s with the tightest access possible.
Dan Walsh 05c3d9
Dan Walsh 05c3d9
""" % (self.domainname, self.domainname))
Dan Walsh 05c3d9
Dan Walsh 05c3d9
            self.fd.write(self.booltext)
Dan Walsh 05c3d9
Miroslav Grepl 9c9358
    def nsswitch_domain(self):
Miroslav Grepl 9c9358
        nsswitch_types = []
Miroslav Grepl 355c11
        nsswitch_booleans = ['authlogin_nsswitch_use_ldap', 'kerberos_enabled']
Miroslav Grepl 9c9358
        nsswitchbooltext = ""
Miroslav Grepl 9c9358
        if "nsswitch_domain" in all_attributes:
Miroslav Grepl 9c9358
            self.fd.write("""
Miroslav Grepl 9c9358
.SH NSSWITCH DOMAIN
Miroslav Grepl 9c9358
""")
Miroslav Grepl 9c9358
            for k in self.attributes.keys():    
Miroslav Grepl 9c9358
                if "nsswitch_domain" in self.attributes[k]:
Miroslav Grepl 9c9358
                    nsswitch_types.append(k)
Miroslav Grepl 9c9358
Miroslav Grepl 9c9358
            if len(nsswitch_types):
Miroslav Grepl 9c9358
                for i in nsswitch_booleans:
Miroslav Grepl 9c9358
                    desc = seobject.booleans_dict[i][2][0].lower() + seobject.booleans_dict[i][2][1:-1]
Miroslav Grepl 9c9358
                    nsswitchbooltext += """
Miroslav Grepl 9c9358
.PP
Miroslav Grepl 9c9358
If you want to %s for the %s, you must turn on the %s boolean.
Miroslav Grepl 9c9358
Miroslav Grepl 9c9358
.EX
Miroslav Grepl 9c9358
setsebool -P %s 1
Miroslav Grepl 9c9358
.EE
Miroslav Grepl 9c9358
""" % (desc,(", ".join(nsswitch_types)), i, i)
Miroslav Grepl 9c9358
Miroslav Grepl 9c9358
        self.fd.write(nsswitchbooltext)
Miroslav Grepl 9c9358
Dan Walsh 05c3d9
    def process_types(self):
Miroslav Grepl 9c9358
        if len(self.ptypes) == 0:
Dan Walsh 05c3d9
            return
Dan Walsh 05c3d9
        self.fd.write(r"""
Dan Walsh 05c3d9
.SH PROCESS TYPES
Dan Walsh 05c3d9
SELinux defines process types (domains) for each process running on the system
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
You can see the context of a process using the \fB\-Z\fP option to \fBps\bP
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
Policy governs the access confined processes have to files. 
Dan Walsh 05c3d9
SELinux %(domainname)s policy is very flexible allowing users to setup their %(domainname)s processes in as secure a method as possible.
Dan Walsh 05c3d9
.PP 
Dan Walsh 05c3d9
The following process types are defined for %(domainname)s:
Dan Walsh 05c3d9
""" % {'domainname':self.domainname})
Dan Walsh 05c3d9
        self.fd.write("""
Dan Walsh 05c3d9
.EX
Dan Walsh 05c3d9
.B %s 
Miroslav Grepl 9c9358
.EE""" % ", ".join(self.ptypes))
Dan Walsh 05c3d9
        self.fd.write("""
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
Note: 
Miroslav Grepl 9ba137
.B semanage permissive -a PROCESS_TYPE 
Dan Walsh 05c3d9
can be used to make a process type permissive. Permissive process types are not denied access by SELinux. AVC messages will still be generated.
Dan Walsh 05c3d9
""")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
    def port_types(self):
Dan Walsh 05c3d9
        self.ports = []
Dan Walsh 05c3d9
        for f in port_types:
Dan Walsh 05c3d9
            if f.startswith(self.short_name):
Dan Walsh 05c3d9
                self.ports.append(f)
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if len(self.ports) == 0:
Dan Walsh 05c3d9
            return
Dan Walsh 05c3d9
        self.fd.write("""
Dan Walsh 05c3d9
.SH PORT TYPES
Dan Walsh 05c3d9
SELinux defines port types to represent TCP and UDP ports. 
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
You can see the types associated with a port by using the following command: 
Dan Walsh 05c3d9
Dan Walsh 05c3d9
.B semanage port -l
Dan Walsh 05c3d9
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
Policy governs the access confined processes have to these ports. 
Dan Walsh 05c3d9
SELinux %(domainname)s policy is very flexible allowing users to setup their %(domainname)s processes in as secure a method as possible.
Dan Walsh 05c3d9
.PP 
Dan Walsh 05c3d9
The following port types are defined for %(domainname)s:""" % {'domainname':self.domainname})
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        for p in self.ports:
Dan Walsh 05c3d9
            self.fd.write("""
Dan Walsh 05c3d9
Dan Walsh 05c3d9
.EX
Dan Walsh 05c3d9
.TP 5
Dan Walsh 05c3d9
.B %s 
Dan Walsh 05c3d9
.TP 10
Dan Walsh 05c3d9
.EE
Dan Walsh 05c3d9
""" % p)
Dan Walsh 05c3d9
            once = True
Miroslav Grepl 1c3892
            for prot in ( "tcp", "udp" ):
Miroslav Grepl 1c3892
               if (p,prot) in portrecs:
Dan Walsh 05c3d9
                    if once:
Dan Walsh 05c3d9
                        self.fd.write("""
Dan Walsh 05c3d9
Dan Walsh 05c3d9
Default Defined Ports:""")
Dan Walsh 05c3d9
                    once = False
Dan Walsh 05c3d9
                    self.fd.write(r"""
Dan Walsh 05c3d9
%s %s
Miroslav Grepl 1c3892
.EE""" % (prot, ",".join(portrecs[(p,prot)])))
Dan Walsh 05c3d9
Dan Walsh 05c3d9
    def file_context(self):
Dan Walsh 05c3d9
        self.fd.write(r"""
Dan Walsh 05c3d9
.SH FILE CONTEXTS
Dan Walsh 05c3d9
SELinux requires files to have an extended attribute to define the file type. 
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
You can see the context of a file using the \fB\-Z\fP option to \fBls\bP
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
Policy governs the access confined processes have to these files. 
Dan Walsh 05c3d9
SELinux %(domainname)s policy is very flexible allowing users to setup their %(domainname)s processes in as secure a method as possible.
Dan Walsh 05c3d9
.PP 
Dan Walsh 05c3d9
The following file types are defined for %(domainname)s:
Dan Walsh 05c3d9
""" % {'domainname':self.domainname})
Dan Walsh 05c3d9
        for f in file_types:
Dan Walsh 05c3d9
            if f.startswith(self.domainname):
Dan Walsh 05c3d9
                self.fd.write("""
Dan Walsh 05c3d9
Dan Walsh 05c3d9
.EX
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
.B %s 
Dan Walsh 05c3d9
.EE
Dan Walsh 05c3d9
Dan Walsh 05c3d9
- Set files with the %s type, if you want to %s
Dan Walsh 05c3d9
""" % (f, f, self.explain(f)))
Dan Walsh 05c3d9
Dan Walsh 05c3d9
                if f in files_dict:
Dan Walsh 05c3d9
                    plural = ""
Dan Walsh 05c3d9
                    if len(files_dict[f]) > 1:
Dan Walsh 05c3d9
                        plural = "s"
Dan Walsh 05c3d9
                        self.fd.write("""
Dan Walsh 05c3d9
.br
Dan Walsh 05c3d9
.TP 5
Dan Walsh 05c3d9
Path%s: 
Dan Walsh 05c3d9
%s""" % (plural, files_dict[f][0][0]))
Dan Walsh 05c3d9
                        for x in files_dict[f][1:]:
Dan Walsh 05c3d9
                            self.fd.write(", %s" % x[0])
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        self.fd.write("""
Dan Walsh 05c3d9
Dan Walsh 05c3d9
.PP
Dan Walsh 03f80a
Note: File context can be temporarily modified with the chcon command.  If you want to permanently change the file context you need to use the 
Dan Walsh 05c3d9
.B semanage fcontext 
Dan Walsh 05c3d9
command.  This will modify the SELinux labeling database.  You will need to use
Dan Walsh 05c3d9
.B restorecon
Dan Walsh 05c3d9
to apply the labels.
Dan Walsh 05c3d9
""")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
    def public_content(self):
Dan Walsh 05c3d9
        if len(self.anon_list) > 0:
Dan Walsh 05c3d9
            self.fd.write("""
Dan Walsh 05c3d9
.SH SHARING FILES
Dan Walsh 05c3d9
If you want to share files with multiple domains (Apache, FTP, rsync, Samba), you can set a file context of public_content_t and public_content_rw_t.  These context allow any of the above domains to read the content.  If you want a particular domain to write to the public_content_rw_t domain, you must set the appropriate boolean.
Dan Walsh 05c3d9
.TP
Dan Walsh 05c3d9
Allow %(domainname)s servers to read the /var/%(domainname)s directory by adding the public_content_t file type to the directory and by restoring the file type.
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
.B
Dan Walsh 05c3d9
semanage fcontext -a -t public_content_t "/var/%(domainname)s(/.*)?"
Dan Walsh 05c3d9
.br
Dan Walsh 05c3d9
.B restorecon -F -R -v /var/%(domainname)s
Dan Walsh 05c3d9
.pp
Dan Walsh 05c3d9
.TP
Dan Walsh 05c3d9
Allow %(domainname)s servers to read and write /var/tmp/incoming by adding the public_content_rw_t type to the directory and by restoring the file type.  This also requires the allow_%(domainname)sd_anon_write boolean to be set.
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
.B
Dan Walsh 05c3d9
semanage fcontext -a -t public_content_rw_t "/var/%(domainname)s/incoming(/.*)?"
Dan Walsh 05c3d9
.br
Dan Walsh 05c3d9
.B restorecon -F -R -v /var/%(domainname)s/incoming
Dan Walsh 05c3d9
Dan Walsh 05c3d9
"""  % {'domainname':self.domainname})
Dan Walsh 05c3d9
            for b in self.anon_list:
Dan Walsh 05c3d9
                desc = seobject.booleans_dict[b][2][0].lower() + seobject.booleans_dict[b][2][1:]
Dan Walsh 05c3d9
                self.fd.write("""
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
If you want to %s, you must turn on the %s boolean.
Dan Walsh 05c3d9
Dan Walsh 05c3d9
.EX
Dan Walsh 05c3d9
.B setsebool -P %s 1
Dan Walsh 05c3d9
.EE
Dan Walsh 05c3d9
""" % (desc, b, b))
Dan Walsh 05c3d9
Dan Walsh 05c3d9
    def footer(self):
Dan Walsh 05c3d9
        self.fd.write("""
Dan Walsh 05c3d9
.SH "COMMANDS"
Dan Walsh 05c3d9
.B semanage fcontext
Dan Walsh 05c3d9
can also be used to manipulate default file context mappings.
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
.B semanage permissive
Dan Walsh 05c3d9
can also be used to manipulate whether or not a process type is permissive.
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
.B semanage module
Dan Walsh 05c3d9
can also be used to enable/disable/install/remove policy modules.
Dan Walsh 05c3d9
""")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if len(self.ports) > 0:
Dan Walsh 05c3d9
            self.fd.write("""
Dan Walsh 05c3d9
.B semanage port
Dan Walsh 05c3d9
can also be used to manipulate the port definitions
Dan Walsh 05c3d9
""")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if self.booltext != "":        
Dan Walsh 05c3d9
            self.fd.write("""
Dan Walsh 05c3d9
.B semanage boolean
Dan Walsh 05c3d9
can also be used to manipulate the booleans
Dan Walsh 05c3d9
""")
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        self.fd.write("""
Dan Walsh 05c3d9
.PP
Dan Walsh 05c3d9
.B system-config-selinux 
Dan Walsh 05c3d9
is a GUI tool available to customize SELinux policy settings.
Dan Walsh 05c3d9
Dan Walsh 05c3d9
.SH AUTHOR	
Dan Walsh 05c3d9
This manual page was autogenerated by genman.py.
Dan Walsh 05c3d9
Dan Walsh 05c3d9
.SH "SEE ALSO"
Dan Walsh 05c3d9
selinux(8), %s(8), semanage(8), restorecon(8), chcon(1)
Dan Walsh 05c3d9
""" % self.domainname)
Dan Walsh 05c3d9
Dan Walsh 05c3d9
        if self.booltext != "":        
Dan Walsh 05c3d9
            self.fd.write(", setsebool(8)")
Dan Walsh 05c3d9
Dan Walsh 03f80a
if len(sys.argv) > 2:
Dan Walsh 03f80a
        domains = sys.argv[2:]
Dan Walsh 03f80a
Dan Walsh 05c3d9
for domainname in domains:
Dan Walsh 05c3d9
    ManPage(domainname, sys.argv[1])