1#! /usr/bin/python -Es 2# Copyright (C) 2012 Red Hat 3# AUTHOR: Dan Walsh <dwalsh@redhat.com> 4# see file 'COPYING' for use and warranty information 5# 6# semanage is a tool for managing SELinux configuration files 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 selinux 27import sepolicy 28from sepolicy import get_os_version, get_conditionals, get_conditionals_format_text 29import argparse 30import gettext 31PROGNAME = "policycoreutils" 32gettext.bindtextdomain(PROGNAME, "/usr/share/locale") 33gettext.textdomain(PROGNAME) 34try: 35 gettext.install(PROGNAME, 36 localedir="/usr/share/locale", 37 unicode=False, 38 codeset='utf-8') 39except IOError: 40 import __builtin__ 41 __builtin__.__dict__['_'] = unicode 42 43usage = "sepolicy generate [-h] [-n NAME] [-p PATH] [" 44usage_dict = {' --newtype': ('-t [TYPES [TYPES ...]]',), ' --customize': ('-d DOMAIN', '-a ADMIN_DOMAIN', "[ -w WRITEPATHS ]",), ' --admin_user': ('[-r TRANSITION_ROLE ]', "[ -w WRITEPATHS ]",), ' --application': ('COMMAND', "[ -w WRITEPATHS ]",), ' --cgi': ('COMMAND', "[ -w WRITEPATHS ]",), ' --confined_admin': ('-a ADMIN_DOMAIN', "[ -w WRITEPATHS ]",), ' --dbus': ('COMMAND', "[ -w WRITEPATHS ]",), ' --desktop_user': ('', "[ -w WRITEPATHS ]",), ' --inetd': ('COMMAND', "[ -w WRITEPATHS ]",), ' --init': ('COMMAND', "[ -w WRITEPATHS ]",), ' --sandbox': ("[ -w WRITEPATHS ]",), ' --term_user': ("[ -w WRITEPATHS ]",), ' --x_user': ("[ -w WRITEPATHS ]",)} 45 46 47class CheckPath(argparse.Action): 48 49 def __call__(self, parser, namespace, values, option_string=None): 50 if not os.path.exists(values): 51 raise ValueError("%s does not exist" % values) 52 setattr(namespace, self.dest, values) 53 54 55class CheckType(argparse.Action): 56 57 def __call__(self, parser, namespace, values, option_string=None): 58 domains = sepolicy.get_all_domains() 59 60 if isinstance(values, str): 61 setattr(namespace, self.dest, values) 62 else: 63 newval = getattr(namespace, self.dest) 64 if not newval: 65 newval = [] 66 67 for v in values: 68 newval.append(v) 69 setattr(namespace, self.dest, newval) 70 71 72class CheckBoolean(argparse.Action): 73 74 def __call__(self, parser, namespace, values, option_string=None): 75 booleans = sepolicy.get_all_booleans() 76 newval = getattr(namespace, self.dest) 77 if not newval: 78 newval = [] 79 80 if isinstance(values, str): 81 v = selinux.selinux_boolean_sub(values) 82 if v not in booleans: 83 raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (v, ", ".join(booleans))) 84 newval.append(v) 85 setattr(namespace, self.dest, newval) 86 else: 87 for value in values: 88 v = selinux.selinux_boolean_sub(value) 89 if v not in booleans: 90 raise ValueError("%s must be an SELinux boolean:\nValid boolean: %s" % (v, ", ".join(booleans))) 91 newval.append(v) 92 setattr(namespace, self.dest, newval) 93 94 95class CheckDomain(argparse.Action): 96 97 def __call__(self, parser, namespace, values, option_string=None): 98 domains = sepolicy.get_all_domains() 99 100 if isinstance(values, str): 101 if values not in domains: 102 raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (values, ", ".join(domains))) 103 setattr(namespace, self.dest, values) 104 else: 105 newval = getattr(namespace, self.dest) 106 if not newval: 107 newval = [] 108 109 for v in values: 110 if v not in domains: 111 raise ValueError("%s must be an SELinux process domain:\nValid domains: %s" % (v, ", ".join(domains))) 112 newval.append(v) 113 setattr(namespace, self.dest, newval) 114 115all_classes = None 116 117 118class CheckClass(argparse.Action): 119 120 def __call__(self, parser, namespace, values, option_string=None): 121 global all_classes 122 if not all_classes: 123 all_classes = map(lambda x: x['name'], sepolicy.info(sepolicy.TCLASS)) 124 if values not in all_classes: 125 raise ValueError("%s must be an SELinux class:\nValid classes: %s" % (values, ", ".join(all_classes))) 126 127 setattr(namespace, self.dest, values) 128 129 130class CheckAdmin(argparse.Action): 131 132 def __call__(self, parser, namespace, values, option_string=None): 133 from sepolicy.interface import get_admin 134 newval = getattr(namespace, self.dest) 135 if not newval: 136 newval = [] 137 admins = get_admin() 138 if values not in admins: 139 raise ValueError("%s must be an SELinux admin domain:\nValid admin domains: %s" % (values, ", ".join(admins))) 140 newval.append(values) 141 setattr(namespace, self.dest, newval) 142 143 144class CheckPort(argparse.Action): 145 146 def __call__(self, parser, namespace, values, option_string=None): 147 newval = getattr(namespace, self.dest) 148 if not newval: 149 newval = [] 150 for v in values: 151 if v < 1 or v > 65536: 152 raise ValueError("%s must be an integer between 1 and 65536" % v) 153 newval.append(v) 154 setattr(namespace, self.dest, newval) 155 156 157class CheckPortType(argparse.Action): 158 159 def __call__(self, parser, namespace, values, option_string=None): 160 port_types = sepolicy.get_all_port_types() 161 newval = getattr(namespace, self.dest) 162 if not newval: 163 newval = [] 164 for v in values: 165 if v not in port_types: 166 raise ValueError("%s must be an SELinux port type:\nValid port types: %s" % (v, ", ".join(port_types))) 167 newval.append(v) 168 setattr(namespace, self.dest, values) 169 170 171class LoadPolicy(argparse.Action): 172 173 def __call__(self, parser, namespace, values, option_string=None): 174 import sepolicy 175 sepolicy.policy(values) 176 setattr(namespace, self.dest, values) 177 178 179class CheckPolicyType(argparse.Action): 180 181 def __call__(self, parser, namespace, values, option_string=None): 182 from sepolicy.generate import get_poltype_desc, poltype 183 if values not in poltype.keys(): 184 raise ValueError("%s invalid SELinux policy type\n%s" % (values, get_poltype_desc())) 185 newval.append(v) 186 setattr(namespace, self.dest, values) 187 188 189class CheckUser(argparse.Action): 190 191 def __call__(self, parser, namespace, value, option_string=None): 192 newval = getattr(namespace, self.dest) 193 if not newval: 194 newval = [] 195 users = sepolicy.get_all_users() 196 if value not in users: 197 raise ValueError("%s must be an SELinux user:\nValid users: %s" % (value, ", ".join(users))) 198 newval.append(value) 199 setattr(namespace, self.dest, newval) 200 201 202class CheckRole(argparse.Action): 203 204 def __call__(self, parser, namespace, value, option_string=None): 205 newval = getattr(namespace, self.dest) 206 if not newval: 207 newval = [] 208 roles = sepolicy.get_all_roles() 209 if value not in roles: 210 raise ValueError("%s must be an SELinux role:\nValid roles: %s" % (value, ", ".join(roles))) 211 newval.append(value[:-2]) 212 setattr(namespace, self.dest, newval) 213 214 215class InterfaceInfo(argparse.Action): 216 217 def __call__(self, parser, namespace, values, option_string=None): 218 from sepolicy.interface import get_interface_dict 219 interface_dict = get_interface_dict() 220 for v in values: 221 if v not in interface_dict.keys(): 222 raise ValueError(_("Interface %s does not exist.") % v) 223 224 setattr(namespace, self.dest, values) 225 226 227def generate_custom_usage(usage_text, usage_dict): 228 sorted_keys = [] 229 for i in usage_dict.keys(): 230 sorted_keys.append(i) 231 sorted_keys.sort() 232 for k in sorted_keys: 233 usage_text += "%s %s |" % (k, (" ".join(usage_dict[k]))) 234 usage_text = usage_text[:-1] + "]" 235 usage_text = _(usage_text) 236 237 return usage_text 238 239 240def numcmp(val1, val2): 241 try: 242 v1 = int(val1.split(",")[0].split("-")[0]) 243 v2 = int(val2.split(",")[0].split("-")[0]) 244 if v1 > v2: 245 return 1 246 if v1 == v2: 247 return 0 248 if v1 < v2: 249 return -1 250 except: 251 return cmp(val1, val2) 252 253 254def _print_net(src, protocol, perm): 255 import sepolicy.network 256 portdict = sepolicy.network.get_network_connect(src, protocol, perm) 257 if len(portdict) > 0: 258 bold_start = "\033[1m" 259 bold_end = "\033[0;0m" 260 print "\n" + bold_start + "%s: %s %s" % (src, protocol, perm) + bold_end 261 port_strings = [] 262 boolean_text = "" 263 for p in portdict: 264 for t, recs in portdict[p]: 265 cond = get_conditionals(src, t, "%s_socket" % protocol, [perm]) 266 if cond: 267 boolean_text = get_conditionals_format_text(cond) 268 port_strings.append("%s (%s) %s" % (", ".join(recs), t, boolean_text)) 269 else: 270 port_strings.append("%s (%s)" % (", ".join(recs), t)) 271 port_strings.sort(numcmp) 272 for p in port_strings: 273 print "\t" + p 274 275 276def network(args): 277 portrecs, portrecsbynum = sepolicy.gen_port_dict() 278 all_ports = [] 279 if args.list_ports: 280 for i in portrecs: 281 if i[0] not in all_ports: 282 all_ports.append(i[0]) 283 all_ports.sort() 284 print "\n".join(all_ports) 285 286 for port in args.port: 287 found = False 288 for i in portrecsbynum: 289 if i[0] <= port and port <= i[1]: 290 if i[0] == i[1]: 291 range = i[0] 292 else: 293 range = "%s-%s" % (i[0], i[1]) 294 found = True 295 print "%d: %s %s %s" % (port, i[2], portrecsbynum[i][0], range) 296 if not found: 297 if port < 500: 298 print "Undefined reserved port type" 299 else: 300 print "Undefined port type" 301 302 for t in args.type: 303 if (t, 'tcp') in portrecs.keys(): 304 print "%s: tcp: %s" % (t, ",".join(portrecs[t, 'tcp'])) 305 if (t, 'udp') in portrecs.keys(): 306 print "%s: udp: %s" % (t, ",".join(portrecs[t, 'udp'])) 307 308 for a in args.applications: 309 d = sepolicy.get_init_transtype(a) 310 if d: 311 args.domain.append(d) 312 313 for d in args.domain: 314 _print_net(d, "tcp", "name_connect") 315 for net in ("tcp", "udp"): 316 _print_net(d, net, "name_bind") 317 318 319def gui_run(args): 320 try: 321 import sepolicy.gui 322 sepolicy.gui.SELinuxGui(args.domain, args.test) 323 pass 324 except ImportError: 325 raise ValueError(_("You need to install policycoreutils-gui package to use the gui option")) 326 327 328def gen_gui_args(parser): 329 gui = parser.add_parser("gui", 330 help=_('Graphical User Interface for SELinux Policy')) 331 gui.add_argument("-d", "--domain", default=None, 332 action=CheckDomain, 333 help=_("Domain name(s) of man pages to be created")) 334 gui.add_argument("-t", "--test", default=False, action="store_true", 335 help=argparse.SUPPRESS) 336 gui.set_defaults(func=gui_run) 337 338 339def manpage(args): 340 from sepolicy.manpage import ManPage, HTMLManPages, manpage_domains, manpage_roles, gen_domains 341 342 path = args.path 343 if not args.policy and args.root != "/": 344 sepolicy.policy(sepolicy.get_installed_policy(args.root)) 345 if args.source_files and args.root == "/": 346 raise ValueError(_("Alternative root needs to be setup")) 347 348 if args.all: 349 test_domains = gen_domains() 350 else: 351 test_domains = args.domain 352 353 for domain in test_domains: 354 m = ManPage(domain, path, args.root, args.source_files, args.web) 355 print m.get_man_page_path() 356 357 if args.web: 358 HTMLManPages(manpage_roles, manpage_domains, path, args.os) 359 360 361def gen_manpage_args(parser): 362 man = parser.add_parser("manpage", 363 help=_('Generate SELinux man pages')) 364 365 man.add_argument("-p", "--path", dest="path", default="/tmp", 366 help=_("path in which the generated SELinux man pages will be stored")) 367 man.add_argument("-o", "--os", dest="os", default=get_os_version(), 368 help=_("name of the OS for man pages")) 369 man.add_argument("-w", "--web", dest="web", default=False, action="store_true", 370 help=_("Generate HTML man pages structure for selected SELinux man page")) 371 man.add_argument("-r", "--root", dest="root", default="/", 372 help=_("Alternate root directory, defaults to /")) 373 man.add_argument("--source_files", dest="source_files", default=False, action="store_true", 374 help=_("With this flag, alternative root path needs to include file context files and policy.xml file")) 375 group = man.add_mutually_exclusive_group(required=True) 376 group.add_argument("-a", "--all", dest="all", default=False, 377 action="store_true", 378 help=_("All domains")) 379 group.add_argument("-d", "--domain", nargs="+", 380 action=CheckDomain, 381 help=_("Domain name(s) of man pages to be created")) 382 man.set_defaults(func=manpage) 383 384 385def gen_network_args(parser): 386 net = parser.add_parser("network", 387 help=_('Query SELinux policy network information')) 388 389 group = net.add_mutually_exclusive_group(required=True) 390 group.add_argument("-l", "--list", dest="list_ports", 391 action="store_true", 392 help=_("list all SELinux port types")) 393 group.add_argument("-p", "--port", dest="port", default=[], 394 action=CheckPort, nargs="+", type=int, 395 help=_("show SELinux type related to the port")) 396 group.add_argument("-t", "--type", dest="type", default=[], 397 action=CheckPortType, nargs="+", 398 help=_("Show ports defined for this SELinux type")) 399 group.add_argument("-d", "--domain", dest="domain", default=[], 400 action=CheckDomain, nargs="+", 401 help=_("show ports to which this domain can bind and/or connect")) 402 group.add_argument("-a", "--application", dest="applications", default=[], 403 nargs="+", 404 help=_("show ports to which this application can bind and/or connect")) 405 net.set_defaults(func=network) 406 407 408def communicate(args): 409 from sepolicy.communicate import get_types 410 411 writable = get_types(args.source, args.tclass, args.sourceaccess.split(",")) 412 readable = get_types(args.target, args.tclass, args.targetaccess.split(",")) 413 out = list(set(writable) & set(readable)) 414 415 for t in out: 416 print t 417 418 419def gen_communicate_args(parser): 420 comm = parser.add_parser("communicate", 421 help=_('query SELinux policy to see if domains can communicate with each other')) 422 comm.add_argument("-s", "--source", dest="source", 423 action=CheckDomain, required=True, 424 help=_("Source Domain")) 425 comm.add_argument("-t", "--target", dest="target", 426 action=CheckDomain, required=True, 427 help=_("Target Domain")) 428 comm.add_argument("-c", "--class", required=False, dest="tclass", 429 action=CheckClass, 430 default="file", help="class to use for communications, Default 'file'") 431 comm.add_argument("-S", "--sourceaccess", required=False, dest="sourceaccess", default="open,write", help="comma separate list of permissions for the source type to use, Default 'open,write'") 432 comm.add_argument("-T", "--targetaccess", required=False, dest="targetaccess", default="open,read", help="comma separated list of permissions for the target type to use, Default 'open,read'") 433 comm.set_defaults(func=communicate) 434 435 436def booleans(args): 437 from sepolicy import boolean_desc 438 if args.all: 439 rc, args.booleans = selinux.security_get_boolean_names() 440 args.booleans.sort() 441 442 for b in args.booleans: 443 print "%s=_(\"%s\")" % (b, boolean_desc(b)) 444 445 446def gen_booleans_args(parser): 447 bools = parser.add_parser("booleans", 448 help=_('query SELinux Policy to see description of booleans')) 449 group = bools.add_mutually_exclusive_group(required=True) 450 group.add_argument("-a", "--all", dest="all", default=False, 451 action="store_true", 452 help=_("get all booleans descriptions")) 453 group.add_argument("-b", "--boolean", dest="booleans", nargs="+", 454 action=CheckBoolean, required=False, 455 help=_("boolean to get description")) 456 bools.set_defaults(func=booleans) 457 458 459def transition(args): 460 from sepolicy.transition import setrans 461 mytrans = setrans(args.source, args.target) 462 mytrans.output() 463 464 465def gen_transition_args(parser): 466 trans = parser.add_parser("transition", 467 help=_('query SELinux Policy to see how a source process domain can transition to the target process domain')) 468 trans.add_argument("-s", "--source", dest="source", 469 action=CheckDomain, required=True, 470 help=_("source process domain")) 471 trans.add_argument("-t", "--target", dest="target", 472 action=CheckDomain, 473 help=_("target process domain")) 474 trans.set_defaults(func=transition) 475 476 477def print_interfaces(interfaces, args, append=""): 478 from sepolicy.interface import get_interface_format_text, interface_compile_test 479 for i in interfaces: 480 if args.verbose: 481 try: 482 print get_interface_format_text(i + append) 483 except KeyError: 484 print i 485 if args.compile: 486 try: 487 interface_compile_test(i) 488 except KeyError: 489 print i 490 else: 491 print i 492 493 494def interface(args): 495 from sepolicy.interface import get_admin, get_user, get_interface_dict, get_all_interfaces 496 if args.list_admin: 497 print_interfaces(get_admin(args.file), args, "_admin") 498 if args.list_user: 499 print_interfaces(get_user(args.file), args, "_role") 500 if args.list: 501 print_interfaces(get_all_interfaces(args.file), args) 502 if args.interfaces: 503 print_interfaces(args.interfaces, args) 504 505 506def generate(args): 507 from sepolicy.generate import policy, AUSER, RUSER, EUSER, USERS, SANDBOX, APPLICATIONS, NEWTYPE 508 cmd = None 509# numbers present POLTYPE defined in sepolicy.generate 510 conflict_args = {'TYPES': (NEWTYPE,), 'DOMAIN': (EUSER,), 'ADMIN_DOMAIN': (AUSER, RUSER, EUSER,)} 511 error_text = "" 512 513 if args.policytype is None: 514 generate_usage = generate_custom_usage(usage, usage_dict) 515 for k in usage_dict: 516 error_text += "%s" % (k) 517 print(generate_usage) 518 print(_("sepolicy generate: error: one of the arguments %s is required") % error_text) 519 sys.exit(1) 520 521 if args.policytype in APPLICATIONS: 522 if not args.command: 523 raise ValueError(_("Command required for this type of policy")) 524 cmd = os.path.realpath(args.command) 525 if not args.name: 526 args.name = os.path.basename(cmd).replace("-", "_") 527 528 mypolicy = policy(args.name, args.policytype) 529 if cmd: 530 mypolicy.set_program(cmd) 531 532 if args.types: 533 if args.policytype not in conflict_args['TYPES']: 534 raise ValueError(_("-t option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype]) 535 mypolicy.set_types(args.types) 536 537 if args.domain: 538 if args.policytype not in conflict_args['DOMAIN']: 539 raise ValueError(_("-d option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype]) 540 541 if args.admin_domain: 542 if args.policytype not in conflict_args['ADMIN_DOMAIN']: 543 raise ValueError(_("-a option can not be used with '%s' domains. Read usage for more details.") % sepolicy.generate.poltype[args.policytype]) 544 545 if len(args.writepaths) > 0 and args.policytype == NEWTYPE: 546 547 raise ValueError(_("-w option can not be used with the --newtype option")) 548 549 for p in args.writepaths: 550 if os.path.isdir(p): 551 mypolicy.add_dir(p) 552 else: 553 mypolicy.add_file(p) 554 555 mypolicy.set_transition_users(args.user) 556 mypolicy.set_admin_roles(args.role) 557 mypolicy.set_admin_domains(args.admin_domain) 558 mypolicy.set_existing_domains(args.domain) 559 560 if args.policytype in APPLICATIONS: 561 mypolicy.gen_writeable() 562 mypolicy.gen_symbols() 563 print mypolicy.generate(args.path) 564 565 566def gen_interface_args(parser): 567 itf = parser.add_parser("interface", 568 help=_('List SELinux Policy interfaces')) 569 itf.add_argument("-c", "--compile", dest="compile", 570 action="store_true", default=False, 571 help="Run compile test for selected interface") 572 itf.add_argument("-v", "--verbose", dest="verbose", 573 action="store_true", default=False, 574 help="Show verbose information") 575 itf.add_argument("-f", "--file", dest="file", 576 help="Interface file") 577 group = itf.add_mutually_exclusive_group(required=True) 578 group.add_argument("-a", "--list_admin", dest="list_admin", action="store_true", default=False, 579 help="List all domains with admin interface - DOMAIN_admin()") 580 group.add_argument("-u", "--list_user", dest="list_user", action="store_true", 581 default=False, 582 help="List all domains with SELinux user role interface - DOMAIN_role()") 583 group.add_argument("-l", "--list", dest="list", action="store_true", 584 default=False, 585 help="List all interfaces") 586 group.add_argument("-i", "--interfaces", nargs="+", dest="interfaces", 587 action=InterfaceInfo, 588 help=_("Enter interface names, you wish to query")) 589 itf.set_defaults(func=interface) 590 591 592def gen_generate_args(parser): 593 from sepolicy.generate import DAEMON, get_poltype_desc, poltype, DAEMON, DBUS, INETD, CGI, SANDBOX, USER, EUSER, TUSER, XUSER, LUSER, AUSER, RUSER, NEWTYPE 594 595 generate_usage = generate_custom_usage(usage, usage_dict) 596 597 pol = parser.add_parser("generate", usage=generate_usage, 598 help=_('Generate SELinux Policy module template')) 599 pol.add_argument("-d", "--domain", dest="domain", default=[], 600 action=CheckDomain, nargs="*", 601 help=_("Enter domain type which you will be extending")) 602 pol.add_argument("-u", "--user", dest="user", default=[], 603 action=CheckUser, 604 help=_("Enter SELinux user(s) which will transition to this domain")) 605 pol.add_argument("-r", "--role", dest="role", default=[], 606 action=CheckRole, 607 help=_("Enter SELinux role(s) to which the administror domain will transition")) 608 pol.add_argument("-a", "--admin", dest="admin_domain", default=[], 609 action=CheckAdmin, 610 help=_("Enter domain(s) which this confined admin will administrate")) 611 pol.add_argument("-n", "--name", dest="name", 612 default=None, 613 help=_("name of policy to generate")) 614 pol.add_argument("-T", "--test", dest="test", default=False, action="store_true", 615 help=argparse.SUPPRESS) 616 pol.add_argument("-t", "--type", dest="types", default=[], nargs="*", 617 action=CheckType, 618 help="Enter type(s) for which you will generate new definition and rule(s)") 619 pol.add_argument("-p", "--path", dest="path", default=os.getcwd(), 620 help=_("path in which the generated policy files will be stored")) 621 pol.add_argument("-w", "--writepath", dest="writepaths", nargs="*", default=[], 622 help=_("path to which the confined processes will need to write")) 623 cmdtype = pol.add_argument_group(_("Policy types which require a command")) 624 cmdgroup = cmdtype.add_mutually_exclusive_group(required=False) 625 cmdgroup.add_argument("--application", dest="policytype", const=USER, 626 action="store_const", 627 help=_("Generate '%s' policy") % poltype[USER]) 628 cmdgroup.add_argument("--cgi", dest="policytype", const=CGI, 629 action="store_const", 630 help=_("Generate '%s' policy") % poltype[CGI]) 631 cmdgroup.add_argument("--dbus", dest="policytype", const=DBUS, 632 action="store_const", 633 help=_("Generate '%s' policy") % poltype[DBUS]) 634 cmdgroup.add_argument("--inetd", dest="policytype", const=INETD, 635 action="store_const", 636 help=_("Generate '%s' policy") % poltype[INETD]) 637 cmdgroup.add_argument("--init", dest="policytype", const=DAEMON, 638 action="store_const", default=DAEMON, 639 help=_("Generate '%s' policy") % poltype[DAEMON]) 640 641 type = pol.add_argument_group("Policy types which do not require a command") 642 group = type.add_mutually_exclusive_group(required=False) 643 group.add_argument("--admin_user", dest="policytype", const=AUSER, 644 action="store_const", 645 help=_("Generate '%s' policy") % poltype[AUSER]) 646 group.add_argument("--confined_admin", dest="policytype", const=RUSER, 647 action="store_const", 648 help=_("Generate '%s' policy") % poltype[RUSER]) 649 group.add_argument("--customize", dest="policytype", const=EUSER, 650 action="store_const", 651 help=_("Generate '%s' policy") % poltype[EUSER]) 652 group.add_argument("--desktop_user", dest="policytype", const=LUSER, 653 action="store_const", 654 help=_("Generate '%s' policy ") % poltype[LUSER]) 655 group.add_argument("--newtype", dest="policytype", const=NEWTYPE, 656 action="store_const", 657 help=_("Generate '%s' policy") % poltype[NEWTYPE]) 658 group.add_argument("--sandbox", dest="policytype", const=SANDBOX, 659 action="store_const", 660 help=_("Generate '%s' policy") % poltype[SANDBOX]) 661 group.add_argument("--term_user", dest="policytype", const=TUSER, 662 action="store_const", 663 help=_("Generate '%s' policy") % poltype[TUSER]) 664 group.add_argument("--x_user", dest="policytype", const=XUSER, 665 action="store_const", 666 help=_("Generate '%s' policy") % poltype[XUSER]) 667 pol.add_argument("command", nargs="?", default=None, 668 help=_("executable to confine")) 669 pol.set_defaults(func=generate) 670 671if __name__ == '__main__': 672 parser = argparse.ArgumentParser(description='SELinux Policy Inspection Tool') 673 subparsers = parser.add_subparsers(help=_("commands")) 674 parser.add_argument("-P", "--policy", dest="policy", 675 action=LoadPolicy, 676 default=None, help=_("Alternate SELinux policy, defaults to /sys/fs/selinux/policy")) 677 gen_booleans_args(subparsers) 678 gen_communicate_args(subparsers) 679 gen_generate_args(subparsers) 680 gen_gui_args(subparsers) 681 gen_interface_args(subparsers) 682 gen_manpage_args(subparsers) 683 gen_network_args(subparsers) 684 gen_transition_args(subparsers) 685 686 try: 687 if os.path.basename(sys.argv[0]) == "sepolgen": 688 parser_args = [ "generate" ] + sys.argv[1:] 689 elif len(sys.argv) > 1: 690 parser_args = sys.argv[1:] 691 else: 692 parser_args = ["-h"] 693 args = parser.parse_args(args=parser_args) 694 args.func(args) 695 sys.exit(0) 696 except ValueError, e: 697 sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) 698 sys.exit(1) 699 except IOError, e: 700 sys.stderr.write("%s: %s\n" % (e.__class__.__name__, str(e))) 701 sys.exit(1) 702 except KeyboardInterrupt: 703 print "Out" 704 sys.exit(0) 705