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