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