• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python -Es
2#
3# Copyright (C) 2007-2012 Red Hat
4# see file 'COPYING' for use and warranty information
5#
6# policygentool is a tool for the initial generation of SELinux policy
7#
8#    This program is free software; you can redistribute it and/or
9#    modify it under the terms of the GNU General Public License as
10#    published by the Free Software Foundation; either version 2 of
11#    the License, or (at your option) any later version.
12#
13#    This program is distributed in the hope that it will be useful,
14#    but WITHOUT ANY WARRANTY; without even the implied warranty of
15#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16#    GNU General Public License for more details.
17#
18#    You should have received a copy of the GNU General Public License
19#    along with this program; if not, write to the Free Software
20#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21#                                        02111-1307  USA
22#
23#
24import os
25import sys
26import stat
27import re
28import sepolicy
29from sepolicy import get_all_types, get_all_attributes, get_all_roles
30import time
31import types
32import platform
33
34from .templates import executable
35from .templates import boolean
36from .templates import etc_rw
37from .templates import unit_file
38from .templates import var_cache
39from .templates import var_spool
40from .templates import var_lib
41from .templates import var_log
42from .templates import var_run
43from .templates import tmp
44from .templates import rw
45from .templates import network
46from .templates import script
47from .templates import spec
48from .templates import user
49import sepolgen.interfaces as interfaces
50import sepolgen.defaults as defaults
51
52##
53## I18N
54##
55PROGNAME = "policycoreutils"
56try:
57    import gettext
58    kwargs = {}
59    if sys.version_info < (3,):
60        kwargs['unicode'] = True
61    gettext.install(PROGNAME,
62                    localedir="/usr/share/locale",
63                    codeset='utf-8',
64                    **kwargs)
65except:
66    try:
67        import builtins
68        builtins.__dict__['_'] = str
69    except ImportError:
70        import __builtin__
71        __builtin__.__dict__['_'] = unicode
72
73
74def get_rpm_nvr_from_header(hdr):
75    'Given an RPM header return the package NVR as a string'
76    name = hdr['name']
77    version = hdr['version']
78    release = hdr['release']
79    release_version = version + "-" + release.split(".")[0]
80    os_version = release.split(".")[1]
81
82    return [name, release_version, os_version]
83
84
85def get_rpm_nvr_list(package):
86    try:
87        import rpm
88        nvr = None
89        ts = rpm.ts()
90        mi = ts.dbMatch(rpm.RPMTAG_NAME, package)
91        for h in mi:
92            nvr = get_rpm_nvr_from_header(h)
93            break
94    except:
95        print(("Failed to retrieve rpm info for %s") % package)
96        nvr = None
97
98    return nvr
99
100
101def get_all_ports():
102    dict = {}
103    for p in sepolicy.info(sepolicy.PORT):
104        if p['type'] == "reserved_port_t" or \
105                p['type'] == "port_t" or \
106                p['type'] == "hi_reserved_port_t":
107            continue
108        dict[(p['low'], p['high'], p['protocol'])] = (p['type'], p['range'])
109    return dict
110
111
112def get_all_users():
113    users = map(lambda x: x['name'], sepolicy.info(sepolicy.USER))
114    users.remove("system_u")
115    users.remove("root")
116    users.sort()
117    return users
118
119ALL = 0
120RESERVED = 1
121UNRESERVED = 2
122PORTS = 3
123ADMIN_TRANSITION_INTERFACE = "_admin$"
124USER_TRANSITION_INTERFACE = "_role$"
125
126DAEMON = 0
127DBUS = 1
128INETD = 2
129CGI = 3
130SANDBOX = 4
131USER = 5
132EUSER = 6
133TUSER = 7
134XUSER = 8
135LUSER = 9
136AUSER = 10
137RUSER = 11
138NEWTYPE = 12
139
140poltype = {}
141poltype[DAEMON] = _("Standard Init Daemon")
142poltype[DBUS] = _("DBUS System Daemon")
143poltype[INETD] = _("Internet Services Daemon")
144poltype[CGI] = _("Web Application/Script (CGI)")
145poltype[SANDBOX] = _("Sandbox")
146poltype[USER] = _("User Application")
147poltype[EUSER] = _("Existing Domain Type")
148poltype[TUSER] = _("Minimal Terminal Login User Role")
149poltype[XUSER] = _("Minimal X Windows Login User Role")
150poltype[LUSER] = _("Desktop Login User Role")
151poltype[AUSER] = _("Administrator Login User Role")
152poltype[RUSER] = _("Confined Root Administrator Role")
153poltype[NEWTYPE] = _("Module information for a new type")
154
155
156def get_poltype_desc():
157    keys = poltype.keys()
158    keys.sort()
159    msg = _("Valid Types:\n")
160    for k in keys:
161        msg += "%2s: %s\n" % (k, poltype[k])
162    return msg
163
164APPLICATIONS = [DAEMON, DBUS, INETD, USER, CGI]
165USERS = [XUSER, TUSER, LUSER, AUSER, RUSER]
166
167
168def verify_ports(ports):
169    if ports == "":
170        return []
171    max_port = 2 ** 16
172    try:
173        temp = []
174        for a in ports.split(","):
175            r = a.split("-")
176            if len(r) > 2:
177                raise ValueError
178            if len(r) == 1:
179                begin = int(r[0])
180                end = int(r[0])
181            else:
182                begin = int(r[0])
183                end = int(r[1])
184
185                if begin > end:
186                    raise ValueError
187
188            for p in range(begin, end + 1):
189                if p < 1 or p > max_port:
190                    raise ValueError
191                temp.append(p)
192        return temp
193    except ValueError:
194        raise ValueError(_("Ports must be numbers or ranges of numbers from 1 to %d " % max_port))
195
196
197class policy:
198
199    def __init__(self, name, type):
200        self.rpms = []
201        self.ports = []
202        self.all_roles = get_all_roles()
203        self.types = []
204
205        if type not in poltype:
206            raise ValueError(_("You must enter a valid policy type"))
207
208        if not name:
209            raise ValueError(_("You must enter a name for your policy module for your '%s'.") % poltype[type])
210        try:
211            self.ports = get_all_ports()
212        except ValueError as e:
213            print("Can not get port types, must be root for this information")
214        except RuntimeError as e:
215            print("Can not get port types", e)
216
217        self.symbols = {}
218        self.symbols["openlog"] = "set_use_kerberos(True)"
219        self.symbols["openlog"] = "set_use_kerb_rcache(True)"
220        self.symbols["openlog"] = "set_use_syslog(True)"
221        self.symbols["gethostby"] = "set_use_resolve(True)"
222        self.symbols["getaddrinfo"] = "set_use_resolve(True)"
223        self.symbols["getnameinfo"] = "set_use_resolve(True)"
224        self.symbols["krb"] = "set_use_kerberos(True)"
225        self.symbols["gss_accept_sec_context"] = "set_manage_krb5_rcache(True)"
226        self.symbols["krb5_verify_init_creds"] = "set_manage_krb5_rcache(True)"
227        self.symbols["krb5_rd_req"] = "set_manage_krb5_rcache(True)"
228        self.symbols["__syslog_chk"] = "set_use_syslog(True)"
229        self.symbols["getpwnam"] = "set_use_uid(True)"
230        self.symbols["getpwuid"] = "set_use_uid(True)"
231        self.symbols["dbus_"] = "set_use_dbus(True)"
232        self.symbols["pam_"] = "set_use_pam(True)"
233        self.symbols["pam_"] = "set_use_audit(True)"
234        self.symbols["fork"] = "add_process('fork')"
235        self.symbols["transition"] = "add_process('transition')"
236        self.symbols["sigchld"] = "add_process('sigchld')"
237        self.symbols["sigkill"] = "add_process('sigkill')"
238        self.symbols["sigstop"] = "add_process('sigstop')"
239        self.symbols["signull"] = "add_process('signull')"
240        self.symbols["ptrace"] = "add_process('ptrace')"
241        self.symbols["getsched"] = "add_process('getsched')"
242        self.symbols["setsched"] = "add_process('setsched')"
243        self.symbols["getsession"] = "add_process('getsession')"
244        self.symbols["getpgid"] = "add_process('getpgid')"
245        self.symbols["setpgid"] = "add_process('setpgid')"
246        self.symbols["getcap"] = "add_process('getcap')"
247        self.symbols["setcap"] = "add_process('setcap')"
248        self.symbols["share"] = "add_process('share')"
249        self.symbols["getattr"] = "add_process('getattr')"
250        self.symbols["setexec"] = "add_process('setexec')"
251        self.symbols["setfscreate"] = "add_process('setfscreate')"
252        self.symbols["noatsecure"] = "add_process('noatsecure')"
253        self.symbols["siginh"] = "add_process('siginh')"
254        self.symbols["kill"] = "add_process('signal_perms')"
255        self.symbols["setrlimit"] = "add_process('setrlimit')"
256        self.symbols["rlimitinh"] = "add_process('rlimitinh')"
257        self.symbols["dyntransition"] = "add_process('dyntransition')"
258        self.symbols["setcurrent"] = "add_process('setcurrent')"
259        self.symbols["execmem"] = "add_process('execmem')"
260        self.symbols["execstack"] = "add_process('execstack')"
261        self.symbols["execheap"] = "add_process('execheap')"
262        self.symbols["setkeycreate"] = "add_process('setkeycreate')"
263        self.symbols["setsockcreate"] = "add_process('setsockcreate')"
264
265        self.symbols["chown"] = "add_capability('chown')"
266        self.symbols["dac_override"] = "add_capability('dac_override')"
267        self.symbols["dac_read_search"] = "add_capability('dac_read_search')"
268        self.symbols["fowner"] = "add_capability('fowner')"
269        self.symbols["fsetid"] = "add_capability('fsetid')"
270        self.symbols["setgid"] = "add_capability('setgid')"
271        self.symbols["setegid"] = "add_capability('setgid')"
272        self.symbols["setresgid"] = "add_capability('setgid')"
273        self.symbols["setregid"] = "add_capability('setgid')"
274        self.symbols["setresuid"] = "add_capability('setuid')"
275        self.symbols["setuid"] = "add_capability('setuid')"
276        self.symbols["seteuid"] = "add_capability('setuid')"
277        self.symbols["setreuid"] = "add_capability('setuid')"
278        self.symbols["setresuid"] = "add_capability('setuid')"
279        self.symbols["setpcap"] = "add_capability('setpcap')"
280        self.symbols["linux_immutable"] = "add_capability('linux_immutable')"
281        self.symbols["net_bind_service"] = "add_capability('net_bind_service')"
282        self.symbols["net_broadcast"] = "add_capability('net_broadcast')"
283        self.symbols["net_admin"] = "add_capability('net_admin')"
284        self.symbols["net_raw"] = "add_capability('net_raw')"
285        self.symbols["ipc_lock"] = "add_capability('ipc_lock')"
286        self.symbols["ipc_owner"] = "add_capability('ipc_owner')"
287        self.symbols["sys_module"] = "add_capability('sys_module')"
288        self.symbols["sys_rawio"] = "add_capability('sys_rawio')"
289        self.symbols["chroot"] = "add_capability('sys_chroot')"
290        self.symbols["sys_chroot"] = "add_capability('sys_chroot')"
291        self.symbols["sys_ptrace"] = "add_capability('sys_ptrace')"
292        self.symbols["sys_pacct"] = "add_capability('sys_pacct')"
293        self.symbols["mount"] = "add_capability('sys_admin')"
294        self.symbols["unshare"] = "add_capability('sys_admin')"
295        self.symbols["sys_admin"] = "add_capability('sys_admin')"
296        self.symbols["sys_boot"] = "add_capability('sys_boot')"
297        self.symbols["sys_nice"] = "add_capability('sys_nice')"
298        self.symbols["sys_resource"] = "add_capability('sys_resource')"
299        self.symbols["sys_time"] = "add_capability('sys_time')"
300        self.symbols["sys_tty_config"] = "add_capability('sys_tty_config')"
301        self.symbols["mknod"] = "add_capability('mknod')"
302        self.symbols["lease"] = "add_capability('lease')"
303        self.symbols["audit_write"] = "add_capability('audit_write')"
304        self.symbols["audit_control"] = "add_capability('audit_control')"
305        self.symbols["setfcap"] = "add_capability('setfcap')"
306
307        self.DEFAULT_DIRS = {}
308        self.DEFAULT_DIRS["/etc"] = ["etc_rw", [], etc_rw]
309        self.DEFAULT_DIRS["/tmp"] = ["tmp", [], tmp]
310        self.DEFAULT_DIRS["rw"] = ["rw", [], rw]
311        self.DEFAULT_DIRS["/usr/lib/systemd/system"] = ["unit_file", [], unit_file]
312        self.DEFAULT_DIRS["/lib/systemd/system"] = ["unit_file", [], unit_file]
313        self.DEFAULT_DIRS["/etc/systemd/system"] = ["unit_file", [], unit_file]
314        self.DEFAULT_DIRS["/var/cache"] = ["var_cache", [], var_cache]
315        self.DEFAULT_DIRS["/var/lib"] = ["var_lib", [], var_lib]
316        self.DEFAULT_DIRS["/var/log"] = ["var_log", [], var_log]
317        self.DEFAULT_DIRS["/var/run"] = ["var_run", [], var_run]
318        self.DEFAULT_DIRS["/var/spool"] = ["var_spool", [], var_spool]
319
320        self.DEFAULT_EXT = {}
321        self.DEFAULT_EXT["_tmp_t"] = tmp
322        self.DEFAULT_EXT["_unit_file_t"] = unit_file
323        self.DEFAULT_EXT["_var_cache_t"] = var_cache
324        self.DEFAULT_EXT["_var_lib_t"] = var_lib
325        self.DEFAULT_EXT["_var_log_t"] = var_log
326        self.DEFAULT_EXT["_var_run_t"] = var_run
327        self.DEFAULT_EXT["_var_spool_t"] = var_spool
328        self.DEFAULT_EXT["_port_t"] = network
329
330        self.DEFAULT_KEYS = ["/etc", "/var/cache", "/var/log", "/tmp", "rw", "/var/lib", "/var/run", "/var/spool", "/etc/systemd/system", "/usr/lib/systemd/system", "/lib/systemd/system"]
331
332        self.DEFAULT_TYPES = (
333            (self.generate_daemon_types, self.generate_daemon_rules),
334            (self.generate_dbusd_types, self.generate_dbusd_rules),
335            (self.generate_inetd_types, self.generate_inetd_rules),
336            (self.generate_cgi_types, self.generate_cgi_rules),
337            (self.generate_sandbox_types, self.generate_sandbox_rules),
338            (self.generate_userapp_types, self.generate_userapp_rules),
339            (self.generate_existing_user_types, self.generate_existing_user_rules),
340            (self.generate_min_login_user_types, self.generate_login_user_rules),
341            (self.generate_x_login_user_types, self.generate_x_login_user_rules),
342            (self.generate_login_user_types, self.generate_login_user_rules),
343            (self.generate_admin_user_types, self.generate_login_user_rules),
344            (self.generate_root_user_types, self.generate_root_user_rules),
345            (self.generate_new_types, self.generate_new_rules))
346        if not re.match(r"^[a-zA-Z0-9-_]+$", name):
347            raise ValueError(_("Name must be alpha numberic with no spaces. Consider using option \"-n MODULENAME\""))
348
349        if type == CGI:
350            self.name = "httpd_%s_script" % name
351        else:
352            self.name = name
353
354        self.file_name = name
355
356        self.capabilities = []
357        self.processes = []
358        self.type = type
359        self.initscript = ""
360        self.program = None
361        self.in_tcp = [False, False, False, []]
362        self.in_udp = [False, False, False, []]
363        self.out_tcp = [False, False, False, []]
364        self.out_udp = [False, False, False, []]
365        self.use_resolve = False
366        self.use_tmp = False
367        self.use_uid = False
368        self.use_syslog = False
369        self.use_kerberos = False
370        self.manage_krb5_rcache = False
371        self.use_pam = False
372        self.use_dbus = False
373        self.use_audit = False
374        self.use_etc = self.type not in [EUSER, NEWTYPE]
375        self.use_localization = self.type not in [EUSER, NEWTYPE]
376        self.use_fd = self.type not in [EUSER, NEWTYPE]
377        self.use_terminal = False
378        self.use_mail = False
379        self.booleans = {}
380        self.files = {}
381        self.dirs = {}
382        self.found_tcp_ports = []
383        self.found_udp_ports = []
384        self.need_tcp_type = False
385        self.need_udp_type = False
386        self.admin_domains = []
387        self.existing_domains = []
388        self.transition_domains = []
389        self.transition_users = []
390        self.roles = []
391
392    def __isnetset(self, l):
393        return l[ALL] or l[RESERVED] or l[UNRESERVED] or len(l[PORTS]) > 0
394
395    def set_admin_domains(self, admin_domains):
396        self.admin_domains = admin_domains
397
398    def set_existing_domains(self, existing_domains):
399        self.existing_domains = existing_domains
400
401    def set_admin_roles(self, roles):
402        self.roles = roles
403
404    def set_transition_domains(self, transition_domains):
405        self.transition_domains = transition_domains
406
407    def set_transition_users(self, transition_users):
408        self.transition_users = transition_users
409
410    def use_in_udp(self):
411        return self.__isnetset(self.in_udp)
412
413    def use_out_udp(self):
414        return self.__isnetset(self.out_udp)
415
416    def use_udp(self):
417        return self.use_in_udp() or self.use_out_udp()
418
419    def use_in_tcp(self):
420        return self.__isnetset(self.in_tcp)
421
422    def use_out_tcp(self):
423        return self.__isnetset(self.out_tcp)
424
425    def use_tcp(self):
426        return self.use_in_tcp() or self.use_out_tcp()
427
428    def use_network(self):
429        return self.use_tcp() or self.use_udp()
430
431    def find_port(self, port, protocol="tcp"):
432        for begin, end, p in self.ports.keys():
433            if port >= begin and port <= end and protocol == p:
434                return self.ports[begin, end, protocol]
435        return None
436
437    def set_program(self, program):
438        if self.type not in APPLICATIONS:
439            raise ValueError(_("User Role types can not be assigned executables."))
440
441        self.program = program
442
443    def set_init_script(self, initscript):
444        if self.type != DAEMON:
445            raise ValueError(_("Only Daemon apps can use an init script.."))
446
447        self.initscript = initscript
448
449    def set_in_tcp(self, all, reserved, unreserved, ports):
450        self.in_tcp = [all, reserved, unreserved, verify_ports(ports)]
451
452    def set_in_udp(self, all, reserved, unreserved, ports):
453        self.in_udp = [all, reserved, unreserved, verify_ports(ports)]
454
455    def set_out_tcp(self, all, ports):
456        self.out_tcp = [all, False, False, verify_ports(ports)]
457
458    def set_out_udp(self, all, ports):
459        self.out_udp = [all, False, False, verify_ports(ports)]
460
461    def set_use_resolve(self, val):
462        if not isinstance(val, types.BooleanType):
463            raise ValueError(_("use_resolve must be a boolean value "))
464
465        self.use_resolve = val
466
467    def set_use_syslog(self, val):
468        if not isinstance(val, types.BooleanType):
469            raise ValueError(_("use_syslog must be a boolean value "))
470
471        self.use_syslog = val
472
473    def set_use_kerberos(self, val):
474        if not isinstance(val, types.BooleanType):
475            raise ValueError(_("use_kerberos must be a boolean value "))
476
477        self.use_kerberos = val
478
479    def set_manage_krb5_rcache(self, val):
480        if not isinstance(val, types.BooleanType):
481            raise ValueError(_("manage_krb5_rcache must be a boolean value "))
482
483        self.manage_krb5_rcache = val
484
485    def set_use_pam(self, val):
486        self.use_pam = (val is True)
487
488    def set_use_dbus(self, val):
489        self.use_dbus = (val is True)
490
491    def set_use_audit(self, val):
492        self.use_audit = (val is True)
493
494    def set_use_etc(self, val):
495        self.use_etc = (val is True)
496
497    def set_use_localization(self, val):
498        self.use_localization = (val is True)
499
500    def set_use_fd(self, val):
501        self.use_fd = (val is True)
502
503    def set_use_terminal(self, val):
504        self.use_terminal = (val is True)
505
506    def set_use_mail(self, val):
507        self.use_mail = (val is True)
508
509    def set_use_tmp(self, val):
510        if self.type in USERS:
511            raise ValueError(_("USER Types automatically get a tmp type"))
512
513        if val:
514            self.DEFAULT_DIRS["/tmp"][1].append("/tmp")
515        else:
516            self.DEFAULT_DIRS["/tmp"][1] = []
517
518    def set_use_uid(self, val):
519        self.use_uid = (val is True)
520
521    def generate_uid_rules(self):
522        if self.use_uid:
523            return re.sub("TEMPLATETYPE", self.name, executable.te_uid_rules)
524        else:
525            return ""
526
527    def generate_syslog_rules(self):
528        if self.use_syslog:
529            return re.sub("TEMPLATETYPE", self.name, executable.te_syslog_rules)
530        else:
531            return ""
532
533    def generate_resolve_rules(self):
534        if self.use_resolve:
535            return re.sub("TEMPLATETYPE", self.name, executable.te_resolve_rules)
536        else:
537            return ""
538
539    def generate_kerberos_rules(self):
540        if self.use_kerberos:
541            return re.sub("TEMPLATETYPE", self.name, executable.te_kerberos_rules)
542        else:
543            return ""
544
545    def generate_manage_krb5_rcache_rules(self):
546        if self.manage_krb5_rcache:
547            return re.sub("TEMPLATETYPE", self.name, executable.te_manage_krb5_rcache_rules)
548        else:
549            return ""
550
551    def generate_pam_rules(self):
552        newte = ""
553        if self.use_pam:
554            newte = re.sub("TEMPLATETYPE", self.name, executable.te_pam_rules)
555        return newte
556
557    def generate_audit_rules(self):
558        newte = ""
559        if self.use_audit:
560            newte = re.sub("TEMPLATETYPE", self.name, executable.te_audit_rules)
561        return newte
562
563    def generate_etc_rules(self):
564        newte = ""
565        if self.use_etc:
566            newte = re.sub("TEMPLATETYPE", self.name, executable.te_etc_rules)
567        return newte
568
569    def generate_fd_rules(self):
570        newte = ""
571        if self.use_fd:
572            newte = re.sub("TEMPLATETYPE", self.name, executable.te_fd_rules)
573        return newte
574
575    def generate_localization_rules(self):
576        newte = ""
577        if self.use_localization:
578            newte = re.sub("TEMPLATETYPE", self.name, executable.te_localization_rules)
579        return newte
580
581    def generate_dbus_rules(self):
582        newte = ""
583        if self.type != DBUS and self.use_dbus:
584            newte = re.sub("TEMPLATETYPE", self.name, executable.te_dbus_rules)
585        return newte
586
587    def generate_mail_rules(self):
588        newte = ""
589        if self.use_mail:
590            newte = re.sub("TEMPLATETYPE", self.name, executable.te_mail_rules)
591        return newte
592
593    def generate_network_action(self, protocol, action, port_name):
594        line = ""
595        method = "corenet_%s_%s_%s" % (protocol, action, port_name)
596        if method in sepolicy.get_methods():
597            line = "%s(%s_t)\n" % (method, self.name)
598        else:
599            line = """
600gen_require(`
601    type %s_t;
602')
603allow %s_t %s_t:%s_socket name_%s;
604""" % (port_name, self.name, port_name, protocol, action)
605        return line
606
607    def generate_network_types(self):
608        for i in self.in_tcp[PORTS]:
609            rec = self.find_port(int(i), "tcp")
610            if rec is None:
611                self.need_tcp_type = True
612            else:
613                port_name = rec[0][:-2]
614                line = self.generate_network_action("tcp", "bind", port_name)
615#                   line = "corenet_tcp_bind_%s(%s_t)\n" % (port_name, self.name)
616                if line not in self.found_tcp_ports:
617                    self.found_tcp_ports.append(line)
618
619        for i in self.out_tcp[PORTS]:
620            rec = self.find_port(int(i), "tcp")
621            if rec is None:
622                self.need_tcp_type = True
623            else:
624                port_name = rec[0][:-2]
625                line = self.generate_network_action("tcp", "connect", port_name)
626#                   line = "corenet_tcp_connect_%s(%s_t)\n" % (port_name, self.name)
627                if line not in self.found_tcp_ports:
628                    self.found_tcp_ports.append(line)
629
630        for i in self.in_udp[PORTS]:
631            rec = self.find_port(int(i), "udp")
632            if rec is None:
633                self.need_udp_type = True
634            else:
635                port_name = rec[0][:-2]
636                line = self.generate_network_action("udp", "bind", port_name)
637#                   line = "corenet_udp_bind_%s(%s_t)\n" % (port_name, self.name)
638                if line not in self.found_udp_ports:
639                    self.found_udp_ports.append(line)
640
641        if self.need_udp_type is True or self.need_tcp_type is True:
642            return re.sub("TEMPLATETYPE", self.name, network.te_types)
643        return ""
644
645    def __find_path(self, file):
646        for d in self.DEFAULT_DIRS:
647            if file.find(d) is 0:
648                self.DEFAULT_DIRS[d][1].append(file)
649                return self.DEFAULT_DIRS[d]
650        self.DEFAULT_DIRS["rw"][1].append(file)
651        return self.DEFAULT_DIRS["rw"]
652
653    def add_capability(self, capability):
654        if capability not in self.capabilities:
655            self.capabilities.append(capability)
656
657    def set_types(self, types):
658        self.types = types
659
660    def add_process(self, process):
661        if process not in self.processes:
662            self.processes.append(process)
663
664    def add_boolean(self, name, description):
665        self.booleans[name] = description
666
667    def add_file(self, file):
668        self.files[file] = self.__find_path(file)
669
670    def add_dir(self, file):
671        self.dirs[file] = self.__find_path(file)
672
673    def generate_capabilities(self):
674        newte = ""
675        self.capabilities.sort()
676        if len(self.capabilities) > 0:
677            newte = "allow %s_t self:capability { %s };\n" % (self.name, " ".join(self.capabilities))
678        return newte
679
680    def generate_process(self):
681        newte = ""
682        self.processes.sort()
683        if len(self.processes) > 0:
684            newte = "allow %s_t self:process { %s };\n" % (self.name, " ".join(self.processes))
685        return newte
686
687    def generate_network_rules(self):
688        newte = ""
689        if self.use_network():
690            newte = "\n"
691
692            newte += re.sub("TEMPLATETYPE", self.name, network.te_network)
693
694            if self.use_tcp():
695                newte += "\n"
696                newte += re.sub("TEMPLATETYPE", self.name, network.te_tcp)
697
698                if self.use_in_tcp():
699                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_tcp)
700
701                    if self.need_tcp_type and len(self.in_tcp[PORTS]) > 0:
702                        newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_tcp)
703
704                if self.need_tcp_type and len(self.out_tcp[PORTS]) > 0:
705                    newte += re.sub("TEMPLATETYPE", self.name, network.te_out_need_port_tcp)
706
707                if self.in_tcp[ALL]:
708                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_tcp)
709                if self.in_tcp[RESERVED]:
710                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_tcp)
711                if self.in_tcp[UNRESERVED]:
712                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_tcp)
713
714                if self.out_tcp[ALL]:
715                    newte += re.sub("TEMPLATETYPE", self.name, network.te_out_all_ports_tcp)
716                if self.out_tcp[RESERVED]:
717                    newte += re.sub("TEMPLATETYPE", self.name, network.te_out_reserved_ports_tcp)
718                if self.out_tcp[UNRESERVED]:
719                    newte += re.sub("TEMPLATETYPE", self.name, network.te_out_unreserved_ports_tcp)
720
721                for i in self.found_tcp_ports:
722                    newte += i
723
724            if self.use_udp():
725                newte += "\n"
726                newte += re.sub("TEMPLATETYPE", self.name, network.te_udp)
727
728                if self.need_udp_type:
729                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_need_port_udp)
730                if self.use_in_udp():
731                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_udp)
732                if self.in_udp[ALL]:
733                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_all_ports_udp)
734                if self.in_udp[RESERVED]:
735                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_reserved_ports_udp)
736                if self.in_udp[UNRESERVED]:
737                    newte += re.sub("TEMPLATETYPE", self.name, network.te_in_unreserved_ports_udp)
738
739                for i in self.found_udp_ports:
740                    newte += i
741        return newte
742
743    def generate_transition_rules(self):
744        newte = ""
745        for app in self.transition_domains:
746            tmp = re.sub("TEMPLATETYPE", self.name, user.te_transition_rules)
747            newte += re.sub("APPLICATION", app, tmp)
748
749        if self.type == USER:
750            for u in self.transition_users:
751                temp = re.sub("TEMPLATETYPE", self.name, executable.te_run_rules)
752                newte += re.sub("USER", u.split("_u")[0], temp)
753
754        return newte
755
756    def generate_admin_rules(self):
757        newte = ""
758        if self.type == EUSER:
759            for d in self.existing_domains:
760                name = d.split("_t")[0]
761                role = name + "_r"
762                for app in self.admin_domains:
763                    tmp = re.sub("TEMPLATETYPE", name, user.te_admin_domain_rules)
764                    if role not in self.all_roles:
765                        tmp = re.sub(role, "system_r", tmp)
766
767                    newte += re.sub("APPLICATION", app, tmp)
768
769            return newte
770
771        if self.type == RUSER:
772            newte += re.sub("TEMPLATETYPE", self.name, user.te_admin_rules)
773
774            for app in self.admin_domains:
775                tmp = re.sub("TEMPLATETYPE", self.name, user.te_admin_domain_rules)
776                newte += re.sub("APPLICATION", app, tmp)
777
778            for u in self.transition_users:
779                role = u.split("_u")[0]
780
781                if (role + "_r") in self.all_roles:
782                    tmp = re.sub("TEMPLATETYPE", self.name, user.te_admin_trans_rules)
783                    newte += re.sub("USER", role, tmp)
784
785        return newte
786
787    def generate_dbus_if(self):
788        newif = ""
789        if self.use_dbus:
790            newif = re.sub("TEMPLATETYPE", self.name, executable.if_dbus_rules)
791        return newif
792
793    def generate_sandbox_if(self):
794        newif = ""
795        if self.type != SANDBOX:
796            return newif
797        newif = re.sub("TEMPLATETYPE", self.name, executable.if_sandbox_rules)
798        return newif
799
800    def generate_admin_if(self):
801        newif = ""
802        newtypes = ""
803        if self.initscript != "":
804            newtypes += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin_types)
805            newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_admin)
806        for d in self.DEFAULT_KEYS:
807            if len(self.DEFAULT_DIRS[d][1]) > 0:
808                newtypes += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_types)
809                newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_admin_rules)
810
811        if newif != "":
812            ret = re.sub("TEMPLATETYPE", self.name, executable.if_begin_admin)
813            ret += newtypes
814
815            ret += re.sub("TEMPLATETYPE", self.name, executable.if_middle_admin)
816            ret += newif
817            ret += re.sub("TEMPLATETYPE", self.name, executable.if_end_admin)
818            return ret
819
820        return ""
821
822    def generate_cgi_types(self):
823        return re.sub("TEMPLATETYPE", self.file_name, executable.te_cgi_types)
824
825    def generate_sandbox_types(self):
826        return re.sub("TEMPLATETYPE", self.file_name, executable.te_sandbox_types)
827
828    def generate_userapp_types(self):
829        return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_types)
830
831    def generate_inetd_types(self):
832        return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_types)
833
834    def generate_dbusd_types(self):
835        return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_types)
836
837    def generate_min_login_user_types(self):
838        return re.sub("TEMPLATETYPE", self.name, user.te_min_login_user_types)
839
840    def generate_login_user_types(self):
841        return re.sub("TEMPLATETYPE", self.name, user.te_login_user_types)
842
843    def generate_admin_user_types(self):
844        return re.sub("TEMPLATETYPE", self.name, user.te_admin_user_types)
845
846    def generate_existing_user_types(self):
847        if len(self.existing_domains) == 0:
848            raise ValueError(_("'%s' policy modules require existing domains") % poltype[self.type])
849        newte = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_types)
850        newte += """gen_require(`"""
851
852        for d in self.existing_domains:
853            newte += """
854        type %s;""" % d
855            role = d.split("_t")[0] + "_r"
856            if role in self.all_roles:
857                newte += """
858	role %s;""" % role
859        newte += """
860')
861"""
862        return newte
863
864    def generate_x_login_user_types(self):
865        return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_types)
866
867    def generate_root_user_types(self):
868        return re.sub("TEMPLATETYPE", self.name, user.te_root_user_types)
869
870    def generate_new_types(self):
871        newte = ""
872        if len(self.types) == 0:
873            raise ValueError(_("Type field required"))
874
875        for t in self.types:
876            for i in self.DEFAULT_EXT:
877                if t.endswith(i):
878                    print(t, t[:-len(i)])
879                    newte += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].te_types)
880                    break
881
882        if NEWTYPE and newte == "":
883            default_ext = []
884            for i in self.DEFAULT_EXT:
885                default_ext.append(i)
886            raise ValueError(_("You need to define a new type which ends with: \n %s") % "\n ".join(default_ext))
887
888        return newte
889
890    def generate_new_rules(self):
891        return ""
892
893    def generate_daemon_types(self):
894        newte = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_types)
895        if self.initscript != "":
896            newte += re.sub("TEMPLATETYPE", self.name, executable.te_initscript_types)
897        return newte
898
899    def generate_tmp_types(self):
900        if self.use_tmp:
901            return re.sub("TEMPLATETYPE", self.name, tmp.te_types)
902        else:
903            return ""
904
905    def generate_booleans(self):
906        newte = ""
907        for b in self.booleans:
908            tmp = re.sub("BOOLEAN", b, boolean.te_boolean)
909            newte += re.sub("DESCRIPTION", self.booleans[b], tmp)
910        return newte
911
912    def generate_boolean_rules(self):
913        newte = ""
914        for b in self.booleans:
915            newte += re.sub("BOOLEAN", b, boolean.te_rules)
916        return newte
917
918    def generate_sandbox_te(self):
919        return re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_types)
920
921    def generate_cgi_te(self):
922        return re.sub("TEMPLATETYPE", self.name, executable.te_cgi_types)
923
924    def generate_daemon_rules(self):
925        newif = re.sub("TEMPLATETYPE", self.name, executable.te_daemon_rules)
926
927        return newif
928
929    def generate_new_type_if(self):
930        newif = ""
931        for t in self.types:
932            for i in self.DEFAULT_EXT:
933                if t.endswith(i):
934                    reqtype = t[:-len(i)] + "_t"
935                    newif += re.sub("TEMPLATETYPE", t[:-len(i)], self.DEFAULT_EXT[i].if_rules)
936                    break
937        return newif
938
939    def generate_login_user_rules(self):
940        return re.sub("TEMPLATETYPE", self.name, user.te_login_user_rules)
941
942    def generate_existing_user_rules(self):
943        nerules = re.sub("TEMPLATETYPE", self.name, user.te_existing_user_rules)
944        return nerules
945
946    def generate_x_login_user_rules(self):
947        return re.sub("TEMPLATETYPE", self.name, user.te_x_login_user_rules)
948
949    def generate_root_user_rules(self):
950        newte = re.sub("TEMPLATETYPE", self.name, user.te_root_user_rules)
951        return newte
952
953    def generate_userapp_rules(self):
954        return re.sub("TEMPLATETYPE", self.name, executable.te_userapp_rules)
955
956    def generate_inetd_rules(self):
957        return re.sub("TEMPLATETYPE", self.name, executable.te_inetd_rules)
958
959    def generate_dbusd_rules(self):
960        return re.sub("TEMPLATETYPE", self.name, executable.te_dbusd_rules)
961
962    def generate_tmp_rules(self):
963        if self.use_tmp:
964            return re.sub("TEMPLATETYPE", self.name, tmp.te_rules)
965        else:
966            return ""
967
968    def generate_cgi_rules(self):
969        newte = ""
970        newte += re.sub("TEMPLATETYPE", self.name, executable.te_cgi_rules)
971        return newte
972
973    def generate_sandbox_rules(self):
974        newte = ""
975        newte += re.sub("TEMPLATETYPE", self.name, executable.te_sandbox_rules)
976        return newte
977
978    def generate_user_if(self):
979        newif = ""
980        if self.use_terminal or self.type == USER:
981            newif = re.sub("TEMPLATETYPE", self.name, executable.if_user_program_rules)
982
983        if self.type in (TUSER, XUSER, AUSER, LUSER):
984            newif += re.sub("TEMPLATETYPE", self.name, executable.if_role_change_rules)
985        return newif
986
987    def generate_if(self):
988        newif = ""
989        newif += re.sub("TEMPLATETYPE", self.name, executable.if_heading_rules)
990        if self.program:
991            newif += re.sub("TEMPLATETYPE", self.name, executable.if_program_rules)
992        if self.initscript != "":
993            newif += re.sub("TEMPLATETYPE", self.name, executable.if_initscript_rules)
994
995        for d in self.DEFAULT_KEYS:
996            if len(self.DEFAULT_DIRS[d][1]) > 0:
997                newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_rules)
998                for i in self.DEFAULT_DIRS[d][1]:
999                    if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
1000                        newif += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].if_stream_rules)
1001                        break
1002        newif += self.generate_user_if()
1003        newif += self.generate_dbus_if()
1004        newif += self.generate_admin_if()
1005        newif += self.generate_sandbox_if()
1006        newif += self.generate_new_type_if()
1007        newif += self.generate_new_rules()
1008
1009        return newif
1010
1011    def generate_default_types(self):
1012        return self.DEFAULT_TYPES[self.type][0]()
1013
1014    def generate_default_rules(self):
1015        if self.DEFAULT_TYPES[self.type][1]:
1016            return self.DEFAULT_TYPES[self.type][1]()
1017        return ""
1018
1019    def generate_roles_rules(self):
1020        newte = ""
1021        if self.type in (TUSER, XUSER, AUSER, LUSER):
1022            roles = ""
1023            if len(self.roles) > 0:
1024                newte += re.sub("TEMPLATETYPE", self.name, user.te_sudo_rules)
1025                newte += re.sub("TEMPLATETYPE", self.name, user.te_newrole_rules)
1026                for role in self.roles:
1027                    tmp = re.sub("TEMPLATETYPE", self.name, user.te_roles_rules)
1028                    newte += re.sub("ROLE", role, tmp)
1029        return newte
1030
1031    def generate_te(self):
1032        newte = self.generate_default_types()
1033        for d in self.DEFAULT_KEYS:
1034            if len(self.DEFAULT_DIRS[d][1]) > 0:
1035                # CGI scripts already have a rw_t
1036                if self.type != CGI or d != "rw":
1037                    newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_types)
1038
1039        if self.type != EUSER:
1040            newte += """
1041########################################
1042#
1043# %s local policy
1044#
1045""" % self.name
1046        newte += self.generate_capabilities()
1047        newte += self.generate_process()
1048        newte += self.generate_network_types()
1049        newte += self.generate_tmp_types()
1050        newte += self.generate_booleans()
1051        newte += self.generate_default_rules()
1052        newte += self.generate_boolean_rules()
1053
1054        for d in self.DEFAULT_KEYS:
1055            if len(self.DEFAULT_DIRS[d][1]) > 0:
1056                if self.type == EUSER:
1057                    newte_tmp = ""
1058                    for domain in self.existing_domains:
1059                        newte_tmp += re.sub("TEMPLATETYPE_t", domain[:-2] + "_t", self.DEFAULT_DIRS[d][2].te_rules)
1060                        newte += re.sub("TEMPLATETYPE_rw_t", self.name + "_rw_t", newte_tmp)
1061                else:
1062                    newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_rules)
1063                for i in self.DEFAULT_DIRS[d][1]:
1064                    if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
1065                        if self.type == EUSER:
1066                            for domain in self.existing_domains:
1067                                newte += re.sub("TEMPLATETYPE", domain[:-2], self.DEFAULT_DIRS[d][2].te_stream_rules)
1068
1069                        else:
1070                            newte += re.sub("TEMPLATETYPE", self.name, self.DEFAULT_DIRS[d][2].te_stream_rules)
1071                        break
1072
1073        newte += self.generate_tmp_rules()
1074        newte += self.generate_network_rules()
1075        newte += self.generate_fd_rules()
1076        newte += self.generate_etc_rules()
1077        newte += self.generate_pam_rules()
1078        newte += self.generate_uid_rules()
1079        newte += self.generate_audit_rules()
1080        newte += self.generate_syslog_rules()
1081        newte += self.generate_localization_rules()
1082        newte += self.generate_resolve_rules()
1083        newte += self.generate_roles_rules()
1084        newte += self.generate_mail_rules()
1085        newte += self.generate_transition_rules()
1086        newte += self.generate_admin_rules()
1087        newte += self.generate_dbus_rules()
1088        newte += self.generate_kerberos_rules()
1089        newte += self.generate_manage_krb5_rcache_rules()
1090
1091        return newte
1092
1093    def generate_fc(self):
1094        newfc = ""
1095        fclist = []
1096        for i in self.files.keys():
1097            if os.path.exists(i) and stat.S_ISSOCK(os.stat(i)[stat.ST_MODE]):
1098                t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_sock_file)
1099            else:
1100                t1 = re.sub("TEMPLATETYPE", self.name, self.files[i][2].fc_file)
1101            t2 = re.sub("FILENAME", i, t1)
1102            fclist.append(re.sub("FILETYPE", self.files[i][0], t2))
1103
1104        for i in self.dirs.keys():
1105            t1 = re.sub("TEMPLATETYPE", self.name, self.dirs[i][2].fc_dir)
1106            t2 = re.sub("FILENAME", i, t1)
1107            fclist.append(re.sub("FILETYPE", self.dirs[i][0], t2))
1108
1109        if self.type in USERS + [SANDBOX]:
1110            if len(fclist) == 0:
1111                return executable.fc_user
1112
1113        if self.type not in USERS + [SANDBOX, EUSER, NEWTYPE] and not self.program:
1114            raise ValueError(_("You must enter the executable path for your confined process"))
1115
1116        if self.program:
1117            t1 = re.sub("EXECUTABLE", self.program, executable.fc_program)
1118            fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
1119
1120        if self.initscript != "":
1121            t1 = re.sub("EXECUTABLE", self.initscript, executable.fc_initscript)
1122            fclist.append(re.sub("TEMPLATETYPE", self.name, t1))
1123
1124        fclist.sort()
1125        newfc = "\n".join(fclist)
1126        return newfc
1127
1128    def generate_user_sh(self):
1129        newsh = ""
1130        if self.type not in (TUSER, XUSER, AUSER, LUSER, RUSER):
1131            return newsh
1132
1133        roles = ""
1134        for role in self.roles:
1135            roles += " %s_r" % role
1136        if roles != "":
1137            roles += " system_r"
1138        tmp = re.sub("TEMPLATETYPE", self.name, script.users)
1139        newsh += re.sub("ROLES", roles, tmp)
1140
1141        if self.type == RUSER or self.type == AUSER:
1142            for u in self.transition_users:
1143                tmp = re.sub("TEMPLATETYPE", self.name, script.admin_trans)
1144                newsh += re.sub("USER", u, tmp)
1145
1146        if self.type == LUSER:
1147            newsh += re.sub("TEMPLATETYPE", self.name, script.min_login_user_default_context)
1148        else:
1149            newsh += re.sub("TEMPLATETYPE", self.name, script.x_login_user_default_context)
1150
1151        return newsh
1152
1153    def generate_sh(self):
1154        temp = re.sub("TEMPLATETYPE", self.file_name, script.compile)
1155        temp = re.sub("DOMAINTYPE", self.name, temp)
1156        if self.type == EUSER:
1157            newsh = re.sub("TEMPLATEFILE", "%s" % self.file_name, temp)
1158        else:
1159            newsh = re.sub("TEMPLATEFILE", self.file_name, temp)
1160            newsh += re.sub("DOMAINTYPE", self.name, script.manpage)
1161
1162        if self.program:
1163            newsh += re.sub("FILENAME", self.program, script.restorecon)
1164        if self.initscript != "":
1165            newsh += re.sub("FILENAME", self.initscript, script.restorecon)
1166
1167        for i in self.files.keys():
1168            newsh += re.sub("FILENAME", i, script.restorecon)
1169
1170        for i in self.dirs.keys():
1171            newsh += re.sub("FILENAME", i, script.restorecon)
1172
1173        for i in self.in_tcp[PORTS] + self.out_tcp[PORTS]:
1174            if self.find_port(i, "tcp") is None:
1175                t1 = re.sub("PORTNUM", "%d" % i, script.tcp_ports)
1176                newsh += re.sub("TEMPLATETYPE", self.name, t1)
1177
1178        for i in self.in_udp[PORTS]:
1179            if self.find_port(i, "udp") is None:
1180                t1 = re.sub("PORTNUM", "%d" % i, script.udp_ports)
1181                newsh += re.sub("TEMPLATETYPE", self.name, t1)
1182
1183        newsh += self.generate_user_sh()
1184        if (platform.linux_distribution(full_distribution_name=0)[0] in ("redhat", "centos", "SuSE", "fedora", "mandrake", "mandriva")):
1185            newsh += re.sub("TEMPLATEFILE", self.file_name, script.rpm)
1186
1187        return newsh
1188
1189    def generate_spec(self):
1190        newspec = ""
1191
1192        selinux_policynvr = get_rpm_nvr_list("selinux-policy")
1193
1194        if selinux_policynvr is None:
1195            selinux_policyver = "0.0.0"
1196        else:
1197            selinux_policyver = selinux_policynvr[1]
1198
1199        newspec += spec.header_comment_section
1200        if self.type in APPLICATIONS:
1201            newspec += spec.define_relabel_files_begin
1202            if self.program:
1203                newspec += re.sub("FILENAME", self.program, spec.define_relabel_files_end)
1204            if self.initscript != "":
1205                newspec += re.sub("FILENAME", self.initscript, spec.define_relabel_files_end)
1206            for i in self.files.keys():
1207                newspec += re.sub("FILENAME", i, spec.define_relabel_files_end)
1208            for i in self.dirs.keys():
1209                newspec += re.sub("FILENAME", i, spec.define_relabel_files_end)
1210
1211        newspec += re.sub("VERSION", selinux_policyver, spec.base_section)
1212        newspec = re.sub("MODULENAME", self.file_name, newspec)
1213        newspec = re.sub("DOMAINNAME", self.name, newspec)
1214        if len(self.rpms) > 0:
1215            newspec += "Requires(post): %s\n" % ", ".join(self.rpms)
1216        newspec += re.sub("MODULENAME", self.file_name, spec.mid_section)
1217        newspec = re.sub("DOMAINNAME", self.name, newspec)
1218        newspec = re.sub("TODAYSDATE", time.strftime("%a %b %e %Y"), newspec)
1219
1220        if self.type not in APPLICATIONS:
1221            newspec = re.sub("%relabel_files", "", newspec)
1222
1223        # Remove man pages from EUSER spec file
1224        if self.type == EUSER:
1225            newspec = re.sub(".*%s_selinux.8.*" % self.name, "", newspec)
1226        # Remove user context file from non users spec file
1227        if self.type not in (TUSER, XUSER, AUSER, LUSER, RUSER):
1228            newspec = re.sub(".*%s_u.*" % self.name, "", newspec)
1229        return newspec
1230
1231    def write_spec(self, out_dir):
1232        specfile = "%s/%s_selinux.spec" % (out_dir, self.file_name)
1233        fd = open(specfile, "w")
1234        fd.write(self.generate_spec())
1235        fd.close()
1236
1237        return specfile
1238
1239    def write_te(self, out_dir):
1240        tefile = "%s/%s.te" % (out_dir, self.file_name)
1241        fd = open(tefile, "w")
1242        fd.write(self.generate_te())
1243        fd.close()
1244        return tefile
1245
1246    def write_sh(self, out_dir):
1247        shfile = "%s/%s.sh" % (out_dir, self.file_name)
1248        fd = open(shfile, "w")
1249        fd.write(self.generate_sh())
1250        fd.close()
1251        os.chmod(shfile, 0o750)
1252        return shfile
1253
1254    def write_if(self, out_dir):
1255        iffile = "%s/%s.if" % (out_dir, self.file_name)
1256        fd = open(iffile, "w")
1257        fd.write(self.generate_if())
1258        fd.close()
1259        return iffile
1260
1261    def write_fc(self, out_dir):
1262        fcfile = "%s/%s.fc" % (out_dir, self.file_name)
1263        fd = open(fcfile, "w")
1264        fd.write(self.generate_fc())
1265        fd.close()
1266        return fcfile
1267
1268    def __extract_rpms(self):
1269        import yum
1270        yb = yum.YumBase()
1271        yb.setCacheDir()
1272
1273        for pkg in yb.rpmdb.searchProvides(self.program):
1274            self.rpms.append(pkg.name)
1275            for fname in pkg.dirlist + pkg.filelist + pkg.ghostlist:
1276                for b in self.DEFAULT_DIRS:
1277                    if b == "/etc":
1278                        continue
1279                    if fname.startswith(b):
1280                        if os.path.isfile(fname):
1281                            self.add_file(fname)
1282                        else:
1283                            self.add_dir(fname)
1284
1285            for bpkg in yb.rpmdb.searchNames([pkg.base_package_name]):
1286                for fname in bpkg.dirlist + bpkg.filelist + bpkg.ghostlist:
1287                    for b in self.DEFAULT_DIRS:
1288                        if b == "/etc":
1289                            continue
1290                        if fname.startswith(b):
1291                            if os.path.isfile(fname):
1292                                self.add_file(fname)
1293                            else:
1294                                self.add_dir(fname)
1295
1296        # some packages have own systemd subpackage
1297        # tor-systemd for example
1298        binary_name = self.program.split("/")[-1]
1299        for bpkg in yb.rpmdb.searchNames(["%s-systemd" % binary_name]):
1300            for fname in bpkg.filelist + bpkg.ghostlist + bpkg.dirlist:
1301                for b in self.DEFAULT_DIRS:
1302                    if b == "/etc":
1303                        continue
1304                    if fname.startswith(b):
1305                        if os.path.isfile(fname):
1306                            self.add_file(fname)
1307                        else:
1308                            self.add_dir(fname)
1309
1310    def gen_writeable(self):
1311        try:
1312            self.__extract_rpms()
1313        except ImportError:
1314            pass
1315
1316        if os.path.isfile("/var/run/%s.pid" % self.name):
1317            self.add_file("/var/run/%s.pid" % self.name)
1318
1319        if os.path.isdir("/var/run/%s" % self.name):
1320            self.add_dir("/var/run/%s" % self.name)
1321
1322        if os.path.isdir("/var/log/%s" % self.name):
1323            self.add_dir("/var/log/%s" % self.name)
1324
1325        if os.path.isfile("/var/log/%s.log" % self.name):
1326            self.add_file("/var/log/%s.log" % self.name)
1327
1328        if os.path.isdir("/var/lib/%s" % self.name):
1329            self.add_dir("/var/lib/%s" % self.name)
1330
1331        if os.path.isfile("/etc/rc.d/init.d/%s" % self.name):
1332            self.set_init_script(r"/etc/rc\.d/init\.d/%s" % self.name)
1333
1334        # we don't want to have subdir in the .fc policy file
1335        # if we already specify labeling for parent dir
1336        temp_basepath = []
1337        for p in self.DEFAULT_DIRS.keys():
1338            temp_dirs = []
1339            try:
1340                temp_basepath = self.DEFAULT_DIRS[p][1][0] + "/"
1341            except IndexError:
1342                continue
1343
1344            for i in self.DEFAULT_DIRS[p][1]:
1345                if i.startswith(temp_basepath):
1346                    temp_dirs.append(i)
1347                else:
1348                    continue
1349
1350            if len(temp_dirs) is not 0:
1351                for i in temp_dirs:
1352                    if i in self.dirs.keys():
1353                        del(self.dirs[i])
1354                    elif i in self.files.keys():
1355                        del(self.files[i])
1356                    else:
1357                        continue
1358
1359                self.DEFAULT_DIRS[p][1] = list(set(self.DEFAULT_DIRS[p][1]) - set(temp_dirs))
1360
1361    def gen_symbols(self):
1362        if self.type not in APPLICATIONS:
1363            return
1364        if not os.path.exists(self.program):
1365            sys.stderr.write("""
1366***************************************
1367Warning %s does not exist
1368***************************************
1369
1370""" % self.program)
1371            return
1372        fd = os.popen("nm -D %s | grep U" % self.program)
1373        for s in fd.read().split():
1374            for b in self.symbols:
1375                if s.startswith(b):
1376                    exec("self.%s" % self.symbols[b])
1377        fd.close()
1378
1379    def generate(self, out_dir=os.getcwd()):
1380        out = "Created the following files:\n"
1381        out += "%s # %s\n" % (self.write_te(out_dir), _("Type Enforcement file"))
1382        out += "%s # %s\n" % (self.write_if(out_dir), _("Interface file"))
1383        out += "%s # %s\n" % (self.write_fc(out_dir), _("File Contexts file"))
1384        if self.type != NEWTYPE:
1385            if (platform.linux_distribution(full_distribution_name=0)[0] in ("redhat", "centos", "SuSE", "fedora", "mandrake", "mandriva")):
1386                out += "%s # %s\n" % (self.write_spec(out_dir), _("Spec file"))
1387            out += "%s # %s\n" % (self.write_sh(out_dir), _("Setup Script"))
1388        return out
1389