1#!/usr/bin/python 2 3# Author: Dan Walsh <dwalsh@redhat.com> 4# Author: Ryan Hallisey <rhallise@redhat.com> 5 6import _policy 7import selinux, glob 8PROGNAME="policycoreutils" 9import gettext 10import sepolgen.defaults as defaults 11import sepolgen.interfaces as interfaces 12import sys 13gettext.bindtextdomain(PROGNAME, "/usr/share/locale") 14gettext.textdomain(PROGNAME) 15try: 16 gettext.install(PROGNAME, 17 localedir="/usr/share/locale", 18 unicode=False, 19 codeset = 'utf-8') 20except IOError: 21 import __builtin__ 22 __builtin__.__dict__['_'] = unicode 23 24TYPE = _policy.TYPE 25ROLE = _policy.ROLE 26ATTRIBUTE = _policy.ATTRIBUTE 27PORT = _policy.PORT 28USER = _policy.USER 29BOOLEAN = _policy.BOOLEAN 30TCLASS = _policy.CLASS 31 32ALLOW = 'allow' 33AUDITALLOW = 'auditallow' 34NEVERALLOW = 'neverallow' 35DONTAUDIT = 'dontaudit' 36SOURCE = 'source' 37TARGET = 'target' 38PERMS = 'permlist' 39CLASS = 'class' 40TRANSITION = 'transition' 41ROLE_ALLOW = 'role_allow' 42 43def info(setype, name=None): 44 dict_list = _policy.info(setype, name) 45 return dict_list 46 47def search(types, info = {}): 48 seinfo = info 49 valid_types = [ALLOW, AUDITALLOW, NEVERALLOW, DONTAUDIT, TRANSITION, ROLE_ALLOW] 50 for setype in types: 51 if setype not in valid_types: 52 raise ValueError("Type has to be in %s" % valid_types) 53 seinfo[setype] = True 54 55 perms = [] 56 if PERMS in seinfo: 57 perms = info[PERMS] 58 seinfo[PERMS] = ",".join(seinfo[PERMS]) 59 60 dict_list = _policy.search(seinfo) 61 if dict_list and len(perms) != 0: 62 dict_list = filter(lambda x: _dict_has_perms(x, perms), dict_list) 63 return dict_list 64 65def get_conditionals(src,dest,tclass,perm): 66 tdict = {} 67 tlist = [] 68 if dest.endswith("_t"): 69 allows=search([ALLOW],{SOURCE:src,TARGET:dest,CLASS:tclass,PERMS:perm}) 70 else: 71 # to include attribute 72 allows=search([ALLOW],{SOURCE:src,CLASS:tclass,PERMS:perm}) 73 for i in allows: 74 if i['target'] == dest: 75 allows=[] 76 allows.append(i) 77 try: 78 for i in map(lambda y: (y), filter(lambda x: set(perm).issubset(x[PERMS]) and x['boolean'], allows)): 79 tdict.update({'source':i['source'],'boolean':i['boolean']}) 80 if tdict not in tlist: 81 tlist.append(tdict) 82 tdict={} 83 except KeyError: 84 return(tlist) 85 86 return (tlist) 87 88def get_conditionals_format_text(cond): 89 enabled = len(filter(lambda x: x['boolean'][0][1], cond)) > 0 90 return _("-- Allowed %s [ %s ]") % (enabled, " || ".join(set(map(lambda x: "%s=%d" % (x['boolean'][0][0], x['boolean'][0][1]), cond)))) 91 92def get_types_from_attribute(attribute): 93 return info(ATTRIBUTE,attribute)[0]["types"] 94 95file_type_str = {} 96file_type_str["a"] = _("all files") 97file_type_str["f"] = _("regular file") 98file_type_str["d"] = _("directory") 99file_type_str["c"] = _("character device") 100file_type_str["b"] = _("block device") 101file_type_str["s"] = _("socket file") 102file_type_str["l"] = _("symbolic link") 103file_type_str["p"] = _("named pipe") 104 105trans_file_type_str = {} 106trans_file_type_str[""] = "a" 107trans_file_type_str["--"] = "f" 108trans_file_type_str["-d"] = "d" 109trans_file_type_str["-c"] = "c" 110trans_file_type_str["-b"] = "b" 111trans_file_type_str["-s"] = "s" 112trans_file_type_str["-l"] = "l" 113trans_file_type_str["-p"] = "p" 114 115def get_file_types(setype): 116 flist=[] 117 mpaths={} 118 for f in get_all_file_types(): 119 if f.startswith(gen_short_name(setype)): 120 flist.append(f) 121 fcdict = get_fcdict() 122 for f in flist: 123 try: 124 mpaths[f] = (fcdict[f]["regex"], file_type_str[fcdict[f]["ftype"]]) 125 except KeyError: 126 mpaths[f] = [] 127 return mpaths 128 129def get_writable_files(setype): 130 all_attributes = get_all_attributes() 131 file_types = get_all_file_types() 132 all_writes = [] 133 mpaths = {} 134 permlist = search([ALLOW],{'source':setype, 'permlist':['open', 'write'], 'class':'file'}) 135 if permlist == None or len(permlist) == 0: 136 return mpaths 137 138 fcdict = get_fcdict() 139 140 attributes = ["proc_type", "sysctl_type"] 141 for i in permlist: 142 if i['target'] in attributes: 143 continue 144 if "enabled" in i: 145 if not i["enabled"]: 146 continue 147 if i['target'].endswith("_t"): 148 if i['target'] not in file_types: 149 continue 150 if i['target'] not in all_writes: 151 if i['target'] != setype: 152 all_writes.append(i['target']) 153 else: 154 for t in get_types_from_attribute(i['target']): 155 if t not in all_writes: 156 all_writes.append(t) 157 158 for f in all_writes: 159 try: 160 mpaths[f] = (fcdict[f]["regex"], file_type_str[fcdict[f]["ftype"]]) 161 except KeyError: 162 mpaths[f] = [] #{"regex":[],"paths":[]} 163 return mpaths 164 165import os, re, sys 166def find_file(reg): 167 if os.path.exists(reg): 168 return [ reg ] 169 try: 170 pat = re.compile(r"%s$" % reg) 171 except: 172 print "bad reg:", reg 173 return [] 174 p = reg 175 if p.endswith("(/.*)?"): 176 p = p[:-6] + "/" 177 178 path = os.path.dirname(p) 179 180 try: # Bug fix: when "all files on system" 181 if path[-1] != "/": # is pass in it breaks without try block 182 path += "/" 183 except IndexError: 184 print "try failed got an IndexError" 185 pass 186 187 try: 188 pat = re.compile(r"%s$" % reg) 189 return filter(pat.match, map(lambda x: path + x, os.listdir(path))) 190 except: 191 return [] 192 193def find_all_files(domain, exclude_list = []): 194 all_entrypoints = [] 195 executable_files = get_entrypoints(domain) 196 for exe in executable_files.keys(): 197 if exe.endswith("_exec_t") and exe not in exclude_list: 198 for path in executable_files[exe]: 199 for f in find_file(path): 200 return f 201 #all_entrypoints.append(f) 202 return None 203 204#return all_entrypoints 205def find_entrypoint_path(exe, exclude_list = []): 206 fcdict = get_fcdict() 207 try: 208 if exe.endswith("_exec_t") and exe not in exclude_list: 209 for path in fcdict[exe]["regex"]: 210 for f in find_file(path): 211 return f 212 except KeyError: 213 pass 214 return None 215 216def read_file_equiv(edict, fc_path, modify): 217 fd = open(fc_path, "r") 218 fc = fd.readlines() 219 fd.close() 220 for e in fc: 221 f = e.split() 222 edict[f[0]] = { "equiv" : f[1], "modify" : modify } 223 return edict 224 225file_equiv_modified=None 226def get_file_equiv_modified(fc_path = selinux.selinux_file_context_path()): 227 global file_equiv_modified 228 if file_equiv_modified: 229 return file_equiv_modified 230 file_equiv_modified = {} 231 file_equiv_modified = read_file_equiv(file_equiv_modified, fc_path + ".subs", modify=True) 232 return file_equiv_modified 233 234file_equiv=None 235def get_file_equiv(fc_path = selinux.selinux_file_context_path()): 236 global file_equiv 237 if file_equiv: 238 return file_equiv 239 file_equiv = get_file_equiv_modified(fc_path) 240 file_equiv = read_file_equiv(file_equiv, fc_path + ".subs_dist", modify = False) 241 return file_equiv 242 243local_files=None 244def get_local_file_paths(fc_path = selinux.selinux_file_context_path()): 245 global local_files 246 if local_files: 247 return local_files 248 local_files=[] 249 fd = open(fc_path+".local", "r") 250 fc = fd.readlines() 251 fd.close() 252 for i in fc: 253 rec = i.split() 254 if len(rec) == 0: 255 continue 256 try: 257 if len(rec) > 2: 258 ftype = trans_file_type_str[rec[1]] 259 else: 260 ftype = "a" 261 262 local_files.append((rec[0], ftype)) 263 except KeyError: 264 pass 265 return local_files 266 267fcdict=None 268def get_fcdict(fc_path = selinux.selinux_file_context_path()): 269 global fcdict 270 if fcdict: 271 return fcdict 272 fd = open(fc_path, "r") 273 fc = fd.readlines() 274 fd.close() 275 fd = open(fc_path+".homedirs", "r") 276 fc += fd.readlines() 277 fd.close() 278 fcdict = {} 279 fd = open(fc_path+".local", "r") 280 fc += fd.readlines() 281 fd.close() 282 283 for i in fc: 284 rec = i.split() 285 try: 286 if len(rec) > 2: 287 ftype = trans_file_type_str[rec[1]] 288 else: 289 ftype = "a" 290 291 t = rec[-1].split(":")[2] 292 if t in fcdict: 293 fcdict[t]["regex"].append(rec[0]) 294 else: 295 fcdict[t] = { "regex": [ rec[0] ], "ftype": ftype} 296 except: 297 pass 298 299 fcdict["logfile"] = { "regex" : [ "all log files" ]} 300 fcdict["user_tmp_type"] = { "regex" : [ "all user tmp files" ]} 301 fcdict["user_home_type"] = { "regex" : [ "all user home files" ]} 302 fcdict["virt_image_type"] = { "regex" : [ "all virtual image files" ]} 303 fcdict["noxattrfs"] = { "regex" : [ "all files on file systems which do not support extended attributes" ]} 304 fcdict["sandbox_tmpfs_type"] = { "regex" : [ "all sandbox content in tmpfs file systems" ]} 305 fcdict["user_tmpfs_type"] = { "regex" : [ "all user content in tmpfs file systems" ]} 306 fcdict["file_type"] = { "regex" : [ "all files on the system" ]} 307 fcdict["samba_share_t"] = { "regex" : [ "use this label for random content that will be shared using samba" ]} 308 return fcdict 309 310def get_transitions_into(setype): 311 try: 312 return filter(lambda x: x["transtype"] == setype, search([TRANSITION],{ 'class':'process'})) 313 except TypeError: 314 pass 315 return None 316 317def get_transitions(setype): 318 try: 319 return search([TRANSITION],{'source':setype, 'class':'process'}) 320 except TypeError: 321 pass 322 return None 323 324def get_file_transitions(setype): 325 try: 326 return filter(lambda x: x['class'] != "process", search([TRANSITION],{'source':setype})) 327 except TypeError: 328 pass 329 return None 330 331def get_boolean_rules(setype, boolean): 332 boollist = [] 333 permlist = search([ALLOW],{'source':setype }) 334 for p in permlist: 335 if "boolean" in p: 336 try: 337 for b in p["boolean"]: 338 if boolean in b: 339 boollist.append(p) 340 except: 341 pass 342 return boollist 343 344def get_all_entrypoints(): 345 return get_types_from_attribute("entry_type") 346 347def get_entrypoint_types(setype): 348 entrypoints = [] 349 try: 350 entrypoints = map(lambda x: x['target'],filter(lambda x: x['source'] == setype, search([ALLOW],{'source':setype, 'permlist':['entrypoint'], 'class':'file'}))) 351 except TypeError: 352 pass 353 return entrypoints 354 355def get_init_transtype(path): 356 entrypoint = selinux.getfilecon(path)[1].split(":")[2] 357 try: 358 entrypoints = filter(lambda x: x['target'] == entrypoint, search([TRANSITION],{'source':"init_t", 'class':'process'})) 359 if len(entrypoints) == 0: 360 return None 361 return entrypoints[0]["transtype"] 362 except TypeError: 363 pass 364 return None 365 366def get_init_entrypoint(transtype): 367 try: 368 entrypoints = filter(lambda x: x['transtype'] == transtype, search([TRANSITION],{'source':"init_t", 'class':'process'})) 369 if len(entrypoints) == 0: 370 return None 371 return entrypoints[0]["target"] 372 except TypeError: 373 pass 374 return None 375 376def get_init_entrypoint_target(entrypoint): 377 try: 378 entrypoints = map(lambda x: x['transtype'], search([TRANSITION],{'source':"init_t", 'target':entrypoint, 'class':'process'})) 379 return entrypoints[0] 380 except TypeError: 381 pass 382 return None 383 384def get_entrypoints(setype): 385 fcdict = get_fcdict() 386 mpaths = {} 387 for f in get_entrypoint_types(setype): 388 try: 389 mpaths[f] = (fcdict[f]["regex"], file_type_str[fcdict[f]["ftype"]]) 390 except KeyError: 391 mpaths[f] = [] 392 return mpaths 393 394def get_installed_policy(root = "/"): 395 try: 396 path = root + selinux.selinux_binary_policy_path() 397 policies = glob.glob ("%s.*" % path ) 398 policies.sort() 399 return policies[-1] 400 except: 401 pass 402 raise ValueError(_("No SELinux Policy installed")) 403 404methods = [] 405def get_methods(): 406 global methods 407 if len(methods) > 0: 408 return methods 409 gen_interfaces() 410 fn = defaults.interface_info() 411 try: 412 fd = open(fn) 413 # List of per_role_template interfaces 414 ifs = interfaces.InterfaceSet() 415 ifs.from_file(fd) 416 methods = ifs.interfaces.keys() 417 fd.close() 418 except: 419 sys.stderr.write("could not open interface info [%s]\n" % fn) 420 sys.exit(1) 421 422 methods.sort() 423 return methods 424 425all_types = None 426def get_all_types(): 427 global all_types 428 if all_types == None: 429 all_types = map(lambda x: x['name'], info(TYPE)) 430 return all_types 431 432user_types = None 433def get_user_types(): 434 global user_types 435 if user_types == None: 436 user_types = info(ATTRIBUTE,"userdomain")[0]["types"] 437 return user_types 438 439role_allows = None 440def get_all_role_allows(): 441 global role_allows 442 if role_allows: 443 return role_allows 444 role_allows = {} 445 for r in search([ROLE_ALLOW]): 446 if r["source"] == "system_r" or r["target"] == "system_r": 447 continue 448 if r["source"] in role_allows: 449 role_allows[r["source"]].append(r["target"]) 450 else: 451 role_allows[r["source"]] = [ r["target"] ] 452 453 return role_allows 454 455def get_all_entrypoint_domains(): 456 import re 457 all_domains = [] 458 types=get_all_types() 459 types.sort() 460 for i in types: 461 m = re.findall("(.*)%s" % "_exec_t$", i) 462 if len(m) > 0: 463 if len(re.findall("(.*)%s" % "_initrc$", m[0])) == 0 and m[0] not in all_domains: 464 all_domains.append(m[0]) 465 return all_domains 466 467portrecs = None 468portrecsbynum = None 469 470def gen_interfaces(): 471 import commands 472 ifile = defaults.interface_info() 473 headers = defaults.headers() 474 rebuild = False 475 try: 476 if os.stat(headers).st_mtime <= os.stat(ifile).st_mtime: 477 return 478 except OSError: 479 pass 480 481 if os.getuid() != 0: 482 raise ValueError(_("You must regenerate interface info by running /usr/bin/sepolgen-ifgen")) 483 print commands.getstatusoutput("/usr/bin/sepolgen-ifgen")[1] 484 485def gen_port_dict(): 486 global portrecs 487 global portrecsbynum 488 if portrecs: 489 return ( portrecs, portrecsbynum ) 490 portrecsbynum = {} 491 portrecs = {} 492 for i in info(PORT): 493 if i['low'] == i['high']: 494 port = str(i['low']) 495 else: 496 port = "%s-%s" % (str(i['low']), str(i['high'])) 497 498 if (i['type'], i['protocol']) in portrecs: 499 portrecs [(i['type'], i['protocol'])].append(port) 500 else: 501 portrecs [(i['type'], i['protocol'])] = [port] 502 503 if 'range' in i: 504 portrecsbynum[(i['low'], i['high'],i['protocol'])] = (i['type'], i['range']) 505 else: 506 portrecsbynum[(i['low'], i['high'],i['protocol'])] = (i['type']) 507 508 return ( portrecs, portrecsbynum ) 509 510all_domains = None 511def get_all_domains(): 512 global all_domains 513 if not all_domains: 514 all_domains = info(ATTRIBUTE,"domain")[0]["types"] 515 return all_domains 516 517roles = None 518def get_all_roles(): 519 global roles 520 if roles: 521 return roles 522 roles = map(lambda x: x['name'], info(ROLE)) 523 roles.remove("object_r") 524 roles.sort() 525 return roles 526 527selinux_user_list = None 528def get_selinux_users(): 529 global selinux_user_list 530 if not selinux_user_list: 531 selinux_user_list = info(USER) 532 for x in selinux_user_list: 533 x['range']="".join(x['range'].split(" ")) 534 return selinux_user_list 535 536login_mappings = None 537def get_login_mappings(): 538 global login_mappings 539 if login_mappings: 540 return login_mappings 541 542 fd = open(selinux.selinux_usersconf_path(), "r") 543 buf=fd.read() 544 fd.close() 545 login_mappings = [] 546 for b in buf.split("\n"): 547 b = b.strip() 548 if len(b) == 0 or b.startswith("#"): 549 continue 550 x = b.split(":") 551 login_mappings.append({ "name": x[0], "seuser": x[1], "mls":":".join(x[2:])}) 552 return login_mappings 553 554def get_all_users(): 555 users = map(lambda x: x['name'], get_selinux_users()) 556 users.sort() 557 return users 558 559file_types = None 560def get_all_file_types(): 561 global file_types 562 if file_types: 563 return file_types 564 file_types = info(ATTRIBUTE,"file_type")[0]["types"] 565 file_types.sort() 566 return file_types 567 568port_types = None 569def get_all_port_types(): 570 global port_types 571 if port_types: 572 return port_types 573 port_types = info(ATTRIBUTE,"port_type")[0]["types"] 574 port_types.sort() 575 return port_types 576 577bools = None 578def get_all_bools(): 579 global bools 580 if not bools: 581 bools = info(BOOLEAN) 582 return bools 583 584def prettyprint(f,trim): 585 return " ".join(f[:-len(trim)].split("_")) 586 587def markup(f): 588 return f 589 590# Autofill for adding files ************************* 591DEFAULT_DIRS = {} 592DEFAULT_DIRS["/etc"] = "etc_t" 593DEFAULT_DIRS["/tmp"] = "tmp_t" 594DEFAULT_DIRS["/usr/lib/systemd/system"] = "unit_file_t" 595DEFAULT_DIRS["/lib/systemd/system"] = "unit_file_t" 596DEFAULT_DIRS["/etc/systemd/system"] = "unit_file_t" 597DEFAULT_DIRS["/var/cache"] = "var_cache_t" 598DEFAULT_DIRS["/var/lib"] = "var_lib_t" 599DEFAULT_DIRS["/var/log"] = "log_t" 600DEFAULT_DIRS["/var/run"] = "var_run_t" 601DEFAULT_DIRS["/run"] = "var_run_t" 602DEFAULT_DIRS["/run/lock"] = "var_lock_t" 603DEFAULT_DIRS["/var/run/lock"] = "var_lock_t" 604DEFAULT_DIRS["/var/spool"] = "var_spool_t" 605DEFAULT_DIRS["/var/www"] = "content_t" 606 607def get_description(f, markup=markup): 608 609 txt = "Set files with the %s type, if you want to " % markup(f) 610 611 if f.endswith("_var_run_t"): 612 return txt + "store the %s files under the /run or /var/run directory." % prettyprint(f, "_var_run_t") 613 if f.endswith("_pid_t"): 614 return txt + "store the %s files under the /run directory." % prettyprint(f, "_pid_t") 615 if f.endswith("_var_lib_t"): 616 return txt + "store the %s files under the /var/lib directory." % prettyprint(f, "_var_lib_t") 617 if f.endswith("_var_t"): 618 return txt + "store the %s files under the /var directory." % prettyprint(f, "_var_lib_t") 619 if f.endswith("_var_spool_t"): 620 return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t") 621 if f.endswith("_spool_t"): 622 return txt + "store the %s files under the /var/spool directory." % prettyprint(f, "_spool_t") 623 if f.endswith("_cache_t") or f.endswith("_var_cache_t"): 624 return txt + "store the files under the /var/cache directory." 625 if f.endswith("_keytab_t"): 626 return txt + "treat the files as kerberos keytab files." 627 if f.endswith("_lock_t"): 628 return txt + "treat the files as %s lock data, stored under the /var/lock directory" % prettyprint(f,"_lock_t") 629 if f.endswith("_log_t"): 630 return txt + "treat the data as %s log data, usually stored under the /var/log directory." % prettyprint(f,"_log_t") 631 if f.endswith("_config_t"): 632 return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_config_t") 633 if f.endswith("_conf_t"): 634 return txt + "treat the files as %s configuration data, usually stored under the /etc directory." % prettyprint(f,"_conf_t") 635 if f.endswith("_exec_t"): 636 return txt + "transition an executable to the %s_t domain." % f[:-len("_exec_t")] 637 if f.endswith("_cgi_content_t"): 638 return txt + "treat the files as %s cgi content." % prettyprint(f, "_cgi_content_t") 639 if f.endswith("_rw_content_t"): 640 return txt + "treat the files as %s read/write content." % prettyprint(f,"_rw_content_t") 641 if f.endswith("_rw_t"): 642 return txt + "treat the files as %s read/write content." % prettyprint(f,"_rw_t") 643 if f.endswith("_write_t"): 644 return txt + "treat the files as %s read/write content." % prettyprint(f,"_write_t") 645 if f.endswith("_db_t"): 646 return txt + "treat the files as %s database content." % prettyprint(f,"_db_t") 647 if f.endswith("_ra_content_t"): 648 return txt + "treat the files as %s read/append content." % prettyprint(f,"_ra_conten_t") 649 if f.endswith("_cert_t"): 650 return txt + "treat the files as %s certificate data." % prettyprint(f,"_cert_t") 651 if f.endswith("_key_t"): 652 return txt + "treat the files as %s key data." % prettyprint(f,"_key_t") 653 654 if f.endswith("_secret_t"): 655 return txt + "treat the files as %s secret data." % prettyprint(f,"_key_t") 656 657 if f.endswith("_ra_t"): 658 return txt + "treat the files as %s read/append content." % prettyprint(f,"_ra_t") 659 660 if f.endswith("_ro_t"): 661 return txt + "treat the files as %s read/only content." % prettyprint(f,"_ro_t") 662 663 if f.endswith("_modules_t"): 664 return txt + "treat the files as %s modules." % prettyprint(f, "_modules_t") 665 666 if f.endswith("_content_t"): 667 return txt + "treat the files as %s content." % prettyprint(f, "_content_t") 668 669 if f.endswith("_state_t"): 670 return txt + "treat the files as %s state data." % prettyprint(f, "_state_t") 671 672 if f.endswith("_files_t"): 673 return txt + "treat the files as %s content." % prettyprint(f, "_files_t") 674 675 if f.endswith("_file_t"): 676 return txt + "treat the files as %s content." % prettyprint(f, "_file_t") 677 678 if f.endswith("_data_t"): 679 return txt + "treat the files as %s content." % prettyprint(f, "_data_t") 680 681 if f.endswith("_file_t"): 682 return txt + "treat the data as %s content." % prettyprint(f, "_file_t") 683 684 if f.endswith("_tmp_t"): 685 return txt + "store %s temporary files in the /tmp directories." % prettyprint(f, "_tmp_t") 686 if f.endswith("_etc_t"): 687 return txt + "store %s files in the /etc directories." % prettyprint(f, "_tmp_t") 688 if f.endswith("_home_t"): 689 return txt + "store %s files in the users home directory." % prettyprint(f, "_home_t") 690 if f.endswith("_tmpfs_t"): 691 return txt + "store %s files on a tmpfs file system." % prettyprint(f, "_tmpfs_t") 692 if f.endswith("_unit_file_t"): 693 return txt + "treat files as a systemd unit file." 694 if f.endswith("_htaccess_t"): 695 return txt + "treat the file as a %s access file." % prettyprint(f, "_htaccess_t") 696 697 return txt + "treat the files as %s data." % prettyprint(f,"_t") 698 699all_attributes = None 700def get_all_attributes(): 701 global all_attributes 702 if not all_attributes: 703 all_attributes = map(lambda x: x['name'], info(ATTRIBUTE)) 704 return all_attributes 705 706def policy(policy_file): 707 global all_domains 708 global all_attributes 709 global bools 710 global all_types 711 global role_allows 712 global users 713 global roles 714 global file_types 715 global port_types 716 all_domains = None 717 all_attributes = None 718 bools = None 719 all_types = None 720 role_allows = None 721 users = None 722 roles = None 723 file_types = None 724 port_types = None 725 try: 726 _policy.policy(policy_file) 727 except: 728 raise ValueError(_("Failed to read %s policy file") % policy_file) 729 730try: 731 policy_file = get_installed_policy() 732 policy(policy_file) 733except ValueError, e: 734 if selinux.is_selinux_enabled() == 1: 735 raise e 736 737def _dict_has_perms(dict, perms): 738 for perm in perms: 739 if perm not in dict[PERMS]: 740 return False 741 return True 742 743def gen_short_name(setype): 744 all_domains = get_all_domains() 745 if setype.endswith("_t"): 746 domainname = setype[:-2] 747 else: 748 domainname = setype 749 if domainname + "_t" not in all_domains: 750 raise ValueError("domain %s_t does not exist" % domainname) 751 if domainname[-1]=='d': 752 short_name = domainname[:-1] + "_" 753 else: 754 short_name = domainname + "_" 755 return (domainname, short_name) 756 757def get_bools(setype): 758 bools = [] 759 domainbools = [] 760 domainname, short_name = gen_short_name(setype) 761 for i in map(lambda x: x['boolean'], filter(lambda x: 'boolean' in x, search([ALLOW],{'source' : setype}))): 762 for b in i: 763 if not isinstance(b,tuple): 764 continue 765 try: 766 enabled = selinux.security_get_boolean_active(b[0]) 767 except OSError: 768 enabled = b[1] 769 if b[0].startswith(short_name) or b[0].startswith(domainname): 770 if (b[0], enabled) not in domainbools and (b[0], not enabled) not in domainbools: 771 domainbools.append((b[0], enabled)) 772 else: 773 if (b[0], enabled) not in bools and (b[0], not enabled) not in bools: 774 bools.append((b[0],enabled)) 775 return (domainbools, bools) 776 777booleans = None 778def get_all_booleans(): 779 global booleans 780 if not booleans: 781 booleans = selinux.security_get_boolean_names()[1] 782 return booleans 783 784booleans_dict = None 785import gzip 786def policy_xml(path="/usr/share/selinux/devel/policy.xml"): 787 try: 788 fd = gzip.open(path) 789 buf = fd.read() 790 fd.close() 791 except IOError: 792 fd = open(path) 793 buf = fd.read() 794 fd.close() 795 return buf 796 797def gen_bool_dict(path="/usr/share/selinux/devel/policy.xml"): 798 global booleans_dict 799 if booleans_dict: 800 return booleans_dict 801 import xml.etree.ElementTree 802 import re 803 booleans_dict = {} 804 try: 805 tree = xml.etree.ElementTree.fromstring(policy_xml(path)) 806 for l in tree.findall("layer"): 807 for m in l.findall("module"): 808 for b in m.findall("tunable"): 809 desc = b.find("desc").find("p").text.strip("\n") 810 desc = re.sub("\n", " ", desc) 811 booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc) 812 for b in m.findall("bool"): 813 desc = b.find("desc").find("p").text.strip("\n") 814 desc = re.sub("\n", " ", desc) 815 booleans_dict[b.get('name')] = (m.get("name"), b.get('dftval'), desc) 816 for i in tree.findall("bool"): 817 desc = i.find("desc").find("p").text.strip("\n") 818 desc = re.sub("\n", " ", desc) 819 booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc) 820 for i in tree.findall("tunable"): 821 desc = i.find("desc").find("p").text.strip("\n") 822 desc = re.sub("\n", " ", desc) 823 booleans_dict[i.get('name')] = ("global", i.get('dftval'), desc) 824 except IOError, e: 825 pass 826 return booleans_dict 827 828def boolean_category(boolean): 829 booleans_dict = gen_bool_dict() 830 if boolean in booleans_dict: 831 return _(booleans_dict[boolean][0]) 832 else: 833 return _("unknown") 834 835def boolean_desc(boolean): 836 booleans_dict = gen_bool_dict() 837 if boolean in booleans_dict: 838 return _(booleans_dict[boolean][2]) 839 else: 840 desc = boolean.split("_") 841 return "Allow %s to %s" % (desc[0], " ".join(desc[1:])) 842 843def get_os_version(): 844 os_version = "" 845 pkg_name = "selinux-policy" 846 try: 847 import commands 848 rc, output = commands.getstatusoutput("rpm -q '%s'" % pkg_name) 849 if rc == 0: 850 os_version = output.split(".")[-2] 851 except: 852 os_version = "" 853 854 if os_version[0:2] == "fc": 855 os_version = "Fedora"+os_version[2:] 856 elif os_version[0:2] == "el": 857 os_version = "RHEL"+os_version[2:] 858 else: 859 os_version = "" 860 861 return os_version 862 863def reinit(): 864 global all_attributes 865 global all_domains 866 global all_types 867 global booleans 868 global booleans_dict 869 global bools 870 global fcdict 871 global file_types 872 global local_files 873 global methods 874 global methods 875 global portrecs 876 global portrecsbynum 877 global port_types 878 global role_allows 879 global roles 880 global login_mappings 881 global selinux_user_list 882 global user_types 883 all_attributes = None 884 all_domains = None 885 all_types = None 886 booleans = None 887 booleans_dict = None 888 bools = None 889 fcdict = None 890 file_types = None 891 local_files=None 892 methods = None 893 methods = None 894 portrecs = None 895 portrecsbynum = None 896 port_types = None 897 role_allows = None 898 roles = None 899 user_types = None 900 login_mappings = None 901 selinux_user_list = None 902