1# Copyright (C) 2005-2013 Red Hat
2# see file 'COPYING' for use and warranty information
3#
4# semanage is a tool for managing SELinux configuration files
5#
6#    This program is free software; you can redistribute it and/or
7#    modify it under the terms of the GNU General Public License as
8#    published by the Free Software Foundation; either version 2 of
9#    the License, or (at your option) any later version.
10#
11#    This program is distributed in the hope that it will be useful,
12#    but WITHOUT ANY WARRANTY; without even the implied warranty of
13#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14#    GNU General Public License for more details.
15#
16#    You should have received a copy of the GNU General Public License
17#    along with this program; if not, write to the Free Software
18#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19#                                        02111-1307  USA
20#
21#
22
23import pwd
24import grp
25import selinux
26import os
27import re
28import sys
29import stat
30import socket
31from semanage import *
32PROGNAME = "policycoreutils"
33import sepolicy
34import setools
35from IPy import IP
36
37try:
38    import gettext
39    kwargs = {}
40    if sys.version_info < (3,):
41        kwargs['unicode'] = True
42    gettext.install(PROGNAME,
43                    localedir="/usr/share/locale",
44                    codeset='utf-8',
45                    **kwargs)
46except:
47    try:
48        import builtins
49        builtins.__dict__['_'] = str
50    except ImportError:
51        import __builtin__
52        __builtin__.__dict__['_'] = unicode
53
54import syslog
55
56file_types = {}
57file_types[""] = SEMANAGE_FCONTEXT_ALL
58file_types["all files"] = SEMANAGE_FCONTEXT_ALL
59file_types["a"] = SEMANAGE_FCONTEXT_ALL
60file_types["regular file"] = SEMANAGE_FCONTEXT_REG
61file_types["--"] = SEMANAGE_FCONTEXT_REG
62file_types["f"] = SEMANAGE_FCONTEXT_REG
63file_types["-d"] = SEMANAGE_FCONTEXT_DIR
64file_types["directory"] = SEMANAGE_FCONTEXT_DIR
65file_types["d"] = SEMANAGE_FCONTEXT_DIR
66file_types["-c"] = SEMANAGE_FCONTEXT_CHAR
67file_types["character device"] = SEMANAGE_FCONTEXT_CHAR
68file_types["c"] = SEMANAGE_FCONTEXT_CHAR
69file_types["-b"] = SEMANAGE_FCONTEXT_BLOCK
70file_types["block device"] = SEMANAGE_FCONTEXT_BLOCK
71file_types["b"] = SEMANAGE_FCONTEXT_BLOCK
72file_types["-s"] = SEMANAGE_FCONTEXT_SOCK
73file_types["socket"] = SEMANAGE_FCONTEXT_SOCK
74file_types["s"] = SEMANAGE_FCONTEXT_SOCK
75file_types["-l"] = SEMANAGE_FCONTEXT_LINK
76file_types["l"] = SEMANAGE_FCONTEXT_LINK
77file_types["symbolic link"] = SEMANAGE_FCONTEXT_LINK
78file_types["p"] = SEMANAGE_FCONTEXT_PIPE
79file_types["-p"] = SEMANAGE_FCONTEXT_PIPE
80file_types["named pipe"] = SEMANAGE_FCONTEXT_PIPE
81
82file_type_str_to_option = {"all files": "a",
83                           "regular file": "f",
84                           "directory": "d",
85                           "character device": "c",
86                           "block device": "b",
87                           "socket": "s",
88                           "symbolic link": "l",
89                           "named pipe": "p"}
90
91ftype_to_audit = {"": "any",
92                  "a" : "any",
93                  "b": "block",
94                  "c": "char",
95                  "d": "dir",
96                  "f": "file",
97                  "l": "symlink",
98                  "p": "pipe",
99                  "s": "socket"}
100
101try:
102    import audit
103    #test if audit module is enabled
104    audit.audit_close(audit.audit_open())
105
106    class logger:
107
108        def __init__(self):
109            self.audit_fd = audit.audit_open()
110            self.log_list = []
111            self.log_change_list = []
112
113        def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
114
115            sep = "-"
116            if sename != oldsename:
117                msg += sep + "sename"
118                sep = ","
119            if serole != oldserole:
120                msg += sep + "role"
121                sep = ","
122            if serange != oldserange:
123                msg += sep + "range"
124                sep = ","
125
126            self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_ASSIGN, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
127
128        def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
129            self.log_list.append([self.audit_fd, audit.AUDIT_ROLE_REMOVE, sys.argv[0], str(msg), name, 0, sename, serole, serange, oldsename, oldserole, oldserange, "", "", ""])
130
131        def log_change(self, msg):
132            self.log_change_list.append([self.audit_fd, audit.AUDIT_USER_MAC_CONFIG_CHANGE, str(msg), "semanage", "", "", ""])
133
134        def commit(self, success):
135            for l in self.log_list:
136                audit.audit_log_semanage_message(*(l + [success]))
137            for l in self.log_change_list:
138                audit.audit_log_user_comm_message(*(l + [success]))
139
140            self.log_list = []
141            self.log_change_list = []
142except (OSError, ImportError):
143    class logger:
144
145        def __init__(self):
146            self.log_list = []
147
148        def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
149            message = " %s name=%s" % (msg, name)
150            if sename != "":
151                message += " sename=" + sename
152            if oldsename != "":
153                message += " oldsename=" + oldsename
154            if serole != "":
155                message += " role=" + serole
156            if oldserole != "":
157                message += " old_role=" + oldserole
158            if serange != "" and serange is not None:
159                message += " MLSRange=" + serange
160            if oldserange != "" and oldserange is not None:
161                message += " old_MLSRange=" + oldserange
162            self.log_list.append(message)
163
164        def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
165            self.log(msg, name, sename, serole, serange, oldsename, oldserole, oldserange)
166
167        def log_change(self, msg):
168            self.log_list.append(" %s" % msg)
169
170        def commit(self, success):
171            if success == 1:
172                message = "Successful: "
173            else:
174                message = "Failed: "
175            for l in self.log_list:
176                syslog.syslog(syslog.LOG_INFO, message + l)
177
178
179class nulllogger:
180
181    def log(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
182        pass
183
184    def log_remove(self, msg, name="", sename="", serole="", serange="", oldsename="", oldserole="", oldserange=""):
185        pass
186
187    def log_change(self, msg):
188        pass
189
190    def commit(self, success):
191        pass
192
193
194def validate_level(raw):
195    sensitivity = "s[0-9]*"
196    category = "c[0-9]*"
197    cat_range = category + r"(\." + category + ")?"
198    categories = cat_range + r"(\," + cat_range + ")*"
199    reg = sensitivity + "(-" + sensitivity + ")?" + "(:" + categories + ")?"
200    return re.search("^" + reg + "$", raw)
201
202
203def translate(raw, prepend=1):
204    filler = "a:b:c:"
205    if prepend == 1:
206        context = "%s%s" % (filler, raw)
207    else:
208        context = raw
209    (rc, trans) = selinux.selinux_raw_to_trans_context(context)
210    if rc != 0:
211        return raw
212    if prepend:
213        trans = trans[len(filler):]
214    if trans == "":
215        return raw
216    else:
217        return trans
218
219
220def untranslate(trans, prepend=1):
221    filler = "a:b:c:"
222    if prepend == 1:
223        context = "%s%s" % (filler, trans)
224    else:
225        context = trans
226
227    (rc, raw) = selinux.selinux_trans_to_raw_context(context)
228    if rc != 0:
229        return trans
230    if prepend:
231        raw = raw[len(filler):]
232    if raw == "":
233        return trans
234    else:
235        return raw
236
237
238class semanageRecords:
239    transaction = False
240    handle = None
241    store = None
242    args = None
243
244    def __init__(self, args = None):
245        global handle
246        if args:
247            # legacy code - args was store originally
248            if type(args) == str:
249                self.store = args
250            else:
251                self.args = args
252        self.noreload = getattr(args, "noreload", False)
253        if not self.store:
254            self.store = getattr(args, "store", "")
255
256        self.sh = self.get_handle(self.store)
257
258        rc, localstore = selinux.selinux_getpolicytype()
259        if self.store == "" or self.store == localstore:
260            self.mylog = logger()
261        else:
262            sepolicy.load_store_policy(self.store)
263            selinux.selinux_set_policy_root("%s%s" % (selinux.selinux_path(), self.store))
264            self.mylog = nulllogger()
265
266    def set_reload(self, load):
267        self.noreload = not load
268
269    def get_handle(self, store):
270        global is_mls_enabled
271
272        if semanageRecords.handle:
273            return semanageRecords.handle
274
275        handle = semanage_handle_create()
276        if not handle:
277            raise ValueError(_("Could not create semanage handle"))
278
279        if not semanageRecords.transaction and store != "":
280            semanage_select_store(handle, store, SEMANAGE_CON_DIRECT)
281            semanageRecords.store = store
282
283        if not semanage_is_managed(handle):
284            semanage_handle_destroy(handle)
285            raise ValueError(_("SELinux policy is not managed or store cannot be accessed."))
286
287        rc = semanage_access_check(handle)
288        if rc < SEMANAGE_CAN_READ:
289            semanage_handle_destroy(handle)
290            raise ValueError(_("Cannot read policy store."))
291
292        rc = semanage_connect(handle)
293        if rc < 0:
294            semanage_handle_destroy(handle)
295            raise ValueError(_("Could not establish semanage connection"))
296
297        is_mls_enabled = semanage_mls_enabled(handle)
298        if is_mls_enabled < 0:
299            semanage_handle_destroy(handle)
300            raise ValueError(_("Could not test MLS enabled status"))
301
302        semanageRecords.handle = handle
303        return semanageRecords.handle
304
305    def deleteall(self):
306        raise ValueError(_("Not yet implemented"))
307
308    def start(self):
309        if semanageRecords.transaction:
310            raise ValueError(_("Semanage transaction already in progress"))
311        self.begin()
312        semanageRecords.transaction = True
313
314    def begin(self):
315        if semanageRecords.transaction:
316            return
317        rc = semanage_begin_transaction(self.sh)
318        if rc < 0:
319            raise ValueError(_("Could not start semanage transaction"))
320
321    def customized(self):
322        raise ValueError(_("Not yet implemented"))
323
324    def commit(self):
325        if semanageRecords.transaction:
326            return
327
328        if self.noreload:
329            semanage_set_reload(self.sh, 0)
330        rc = semanage_commit(self.sh)
331        if rc < 0:
332            self.mylog.commit(0)
333            raise ValueError(_("Could not commit semanage transaction"))
334        self.mylog.commit(1)
335
336    def finish(self):
337        if not semanageRecords.transaction:
338            raise ValueError(_("Semanage transaction not in progress"))
339        semanageRecords.transaction = False
340        self.commit()
341
342
343class moduleRecords(semanageRecords):
344
345    def __init__(self, args = None):
346        semanageRecords.__init__(self, args)
347
348    def get_all(self):
349        l = []
350        (rc, mlist, number) = semanage_module_list_all(self.sh)
351        if rc < 0:
352            raise ValueError(_("Could not list SELinux modules"))
353
354        for i in range(number):
355            mod = semanage_module_list_nth(mlist, i)
356
357            rc, name = semanage_module_info_get_name(self.sh, mod)
358            if rc < 0:
359                raise ValueError(_("Could not get module name"))
360
361            rc, enabled = semanage_module_info_get_enabled(self.sh, mod)
362            if rc < 0:
363                raise ValueError(_("Could not get module enabled"))
364
365            rc, priority = semanage_module_info_get_priority(self.sh, mod)
366            if rc < 0:
367                raise ValueError(_("Could not get module priority"))
368
369            rc, lang_ext = semanage_module_info_get_lang_ext(self.sh, mod)
370            if rc < 0:
371                raise ValueError(_("Could not get module lang_ext"))
372
373            l.append((name, enabled, priority, lang_ext))
374
375        # sort the list so they are in name order, but with higher priorities coming first
376        l.sort(key=lambda t: t[3], reverse=True)
377        l.sort(key=lambda t: t[0])
378        return l
379
380    def customized(self):
381        all = self.get_all()
382        if len(all) == 0:
383            return []
384        return ["-d %s" % x[0] for x in [t for t in all if t[1] == 0]]
385
386    def list(self, heading=1, locallist=0):
387        all = self.get_all()
388        if len(all) == 0:
389            return
390
391        if heading:
392            print("\n%-25s %-9s %s\n" % (_("Module Name"), _("Priority"), _("Language")))
393        for t in all:
394            if t[1] == 0:
395                disabled = _("Disabled")
396            else:
397                if locallist:
398                    continue
399                disabled = ""
400            print("%-25s %-9s %-5s %s" % (t[0], t[2], t[3], disabled))
401
402    def add(self, file, priority):
403        if not os.path.exists(file):
404            raise ValueError(_("Module does not exist: %s ") % file)
405
406        rc = semanage_set_default_priority(self.sh, priority)
407        if rc < 0:
408            raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
409
410        rc = semanage_module_install_file(self.sh, file)
411        if rc >= 0:
412            self.commit()
413
414    def set_enabled(self, module, enable):
415        for m in module.split():
416            rc, key = semanage_module_key_create(self.sh)
417            if rc < 0:
418                raise ValueError(_("Could not create module key"))
419
420            rc = semanage_module_key_set_name(self.sh, key, m)
421            if rc < 0:
422                raise ValueError(_("Could not set module key name"))
423
424            rc = semanage_module_set_enabled(self.sh, key, enable)
425            if rc < 0:
426                if enable:
427                    raise ValueError(_("Could not enable module %s") % m)
428                else:
429                    raise ValueError(_("Could not disable module %s") % m)
430        self.commit()
431
432    def delete(self, module, priority):
433        rc = semanage_set_default_priority(self.sh, priority)
434        if rc < 0:
435            raise ValueError(_("Invalid priority %d (needs to be between 1 and 999)") % priority)
436
437        for m in module.split():
438            rc = semanage_module_remove(self.sh, m)
439            if rc < 0 and rc != -2:
440                raise ValueError(_("Could not remove module %s (remove failed)") % m)
441
442        self.commit()
443
444    def deleteall(self):
445        l = [x[0] for x in [t for t in self.get_all() if t[1] == 0]]
446        for m in l:
447            self.set_enabled(m, True)
448
449
450class dontauditClass(semanageRecords):
451
452    def __init__(self, args = None):
453        semanageRecords.__init__(self, args)
454
455    def toggle(self, dontaudit):
456        if dontaudit not in ["on", "off"]:
457            raise ValueError(_("dontaudit requires either 'on' or 'off'"))
458        self.begin()
459        semanage_set_disable_dontaudit(self.sh, dontaudit == "off")
460        self.commit()
461
462
463class permissiveRecords(semanageRecords):
464
465    def __init__(self, args = None):
466        semanageRecords.__init__(self, args)
467
468    def get_all(self):
469        l = []
470        (rc, mlist, number) = semanage_module_list(self.sh)
471        if rc < 0:
472            raise ValueError(_("Could not list SELinux modules"))
473
474        for i in range(number):
475            mod = semanage_module_list_nth(mlist, i)
476            name = semanage_module_get_name(mod)
477            if name and name.startswith("permissive_"):
478                l.append(name.split("permissive_")[1])
479        return l
480
481    def customized(self):
482        return ["-a %s" % x for x in sorted(self.get_all())]
483
484    def list(self, heading=1, locallist=0):
485        all = [y["name"] for y in [x for x in sepolicy.info(sepolicy.TYPE) if x["permissive"]]]
486        if len(all) == 0:
487            return
488
489        if heading:
490            print("\n%-25s\n" % (_("Builtin Permissive Types")))
491        customized = self.get_all()
492        for t in all:
493            if t not in customized:
494                print(t)
495
496        if len(customized) == 0:
497            return
498
499        if heading:
500            print("\n%-25s\n" % (_("Customized Permissive Types")))
501        for t in customized:
502            print(t)
503
504    def add(self, type):
505        try:
506            import sepolgen.module as module
507        except ImportError:
508            raise ValueError(_("The sepolgen python module is required to setup permissive domains.\nIn some distributions it is included in the policycoreutils-devel package.\n# yum install policycoreutils-devel\nOr similar for your distro."))
509
510        name = "permissive_%s" % type
511        modtxt = "(typepermissive %s)" % type
512
513        rc = semanage_module_install(self.sh, modtxt, len(modtxt), name, "cil")
514        if rc >= 0:
515            self.commit()
516
517        if rc < 0:
518            raise ValueError(_("Could not set permissive domain %s (module installation failed)") % name)
519
520    def delete(self, name):
521        for n in name.split():
522            rc = semanage_module_remove(self.sh, "permissive_%s" % n)
523            if rc < 0:
524                raise ValueError(_("Could not remove permissive domain %s (remove failed)") % name)
525
526        self.commit()
527
528    def deleteall(self):
529        l = self.get_all()
530        if len(l) > 0:
531            all = " ".join(l)
532            self.delete(all)
533
534
535class loginRecords(semanageRecords):
536
537    def __init__(self, args = None):
538        semanageRecords.__init__(self, args)
539        self.oldsename = None
540        self.oldserange = None
541        self.sename = None
542        self.serange = None
543
544    def __add(self, name, sename, serange):
545        rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
546        if sename == "":
547            sename = "user_u"
548
549        userrec = seluserRecords(self.args)
550        range, (rc, oldserole) = userrec.get(self.oldsename)
551        range, (rc, serole) = userrec.get(sename)
552
553        if is_mls_enabled == 1:
554            if serange != "":
555                serange = untranslate(serange)
556            else:
557                serange = range
558
559        (rc, k) = semanage_seuser_key_create(self.sh, name)
560        if rc < 0:
561            raise ValueError(_("Could not create a key for %s") % name)
562
563        (rc, exists) = semanage_seuser_exists(self.sh, k)
564        if rc < 0:
565            raise ValueError(_("Could not check if login mapping for %s is defined") % name)
566        if exists:
567            raise ValueError(_("Login mapping for %s is already defined") % name)
568        if name[0] == '%':
569            try:
570                grp.getgrnam(name[1:])
571            except:
572                raise ValueError(_("Linux Group %s does not exist") % name[1:])
573        else:
574            try:
575                pwd.getpwnam(name)
576            except:
577                raise ValueError(_("Linux User %s does not exist") % name)
578
579        (rc, u) = semanage_seuser_create(self.sh)
580        if rc < 0:
581            raise ValueError(_("Could not create login mapping for %s") % name)
582
583        rc = semanage_seuser_set_name(self.sh, u, name)
584        if rc < 0:
585            raise ValueError(_("Could not set name for %s") % name)
586
587        if (is_mls_enabled == 1) and (serange != ""):
588            rc = semanage_seuser_set_mlsrange(self.sh, u, serange)
589            if rc < 0:
590                raise ValueError(_("Could not set MLS range for %s") % name)
591
592        rc = semanage_seuser_set_sename(self.sh, u, sename)
593        if rc < 0:
594            raise ValueError(_("Could not set SELinux user for %s") % name)
595
596        rc = semanage_seuser_modify_local(self.sh, k, u)
597        if rc < 0:
598            raise ValueError(_("Could not add login mapping for %s") % name)
599
600        semanage_seuser_key_free(k)
601        semanage_seuser_free(u)
602
603    def add(self, name, sename, serange):
604        try:
605            self.begin()
606            self.__add(name, sename, serange)
607            self.commit()
608        except ValueError as error:
609            raise error
610
611    def __modify(self, name, sename="", serange=""):
612        rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
613        if sename == "" and serange == "":
614            raise ValueError(_("Requires seuser or serange"))
615
616        userrec = seluserRecords(self.args)
617        range, (rc, oldserole) = userrec.get(self.oldsename)
618
619        if sename != "":
620            range, (rc, serole) = userrec.get(sename)
621        else:
622            serole = oldserole
623
624        if serange != "":
625            self.serange = serange
626        else:
627            self.serange = range
628
629        (rc, k) = semanage_seuser_key_create(self.sh, name)
630        if rc < 0:
631            raise ValueError(_("Could not create a key for %s") % name)
632
633        (rc, exists) = semanage_seuser_exists(self.sh, k)
634        if rc < 0:
635            raise ValueError(_("Could not check if login mapping for %s is defined") % name)
636        if not exists:
637            raise ValueError(_("Login mapping for %s is not defined") % name)
638
639        (rc, u) = semanage_seuser_query(self.sh, k)
640        if rc < 0:
641            raise ValueError(_("Could not query seuser for %s") % name)
642
643        self.oldserange = semanage_seuser_get_mlsrange(u)
644        self.oldsename = semanage_seuser_get_sename(u)
645        if (is_mls_enabled == 1) and (serange != ""):
646            semanage_seuser_set_mlsrange(self.sh, u, untranslate(serange))
647
648        if sename != "":
649            semanage_seuser_set_sename(self.sh, u, sename)
650            self.sename = sename
651        else:
652            self.sename = self.oldsename
653
654        rc = semanage_seuser_modify_local(self.sh, k, u)
655        if rc < 0:
656            raise ValueError(_("Could not modify login mapping for %s") % name)
657
658        semanage_seuser_key_free(k)
659        semanage_seuser_free(u)
660
661    def modify(self, name, sename="", serange=""):
662        try:
663            self.begin()
664            self.__modify(name, sename, serange)
665            self.commit()
666        except ValueError as error:
667            raise error
668
669    def __delete(self, name):
670        rec, self.oldsename, self.oldserange = selinux.getseuserbyname(name)
671        userrec = seluserRecords(self.args)
672        range, (rc, oldserole) = userrec.get(self.oldsename)
673
674        (rc, k) = semanage_seuser_key_create(self.sh, name)
675        if rc < 0:
676            raise ValueError(_("Could not create a key for %s") % name)
677
678        (rc, exists) = semanage_seuser_exists(self.sh, k)
679        if rc < 0:
680            raise ValueError(_("Could not check if login mapping for %s is defined") % name)
681        if not exists:
682            raise ValueError(_("Login mapping for %s is not defined") % name)
683
684        (rc, exists) = semanage_seuser_exists_local(self.sh, k)
685        if rc < 0:
686            raise ValueError(_("Could not check if login mapping for %s is defined") % name)
687        if not exists:
688            raise ValueError(_("Login mapping for %s is defined in policy, cannot be deleted") % name)
689
690        rc = semanage_seuser_del_local(self.sh, k)
691        if rc < 0:
692            raise ValueError(_("Could not delete login mapping for %s") % name)
693
694        semanage_seuser_key_free(k)
695
696        rec, self.sename, self.serange = selinux.getseuserbyname("__default__")
697        range, (rc, serole) = userrec.get(self.sename)
698
699    def delete(self, name):
700        try:
701            self.begin()
702            self.__delete(name)
703            self.commit()
704
705        except ValueError as error:
706            raise error
707
708    def deleteall(self):
709        (rc, ulist) = semanage_seuser_list_local(self.sh)
710        if rc < 0:
711            raise ValueError(_("Could not list login mappings"))
712
713        try:
714            self.begin()
715            for u in ulist:
716                self.__delete(semanage_seuser_get_name(u))
717            self.commit()
718        except ValueError as error:
719            raise error
720
721    def get_all_logins(self):
722        ddict = {}
723        self.logins_path = selinux.selinux_policy_root() + "/logins"
724        for path, dirs, files in os.walk(self.logins_path):
725            if path == self.logins_path:
726                for name in files:
727                    try:
728                        fd = open(path + "/" + name)
729                        rec = fd.read().rstrip().split(":")
730                        fd.close()
731                        ddict[name] = (rec[1], rec[2], rec[0])
732                    except IndexError:
733                        pass
734        return ddict
735
736    def get_all(self, locallist=0):
737        ddict = {}
738        if locallist:
739            (rc, self.ulist) = semanage_seuser_list_local(self.sh)
740        else:
741            (rc, self.ulist) = semanage_seuser_list(self.sh)
742        if rc < 0:
743            raise ValueError(_("Could not list login mappings"))
744
745        for u in self.ulist:
746            name = semanage_seuser_get_name(u)
747            ddict[name] = (semanage_seuser_get_sename(u), semanage_seuser_get_mlsrange(u), "*")
748        return ddict
749
750    def customized(self):
751        l = []
752        ddict = self.get_all(True)
753        for k in sorted(ddict.keys()):
754            if ddict[k][1]:
755                l.append("-a -s %s -r '%s' %s" % (ddict[k][0], ddict[k][1], k))
756            else:
757                l.append("-a -s %s %s" % (ddict[k][0], k))
758        return l
759
760    def list(self, heading=1, locallist=0):
761        ddict = self.get_all(locallist)
762        ldict = self.get_all_logins()
763        lkeys = sorted(ldict.keys())
764        keys = sorted(ddict.keys())
765        if len(keys) == 0 and len(lkeys) == 0:
766            return
767
768        if is_mls_enabled == 1:
769            if heading:
770                print("\n%-20s %-20s %-20s %s\n" % (_("Login Name"), _("SELinux User"), _("MLS/MCS Range"), _("Service")))
771            for k in keys:
772                u = ddict[k]
773                print("%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2]))
774            if len(lkeys):
775                print("\nLocal customization in %s" % self.logins_path)
776
777            for k in lkeys:
778                u = ldict[k]
779                print("%-20s %-20s %-20s %s" % (k, u[0], translate(u[1]), u[2]))
780        else:
781            if heading:
782                print("\n%-25s %-25s\n" % (_("Login Name"), _("SELinux User")))
783            for k in keys:
784                print("%-25s %-25s" % (k, ddict[k][0]))
785
786
787class seluserRecords(semanageRecords):
788
789    def __init__(self, args = None):
790        semanageRecords.__init__(self, args)
791
792    def get(self, name):
793        (rc, k) = semanage_user_key_create(self.sh, name)
794        if rc < 0:
795            raise ValueError(_("Could not create a key for %s") % name)
796        (rc, exists) = semanage_user_exists(self.sh, k)
797        if rc < 0:
798            raise ValueError(_("Could not check if SELinux user %s is defined") % name)
799        (rc, u) = semanage_user_query(self.sh, k)
800        if rc < 0:
801            raise ValueError(_("Could not query user for %s") % name)
802        serange = semanage_user_get_mlsrange(u)
803        serole = semanage_user_get_roles(self.sh, u)
804        semanage_user_key_free(k)
805        semanage_user_free(u)
806        return serange, serole
807
808    def __add(self, name, roles, selevel, serange, prefix):
809        if is_mls_enabled == 1:
810            if serange == "":
811                serange = "s0"
812            else:
813                serange = untranslate(serange)
814
815            if selevel == "":
816                selevel = "s0"
817            else:
818                selevel = untranslate(selevel)
819
820        if len(roles) < 1:
821            raise ValueError(_("You must add at least one role for %s") % name)
822
823        (rc, k) = semanage_user_key_create(self.sh, name)
824        if rc < 0:
825            raise ValueError(_("Could not create a key for %s") % name)
826
827        (rc, exists) = semanage_user_exists(self.sh, k)
828        if rc < 0:
829            raise ValueError(_("Could not check if SELinux user %s is defined") % name)
830        if exists:
831            raise ValueError(_("SELinux user %s is already defined") % name)
832
833        (rc, u) = semanage_user_create(self.sh)
834        if rc < 0:
835            raise ValueError(_("Could not create SELinux user for %s") % name)
836
837        rc = semanage_user_set_name(self.sh, u, name)
838        if rc < 0:
839            raise ValueError(_("Could not set name for %s") % name)
840
841        for r in roles:
842            rc = semanage_user_add_role(self.sh, u, r)
843            if rc < 0:
844                raise ValueError(_("Could not add role %s for %s") % (r, name))
845
846        if is_mls_enabled == 1:
847            rc = semanage_user_set_mlsrange(self.sh, u, serange)
848            if rc < 0:
849                raise ValueError(_("Could not set MLS range for %s") % name)
850
851            rc = semanage_user_set_mlslevel(self.sh, u, selevel)
852            if rc < 0:
853                raise ValueError(_("Could not set MLS level for %s") % name)
854        rc = semanage_user_set_prefix(self.sh, u, prefix)
855        if rc < 0:
856            raise ValueError(_("Could not add prefix %s for %s") % (r, prefix))
857        (rc, key) = semanage_user_key_extract(self.sh, u)
858        if rc < 0:
859            raise ValueError(_("Could not extract key for %s") % name)
860
861        rc = semanage_user_modify_local(self.sh, k, u)
862        if rc < 0:
863            raise ValueError(_("Could not add SELinux user %s") % name)
864
865        semanage_user_key_free(k)
866        semanage_user_free(u)
867        self.mylog.log("seuser", sename=name, serole=",".join(roles), serange=serange)
868
869    def add(self, name, roles, selevel, serange, prefix):
870        try:
871            self.begin()
872            self.__add(name, roles, selevel, serange, prefix)
873            self.commit()
874        except ValueError as error:
875            self.mylog.commit(0)
876            raise error
877
878    def __modify(self, name, roles=[], selevel="", serange="", prefix=""):
879        oldserole = ""
880        oldserange = ""
881        newroles = " ".join(roles)
882        if prefix == "" and len(roles) == 0 and serange == "" and selevel == "":
883            if is_mls_enabled == 1:
884                raise ValueError(_("Requires prefix, roles, level or range"))
885            else:
886                raise ValueError(_("Requires prefix or roles"))
887
888        (rc, k) = semanage_user_key_create(self.sh, name)
889        if rc < 0:
890            raise ValueError(_("Could not create a key for %s") % name)
891
892        (rc, exists) = semanage_user_exists(self.sh, k)
893        if rc < 0:
894            raise ValueError(_("Could not check if SELinux user %s is defined") % name)
895        if not exists:
896            raise ValueError(_("SELinux user %s is not defined") % name)
897
898        (rc, u) = semanage_user_query(self.sh, k)
899        if rc < 0:
900            raise ValueError(_("Could not query user for %s") % name)
901
902        oldserange = semanage_user_get_mlsrange(u)
903        (rc, rlist) = semanage_user_get_roles(self.sh, u)
904        if rc >= 0:
905            oldserole = " ".join(rlist)
906
907        if (is_mls_enabled == 1) and (serange != ""):
908            semanage_user_set_mlsrange(self.sh, u, untranslate(serange))
909        if (is_mls_enabled == 1) and (selevel != ""):
910            semanage_user_set_mlslevel(self.sh, u, untranslate(selevel))
911
912        if prefix != "":
913            semanage_user_set_prefix(self.sh, u, prefix)
914
915        if len(roles) != 0:
916            for r in rlist:
917                if r not in roles:
918                    semanage_user_del_role(u, r)
919            for r in roles:
920                if r not in rlist:
921                    semanage_user_add_role(self.sh, u, r)
922
923        rc = semanage_user_modify_local(self.sh, k, u)
924        if rc < 0:
925            raise ValueError(_("Could not modify SELinux user %s") % name)
926
927        semanage_user_key_free(k)
928        semanage_user_free(u)
929
930        role = ",".join(newroles.split())
931        oldserole = ",".join(oldserole.split())
932        self.mylog.log("seuser", sename=name, oldsename=name, serole=role, serange=serange, oldserole=oldserole, oldserange=oldserange)
933
934    def modify(self, name, roles=[], selevel="", serange="", prefix=""):
935        try:
936            self.begin()
937            self.__modify(name, roles, selevel, serange, prefix)
938            self.commit()
939        except ValueError as error:
940            self.mylog.commit(0)
941            raise error
942
943    def __delete(self, name):
944        (rc, k) = semanage_user_key_create(self.sh, name)
945        if rc < 0:
946            raise ValueError(_("Could not create a key for %s") % name)
947
948        (rc, exists) = semanage_user_exists(self.sh, k)
949        if rc < 0:
950            raise ValueError(_("Could not check if SELinux user %s is defined") % name)
951        if not exists:
952            raise ValueError(_("SELinux user %s is not defined") % name)
953
954        (rc, exists) = semanage_user_exists_local(self.sh, k)
955        if rc < 0:
956            raise ValueError(_("Could not check if SELinux user %s is defined") % name)
957        if not exists:
958            raise ValueError(_("SELinux user %s is defined in policy, cannot be deleted") % name)
959
960        (rc, u) = semanage_user_query(self.sh, k)
961        if rc < 0:
962            raise ValueError(_("Could not query user for %s") % name)
963        oldserange = semanage_user_get_mlsrange(u)
964        (rc, rlist) = semanage_user_get_roles(self.sh, u)
965        oldserole = ",".join(rlist)
966
967        rc = semanage_user_del_local(self.sh, k)
968        if rc < 0:
969            raise ValueError(_("Could not delete SELinux user %s") % name)
970
971        semanage_user_key_free(k)
972        semanage_user_free(u)
973
974        self.mylog.log_remove("seuser", oldsename=name, oldserange=oldserange, oldserole=oldserole)
975
976    def delete(self, name):
977        try:
978            self.begin()
979            self.__delete(name)
980            self.commit()
981
982        except ValueError as error:
983            self.mylog.commit(0)
984            raise error
985
986    def deleteall(self):
987        (rc, ulist) = semanage_user_list_local(self.sh)
988        if rc < 0:
989            raise ValueError(_("Could not list login mappings"))
990
991        try:
992            self.begin()
993            for u in ulist:
994                self.__delete(semanage_user_get_name(u))
995            self.commit()
996        except ValueError as error:
997            self.mylog.commit(0)
998            raise error
999
1000    def get_all(self, locallist=0):
1001        ddict = {}
1002        if locallist:
1003            (rc, self.ulist) = semanage_user_list_local(self.sh)
1004        else:
1005            (rc, self.ulist) = semanage_user_list(self.sh)
1006        if rc < 0:
1007            raise ValueError(_("Could not list SELinux users"))
1008
1009        for u in self.ulist:
1010            name = semanage_user_get_name(u)
1011            (rc, rlist) = semanage_user_get_roles(self.sh, u)
1012            if rc < 0:
1013                raise ValueError(_("Could not list roles for user %s") % name)
1014
1015            roles = " ".join(rlist)
1016            ddict[semanage_user_get_name(u)] = (semanage_user_get_prefix(u), semanage_user_get_mlslevel(u), semanage_user_get_mlsrange(u), roles)
1017
1018        return ddict
1019
1020    def customized(self):
1021        l = []
1022        ddict = self.get_all(True)
1023        for k in sorted(ddict.keys()):
1024            if ddict[k][1] or ddict[k][2]:
1025                l.append("-a -L %s -r %s -R '%s' %s" % (ddict[k][1], ddict[k][2], ddict[k][3], k))
1026            else:
1027                l.append("-a -R '%s' %s" % (ddict[k][3], k))
1028        return l
1029
1030    def list(self, heading=1, locallist=0):
1031        ddict = self.get_all(locallist)
1032        if len(ddict) == 0:
1033            return
1034        keys = sorted(ddict.keys())
1035
1036        if is_mls_enabled == 1:
1037            if heading:
1038                print("\n%-15s %-10s %-10s %-30s" % ("", _("Labeling"), _("MLS/"), _("MLS/")))
1039                print("%-15s %-10s %-10s %-30s %s\n" % (_("SELinux User"), _("Prefix"), _("MCS Level"), _("MCS Range"), _("SELinux Roles")))
1040            for k in keys:
1041                print("%-15s %-10s %-10s %-30s %s" % (k, ddict[k][0], translate(ddict[k][1]), translate(ddict[k][2]), ddict[k][3]))
1042        else:
1043            if heading:
1044                print("%-15s %s\n" % (_("SELinux User"), _("SELinux Roles")))
1045            for k in keys:
1046                print("%-15s %s" % (k, ddict[k][3]))
1047
1048
1049class portRecords(semanageRecords):
1050
1051    valid_types = []
1052
1053    def __init__(self, args = None):
1054        semanageRecords.__init__(self, args)
1055        try:
1056            self.valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "port_type"))[0]["types"])
1057        except RuntimeError:
1058            pass
1059
1060    def __genkey(self, port, proto):
1061        protocols = {"tcp": SEMANAGE_PROTO_TCP,
1062                     "udp": SEMANAGE_PROTO_UDP,
1063                     "sctp": SEMANAGE_PROTO_SCTP,
1064                     "dccp": SEMANAGE_PROTO_DCCP}
1065
1066        if proto in protocols.keys():
1067            proto_d = protocols[proto]
1068        else:
1069            raise ValueError(_("Protocol has to be one of udp, tcp, dccp or sctp"))
1070        if port == "":
1071            raise ValueError(_("Port is required"))
1072
1073        if isinstance(port, str):
1074            ports = port.split('-', 1)
1075        else:
1076            ports = (port,)
1077
1078        if len(ports) == 1:
1079            high = low = int(ports[0])
1080        else:
1081            low = int(ports[0])
1082            high = int(ports[1])
1083
1084        if high > 65535:
1085            raise ValueError(_("Invalid Port"))
1086
1087        (rc, k) = semanage_port_key_create(self.sh, low, high, proto_d)
1088        if rc < 0:
1089            raise ValueError(_("Could not create a key for %s/%s") % (proto, port))
1090        return (k, proto_d, low, high)
1091
1092    def __add(self, port, proto, serange, type):
1093        if is_mls_enabled == 1:
1094            if serange == "":
1095                serange = "s0"
1096            else:
1097                serange = untranslate(serange)
1098
1099        if type == "":
1100            raise ValueError(_("Type is required"))
1101
1102        type = sepolicy.get_real_type_name(type)
1103
1104        if type not in self.valid_types:
1105            raise ValueError(_("Type %s is invalid, must be a port type") % type)
1106
1107        (k, proto_d, low, high) = self.__genkey(port, proto)
1108
1109        (rc, exists) = semanage_port_exists(self.sh, k)
1110        if rc < 0:
1111            raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
1112        if exists:
1113            raise ValueError(_("Port %s/%s already defined") % (proto, port))
1114
1115        (rc, p) = semanage_port_create(self.sh)
1116        if rc < 0:
1117            raise ValueError(_("Could not create port for %s/%s") % (proto, port))
1118
1119        semanage_port_set_proto(p, proto_d)
1120        semanage_port_set_range(p, low, high)
1121        (rc, con) = semanage_context_create(self.sh)
1122        if rc < 0:
1123            raise ValueError(_("Could not create context for %s/%s") % (proto, port))
1124
1125        rc = semanage_context_set_user(self.sh, con, "system_u")
1126        if rc < 0:
1127            raise ValueError(_("Could not set user in port context for %s/%s") % (proto, port))
1128
1129        rc = semanage_context_set_role(self.sh, con, "object_r")
1130        if rc < 0:
1131            raise ValueError(_("Could not set role in port context for %s/%s") % (proto, port))
1132
1133        rc = semanage_context_set_type(self.sh, con, type)
1134        if rc < 0:
1135            raise ValueError(_("Could not set type in port context for %s/%s") % (proto, port))
1136
1137        if (is_mls_enabled == 1) and (serange != ""):
1138            rc = semanage_context_set_mls(self.sh, con, serange)
1139            if rc < 0:
1140                raise ValueError(_("Could not set mls fields in port context for %s/%s") % (proto, port))
1141
1142        rc = semanage_port_set_con(self.sh, p, con)
1143        if rc < 0:
1144            raise ValueError(_("Could not set port context for %s/%s") % (proto, port))
1145
1146        rc = semanage_port_modify_local(self.sh, k, p)
1147        if rc < 0:
1148            raise ValueError(_("Could not add port %s/%s") % (proto, port))
1149
1150        semanage_context_free(con)
1151        semanage_port_key_free(k)
1152        semanage_port_free(p)
1153
1154        self.mylog.log_change("resrc=port op=add lport=%s proto=%s tcontext=%s:%s:%s:%s" % (port, socket.getprotobyname(proto), "system_u", "object_r", type, serange))
1155
1156    def add(self, port, proto, serange, type):
1157        self.begin()
1158        self.__add(port, proto, serange, type)
1159        self.commit()
1160
1161    def __modify(self, port, proto, serange, setype):
1162        if serange == "" and setype == "":
1163            if is_mls_enabled == 1:
1164                raise ValueError(_("Requires setype or serange"))
1165            else:
1166                raise ValueError(_("Requires setype"))
1167
1168        setype = sepolicy.get_real_type_name(setype)
1169        if setype and setype not in self.valid_types:
1170            raise ValueError(_("Type %s is invalid, must be a port type") % setype)
1171
1172        (k, proto_d, low, high) = self.__genkey(port, proto)
1173
1174        (rc, exists) = semanage_port_exists(self.sh, k)
1175        if rc < 0:
1176            raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
1177        if not exists:
1178            raise ValueError(_("Port %s/%s is not defined") % (proto, port))
1179
1180        (rc, p) = semanage_port_query(self.sh, k)
1181        if rc < 0:
1182            raise ValueError(_("Could not query port %s/%s") % (proto, port))
1183
1184        con = semanage_port_get_con(p)
1185
1186        if is_mls_enabled == 1:
1187            if serange == "":
1188                serange = "s0"
1189            else:
1190                semanage_context_set_mls(self.sh, con, untranslate(serange))
1191        if setype != "":
1192            semanage_context_set_type(self.sh, con, setype)
1193
1194        rc = semanage_port_modify_local(self.sh, k, p)
1195        if rc < 0:
1196            raise ValueError(_("Could not modify port %s/%s") % (proto, port))
1197
1198        semanage_port_key_free(k)
1199        semanage_port_free(p)
1200
1201        self.mylog.log_change("resrc=port op=modify lport=%s proto=%s tcontext=%s:%s:%s:%s" % (port, socket.getprotobyname(proto), "system_u", "object_r", setype, serange))
1202
1203    def modify(self, port, proto, serange, setype):
1204        self.begin()
1205        self.__modify(port, proto, serange, setype)
1206        self.commit()
1207
1208    def deleteall(self):
1209        (rc, plist) = semanage_port_list_local(self.sh)
1210        if rc < 0:
1211            raise ValueError(_("Could not list the ports"))
1212
1213        self.begin()
1214
1215        for port in plist:
1216            proto = semanage_port_get_proto(port)
1217            proto_str = semanage_port_get_proto_str(proto)
1218            low = semanage_port_get_low(port)
1219            high = semanage_port_get_high(port)
1220            port_str = "%s-%s" % (low, high)
1221
1222            (k, proto_d, low, high) = self.__genkey(port_str, proto_str)
1223            if rc < 0:
1224                raise ValueError(_("Could not create a key for %s") % port_str)
1225
1226            rc = semanage_port_del_local(self.sh, k)
1227            if rc < 0:
1228                raise ValueError(_("Could not delete the port %s") % port_str)
1229            semanage_port_key_free(k)
1230
1231            if low == high:
1232                port_str = low
1233
1234            self.mylog.log_change("resrc=port op=delete lport=%s proto=%s" % (port_str, socket.getprotobyname(proto_str)))
1235
1236        self.commit()
1237
1238    def __delete(self, port, proto):
1239        (k, proto_d, low, high) = self.__genkey(port, proto)
1240        (rc, exists) = semanage_port_exists(self.sh, k)
1241        if rc < 0:
1242            raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
1243        if not exists:
1244            raise ValueError(_("Port %s/%s is not defined") % (proto, port))
1245
1246        (rc, exists) = semanage_port_exists_local(self.sh, k)
1247        if rc < 0:
1248            raise ValueError(_("Could not check if port %s/%s is defined") % (proto, port))
1249        if not exists:
1250            raise ValueError(_("Port %s/%s is defined in policy, cannot be deleted") % (proto, port))
1251
1252        rc = semanage_port_del_local(self.sh, k)
1253        if rc < 0:
1254            raise ValueError(_("Could not delete port %s/%s") % (proto, port))
1255
1256        semanage_port_key_free(k)
1257
1258        self.mylog.log_change("resrc=port op=delete lport=%s proto=%s" % (port, socket.getprotobyname(proto)))
1259
1260    def delete(self, port, proto):
1261        self.begin()
1262        self.__delete(port, proto)
1263        self.commit()
1264
1265    def get_all(self, locallist=0):
1266        ddict = {}
1267        if locallist:
1268            (rc, self.plist) = semanage_port_list_local(self.sh)
1269        else:
1270            (rc, self.plist) = semanage_port_list(self.sh)
1271        if rc < 0:
1272            raise ValueError(_("Could not list ports"))
1273
1274        for port in self.plist:
1275            con = semanage_port_get_con(port)
1276            ctype = semanage_context_get_type(con)
1277            level = semanage_context_get_mls(con)
1278            proto = semanage_port_get_proto(port)
1279            proto_str = semanage_port_get_proto_str(proto)
1280            low = semanage_port_get_low(port)
1281            high = semanage_port_get_high(port)
1282            ddict[(low, high, proto_str)] = (ctype, level)
1283        return ddict
1284
1285    def get_all_by_type(self, locallist=0):
1286        ddict = {}
1287        if locallist:
1288            (rc, self.plist) = semanage_port_list_local(self.sh)
1289        else:
1290            (rc, self.plist) = semanage_port_list(self.sh)
1291        if rc < 0:
1292            raise ValueError(_("Could not list ports"))
1293
1294        for port in self.plist:
1295            con = semanage_port_get_con(port)
1296            ctype = semanage_context_get_type(con)
1297            proto = semanage_port_get_proto(port)
1298            proto_str = semanage_port_get_proto_str(proto)
1299            low = semanage_port_get_low(port)
1300            high = semanage_port_get_high(port)
1301            if (ctype, proto_str) not in ddict.keys():
1302                ddict[(ctype, proto_str)] = []
1303            if low == high:
1304                ddict[(ctype, proto_str)].append("%d" % low)
1305            else:
1306                ddict[(ctype, proto_str)].append("%d-%d" % (low, high))
1307        return ddict
1308
1309    def customized(self):
1310        l = []
1311        ddict = self.get_all(True)
1312        for k in sorted(ddict.keys()):
1313            port = k[0] if k[0] == k[1] else "%s-%s" % (k[0], k[1])
1314            if ddict[k][1]:
1315                l.append("-a -t %s -r '%s' -p %s %s" % (ddict[k][0], ddict[k][1], k[2], port))
1316            else:
1317                l.append("-a -t %s -p %s %s" % (ddict[k][0], k[2], port))
1318        return l
1319
1320    def list(self, heading=1, locallist=0):
1321        ddict = self.get_all_by_type(locallist)
1322        if len(ddict) == 0:
1323            return
1324        keys = sorted(ddict.keys())
1325
1326        if heading:
1327            print("%-30s %-8s %s\n" % (_("SELinux Port Type"), _("Proto"), _("Port Number")))
1328        for i in keys:
1329            rec = "%-30s %-8s " % i
1330            rec += "%s" % ddict[i][0]
1331            for p in ddict[i][1:]:
1332                rec += ", %s" % p
1333            print(rec)
1334
1335class ibpkeyRecords(semanageRecords):
1336
1337    valid_types = []
1338
1339    def __init__(self, args = None):
1340        semanageRecords.__init__(self, args)
1341        try:
1342            q = setools.TypeQuery(setools.SELinuxPolicy(sepolicy.get_store_policy(self.store)), attrs=["ibpkey_type"])
1343            self.valid_types = sorted(str(t) for t in q.results())
1344        except:
1345            pass
1346
1347    def __genkey(self, pkey, subnet_prefix):
1348        if subnet_prefix == "":
1349            raise ValueError(_("Subnet Prefix is required"))
1350
1351        pkeys = pkey.split("-")
1352        if len(pkeys) == 1:
1353            high = low = int(pkeys[0], 0)
1354        else:
1355            low = int(pkeys[0], 0)
1356            high = int(pkeys[1], 0)
1357
1358        if high > 65535:
1359            raise ValueError(_("Invalid Pkey"))
1360
1361        (rc, k) = semanage_ibpkey_key_create(self.sh, subnet_prefix, low, high)
1362        if rc < 0:
1363            raise ValueError(_("Could not create a key for %s/%s") % (subnet_prefix, pkey))
1364        return (k, subnet_prefix, low, high)
1365
1366    def __add(self, pkey, subnet_prefix, serange, type):
1367        if is_mls_enabled == 1:
1368            if serange == "":
1369                serange = "s0"
1370            else:
1371                serange = untranslate(serange)
1372
1373        if type == "":
1374            raise ValueError(_("Type is required"))
1375
1376        type = sepolicy.get_real_type_name(type)
1377
1378        if type not in self.valid_types:
1379            raise ValueError(_("Type %s is invalid, must be a ibpkey type") % type)
1380
1381        (k, subnet_prefix, low, high) = self.__genkey(pkey, subnet_prefix)
1382
1383        (rc, exists) = semanage_ibpkey_exists(self.sh, k)
1384        if rc < 0:
1385            raise ValueError(_("Could not check if ibpkey %s/%s is defined") % (subnet_prefix, pkey))
1386        if exists:
1387            raise ValueError(_("ibpkey %s/%s already defined") % (subnet_prefix, pkey))
1388
1389        (rc, p) = semanage_ibpkey_create(self.sh)
1390        if rc < 0:
1391            raise ValueError(_("Could not create ibpkey for %s/%s") % (subnet_prefix, pkey))
1392
1393        semanage_ibpkey_set_subnet_prefix(self.sh, p, subnet_prefix)
1394        semanage_ibpkey_set_range(p, low, high)
1395        (rc, con) = semanage_context_create(self.sh)
1396        if rc < 0:
1397            raise ValueError(_("Could not create context for %s/%s") % (subnet_prefix, pkey))
1398
1399        rc = semanage_context_set_user(self.sh, con, "system_u")
1400        if rc < 0:
1401            raise ValueError(_("Could not set user in ibpkey context for %s/%s") % (subnet_prefix, pkey))
1402
1403        rc = semanage_context_set_role(self.sh, con, "object_r")
1404        if rc < 0:
1405            raise ValueError(_("Could not set role in ibpkey context for %s/%s") % (subnet_prefix, pkey))
1406
1407        rc = semanage_context_set_type(self.sh, con, type)
1408        if rc < 0:
1409            raise ValueError(_("Could not set type in ibpkey context for %s/%s") % (subnet_prefix, pkey))
1410
1411        if (is_mls_enabled == 1) and (serange != ""):
1412            rc = semanage_context_set_mls(self.sh, con, serange)
1413            if rc < 0:
1414                raise ValueError(_("Could not set mls fields in ibpkey context for %s/%s") % (subnet_prefix, pkey))
1415
1416        rc = semanage_ibpkey_set_con(self.sh, p, con)
1417        if rc < 0:
1418            raise ValueError(_("Could not set ibpkey context for %s/%s") % (subnet_prefix, pkey))
1419
1420        rc = semanage_ibpkey_modify_local(self.sh, k, p)
1421        if rc < 0:
1422            raise ValueError(_("Could not add ibpkey %s/%s") % (subnet_prefix, pkey))
1423
1424        semanage_context_free(con)
1425        semanage_ibpkey_key_free(k)
1426        semanage_ibpkey_free(p)
1427
1428    def add(self, pkey, subnet_prefix, serange, type):
1429        self.begin()
1430        self.__add(pkey, subnet_prefix, serange, type)
1431        self.commit()
1432
1433    def __modify(self, pkey, subnet_prefix, serange, setype):
1434        if serange == "" and setype == "":
1435            if is_mls_enabled == 1:
1436                raise ValueError(_("Requires setype or serange"))
1437            else:
1438                raise ValueError(_("Requires setype"))
1439
1440        setype = sepolicy.get_real_type_name(setype)
1441
1442        if setype and setype not in self.valid_types:
1443            raise ValueError(_("Type %s is invalid, must be a ibpkey type") % setype)
1444
1445        (k, subnet_prefix, low, high) = self.__genkey(pkey, subnet_prefix)
1446
1447        (rc, exists) = semanage_ibpkey_exists(self.sh, k)
1448        if rc < 0:
1449            raise ValueError(_("Could not check if ibpkey %s/%s is defined") % (subnet_prefix, pkey))
1450        if not exists:
1451            raise ValueError(_("ibpkey %s/%s is not defined") % (subnet_prefix, pkey))
1452
1453        (rc, p) = semanage_ibpkey_query(self.sh, k)
1454        if rc < 0:
1455            raise ValueError(_("Could not query ibpkey %s/%s") % (subnet_prefix, pkey))
1456
1457        con = semanage_ibpkey_get_con(p)
1458
1459        if (is_mls_enabled == 1) and (serange != ""):
1460            semanage_context_set_mls(self.sh, con, untranslate(serange))
1461        if setype != "":
1462            semanage_context_set_type(self.sh, con, setype)
1463
1464        rc = semanage_ibpkey_modify_local(self.sh, k, p)
1465        if rc < 0:
1466            raise ValueError(_("Could not modify ibpkey %s/%s") % (subnet_prefix, pkey))
1467
1468        semanage_ibpkey_key_free(k)
1469        semanage_ibpkey_free(p)
1470
1471    def modify(self, pkey, subnet_prefix, serange, setype):
1472        self.begin()
1473        self.__modify(pkey, subnet_prefix, serange, setype)
1474        self.commit()
1475
1476    def deleteall(self):
1477        (rc, plist) = semanage_ibpkey_list_local(self.sh)
1478        if rc < 0:
1479            raise ValueError(_("Could not list the ibpkeys"))
1480
1481        self.begin()
1482
1483        for ibpkey in plist:
1484            (rc, subnet_prefix) = semanage_ibpkey_get_subnet_prefix(self.sh, ibpkey)
1485            low = semanage_ibpkey_get_low(ibpkey)
1486            high = semanage_ibpkey_get_high(ibpkey)
1487            pkey_str = "%s-%s" % (low, high)
1488            (k, subnet_prefix, low, high) = self.__genkey(pkey_str, subnet_prefix)
1489            if rc < 0:
1490                raise ValueError(_("Could not create a key for %s") % pkey_str)
1491
1492            rc = semanage_ibpkey_del_local(self.sh, k)
1493            if rc < 0:
1494                raise ValueError(_("Could not delete the ibpkey %s") % pkey_str)
1495            semanage_ibpkey_key_free(k)
1496
1497        self.commit()
1498
1499    def __delete(self, pkey, subnet_prefix):
1500        (k, subnet_prefix, low, high) = self.__genkey(pkey, subnet_prefix)
1501        (rc, exists) = semanage_ibpkey_exists(self.sh, k)
1502        if rc < 0:
1503            raise ValueError(_("Could not check if ibpkey %s/%s is defined") % (subnet_prefix, pkey))
1504        if not exists:
1505            raise ValueError(_("ibpkey %s/%s is not defined") % (subnet_prefix, pkey))
1506
1507        (rc, exists) = semanage_ibpkey_exists_local(self.sh, k)
1508        if rc < 0:
1509            raise ValueError(_("Could not check if ibpkey %s/%s is defined") % (subnet_prefix, pkey))
1510        if not exists:
1511            raise ValueError(_("ibpkey %s/%s is defined in policy, cannot be deleted") % (subnet_prefix, pkey))
1512
1513        rc = semanage_ibpkey_del_local(self.sh, k)
1514        if rc < 0:
1515            raise ValueError(_("Could not delete ibpkey %s/%s") % (subnet_prefix, pkey))
1516
1517        semanage_ibpkey_key_free(k)
1518
1519    def delete(self, pkey, subnet_prefix):
1520        self.begin()
1521        self.__delete(pkey, subnet_prefix)
1522        self.commit()
1523
1524    def get_all(self, locallist=0):
1525        ddict = {}
1526        if locallist:
1527            (rc, self.plist) = semanage_ibpkey_list_local(self.sh)
1528        else:
1529            (rc, self.plist) = semanage_ibpkey_list(self.sh)
1530        if rc < 0:
1531            raise ValueError(_("Could not list ibpkeys"))
1532
1533        for ibpkey in self.plist:
1534            con = semanage_ibpkey_get_con(ibpkey)
1535            ctype = semanage_context_get_type(con)
1536            if ctype == "reserved_ibpkey_t":
1537                continue
1538            level = semanage_context_get_mls(con)
1539            (rc, subnet_prefix) = semanage_ibpkey_get_subnet_prefix(self.sh, ibpkey)
1540            low = semanage_ibpkey_get_low(ibpkey)
1541            high = semanage_ibpkey_get_high(ibpkey)
1542            ddict[(low, high, subnet_prefix)] = (ctype, level)
1543        return ddict
1544
1545    def get_all_by_type(self, locallist=0):
1546        ddict = {}
1547        if locallist:
1548            (rc, self.plist) = semanage_ibpkey_list_local(self.sh)
1549        else:
1550            (rc, self.plist) = semanage_ibpkey_list(self.sh)
1551        if rc < 0:
1552            raise ValueError(_("Could not list ibpkeys"))
1553
1554        for ibpkey in self.plist:
1555            con = semanage_ibpkey_get_con(ibpkey)
1556            ctype = semanage_context_get_type(con)
1557            (rc, subnet_prefix) = semanage_ibpkey_get_subnet_prefix(self.sh, ibpkey)
1558            low = semanage_ibpkey_get_low(ibpkey)
1559            high = semanage_ibpkey_get_high(ibpkey)
1560            if (ctype, subnet_prefix) not in ddict.keys():
1561                ddict[(ctype, subnet_prefix)] = []
1562            if low == high:
1563                ddict[(ctype, subnet_prefix)].append("0x%x" % low)
1564            else:
1565                ddict[(ctype, subnet_prefix)].append("0x%x-0x%x" % (low, high))
1566        return ddict
1567
1568    def customized(self):
1569        l = []
1570        ddict = self.get_all(True)
1571
1572        for k in sorted(ddict.keys()):
1573            port = k[0] if k[0] == k[1] else "%s-%s" % (k[0], k[1])
1574            if ddict[k][1]:
1575                l.append("-a -t %s -r '%s' -x %s %s" % (ddict[k][0], ddict[k][1], k[2], port))
1576            else:
1577                l.append("-a -t %s -x %s %s" % (ddict[k][0], k[2], port))
1578        return l
1579
1580    def list(self, heading=1, locallist=0):
1581        ddict = self.get_all_by_type(locallist)
1582        keys = ddict.keys()
1583        if len(keys) == 0:
1584            return
1585
1586        if heading:
1587            print("%-30s %-18s %s\n" % (_("SELinux IB Pkey Type"), _("Subnet_Prefix"), _("Pkey Number")))
1588        for i in sorted(keys):
1589            rec = "%-30s %-18s " % i
1590            rec += "%s" % ddict[i][0]
1591            for p in ddict[i][1:]:
1592                rec += ", %s" % p
1593            print(rec)
1594
1595class ibendportRecords(semanageRecords):
1596
1597    valid_types = []
1598
1599    def __init__(self, args = None):
1600        semanageRecords.__init__(self, args)
1601        try:
1602            q = setools.TypeQuery(setools.SELinuxPolicy(sepolicy.get_store_policy(self.store)), attrs=["ibendport_type"])
1603            self.valid_types = set(str(t) for t in q.results())
1604        except:
1605            pass
1606
1607    def __genkey(self, ibendport, ibdev_name):
1608        if ibdev_name == "":
1609            raise ValueError(_("IB device name is required"))
1610
1611        port = int(ibendport)
1612
1613        if port > 255 or port < 1:
1614            raise ValueError(_("Invalid Port Number"))
1615
1616        (rc, k) = semanage_ibendport_key_create(self.sh, ibdev_name, port)
1617        if rc < 0:
1618            raise ValueError(_("Could not create a key for ibendport %s/%s") % (ibdev_name, ibendport))
1619        return (k, ibdev_name, port)
1620
1621    def __add(self, ibendport, ibdev_name, serange, type):
1622        if is_mls_enabled == 1:
1623            if serange == "":
1624                serange = "s0"
1625            else:
1626                serange = untranslate(serange)
1627
1628        if type == "":
1629            raise ValueError(_("Type is required"))
1630
1631        type = sepolicy.get_real_type_name(type)
1632
1633        if type not in self.valid_types:
1634            raise ValueError(_("Type %s is invalid, must be an ibendport type") % type)
1635        (k, ibendport, port) = self.__genkey(ibendport, ibdev_name)
1636
1637        (rc, exists) = semanage_ibendport_exists(self.sh, k)
1638        if rc < 0:
1639            raise ValueError(_("Could not check if ibendport %s/%s is defined") % (ibdev_name, port))
1640        if exists:
1641            raise ValueError(_("ibendport %s/%s already defined") % (ibdev_name, port))
1642
1643        (rc, p) = semanage_ibendport_create(self.sh)
1644        if rc < 0:
1645            raise ValueError(_("Could not create ibendport for %s/%s") % (ibdev_name, port))
1646
1647        semanage_ibendport_set_ibdev_name(self.sh, p, ibdev_name)
1648        semanage_ibendport_set_port(p, port)
1649        (rc, con) = semanage_context_create(self.sh)
1650        if rc < 0:
1651            raise ValueError(_("Could not create context for %s/%s") % (ibdev_name, port))
1652
1653        rc = semanage_context_set_user(self.sh, con, "system_u")
1654        if rc < 0:
1655            raise ValueError(_("Could not set user in ibendport context for %s/%s") % (ibdev_name, port))
1656
1657        rc = semanage_context_set_role(self.sh, con, "object_r")
1658        if rc < 0:
1659            raise ValueError(_("Could not set role in ibendport context for %s/%s") % (ibdev_name, port))
1660
1661        rc = semanage_context_set_type(self.sh, con, type)
1662        if rc < 0:
1663            raise ValueError(_("Could not set type in ibendport context for %s/%s") % (ibdev_name, port))
1664
1665        if (is_mls_enabled == 1) and (serange != ""):
1666            rc = semanage_context_set_mls(self.sh, con, serange)
1667            if rc < 0:
1668                raise ValueError(_("Could not set mls fields in ibendport context for %s/%s") % (ibdev_name, port))
1669
1670        rc = semanage_ibendport_set_con(self.sh, p, con)
1671        if rc < 0:
1672            raise ValueError(_("Could not set ibendport context for %s/%s") % (ibdev_name, port))
1673
1674        rc = semanage_ibendport_modify_local(self.sh, k, p)
1675        if rc < 0:
1676            raise ValueError(_("Could not add ibendport %s/%s") % (ibdev_name, port))
1677
1678        semanage_context_free(con)
1679        semanage_ibendport_key_free(k)
1680        semanage_ibendport_free(p)
1681
1682    def add(self, ibendport, ibdev_name, serange, type):
1683        self.begin()
1684        self.__add(ibendport, ibdev_name, serange, type)
1685        self.commit()
1686
1687    def __modify(self, ibendport, ibdev_name, serange, setype):
1688        if serange == "" and setype == "":
1689            if is_mls_enabled == 1:
1690                raise ValueError(_("Requires setype or serange"))
1691            else:
1692                raise ValueError(_("Requires setype"))
1693
1694        setype = sepolicy.get_real_type_name(setype)
1695
1696        if setype and setype not in self.valid_types:
1697            raise ValueError(_("Type %s is invalid, must be an ibendport type") % setype)
1698
1699        (k, ibdev_name, port) = self.__genkey(ibendport, ibdev_name)
1700
1701        (rc, exists) = semanage_ibendport_exists(self.sh, k)
1702        if rc < 0:
1703            raise ValueError(_("Could not check if ibendport %s/%s is defined") % (ibdev_name, ibendport))
1704        if not exists:
1705            raise ValueError(_("ibendport %s/%s is not defined") % (ibdev_name, ibendport))
1706
1707        (rc, p) = semanage_ibendport_query(self.sh, k)
1708        if rc < 0:
1709            raise ValueError(_("Could not query ibendport %s/%s") % (ibdev_name, ibendport))
1710
1711        con = semanage_ibendport_get_con(p)
1712
1713        if (is_mls_enabled == 1) and (serange != ""):
1714            semanage_context_set_mls(self.sh, con, untranslate(serange))
1715        if setype != "":
1716            semanage_context_set_type(self.sh, con, setype)
1717
1718        rc = semanage_ibendport_modify_local(self.sh, k, p)
1719        if rc < 0:
1720            raise ValueError(_("Could not modify ibendport %s/%s") % (ibdev_name, ibendport))
1721
1722        semanage_ibendport_key_free(k)
1723        semanage_ibendport_free(p)
1724
1725    def modify(self, ibendport, ibdev_name, serange, setype):
1726        self.begin()
1727        self.__modify(ibendport, ibdev_name, serange, setype)
1728        self.commit()
1729
1730    def deleteall(self):
1731        (rc, plist) = semanage_ibendport_list_local(self.sh)
1732        if rc < 0:
1733            raise ValueError(_("Could not list the ibendports"))
1734
1735        self.begin()
1736
1737        for ibendport in plist:
1738            (rc, ibdev_name) = semanage_ibendport_get_ibdev_name(self.sh, ibendport)
1739            port = semanage_ibendport_get_port(ibendport)
1740            (k, ibdev_name, port) = self.__genkey(str(port), ibdev_name)
1741            if rc < 0:
1742                raise ValueError(_("Could not create a key for %s/%d") % (ibdevname, port))
1743
1744            rc = semanage_ibendport_del_local(self.sh, k)
1745            if rc < 0:
1746                raise ValueError(_("Could not delete the ibendport %s/%d") % (ibdev_name, port))
1747            semanage_ibendport_key_free(k)
1748
1749        self.commit()
1750
1751    def __delete(self, ibendport, ibdev_name):
1752        (k, ibdev_name, port) = self.__genkey(ibendport, ibdev_name)
1753        (rc, exists) = semanage_ibendport_exists(self.sh, k)
1754        if rc < 0:
1755            raise ValueError(_("Could not check if ibendport %s/%s is defined") % (ibdev_name, ibendport))
1756        if not exists:
1757            raise ValueError(_("ibendport %s/%s is not defined") % (ibdev_name, ibendport))
1758
1759        (rc, exists) = semanage_ibendport_exists_local(self.sh, k)
1760        if rc < 0:
1761            raise ValueError(_("Could not check if ibendport %s/%s is defined") % (ibdev_name, ibendport))
1762        if not exists:
1763            raise ValueError(_("ibendport %s/%s is defined in policy, cannot be deleted") % (ibdev_name, ibendport))
1764
1765        rc = semanage_ibendport_del_local(self.sh, k)
1766        if rc < 0:
1767            raise ValueError(_("Could not delete ibendport %s/%s") % (ibdev_name, ibendport))
1768
1769        semanage_ibendport_key_free(k)
1770
1771    def delete(self, ibendport, ibdev_name):
1772        self.begin()
1773        self.__delete(ibendport, ibdev_name)
1774        self.commit()
1775
1776    def get_all(self, locallist=0):
1777        ddict = {}
1778        if locallist:
1779            (rc, self.plist) = semanage_ibendport_list_local(self.sh)
1780        else:
1781            (rc, self.plist) = semanage_ibendport_list(self.sh)
1782        if rc < 0:
1783            raise ValueError(_("Could not list ibendports"))
1784
1785        for ibendport in self.plist:
1786            con = semanage_ibendport_get_con(ibendport)
1787            ctype = semanage_context_get_type(con)
1788            if ctype == "reserved_ibendport_t":
1789                continue
1790            level = semanage_context_get_mls(con)
1791            (rc, ibdev_name) = semanage_ibendport_get_ibdev_name(self.sh, ibendport)
1792            port = semanage_ibendport_get_port(ibendport)
1793            ddict[(port, ibdev_name)] = (ctype, level)
1794        return ddict
1795
1796    def get_all_by_type(self, locallist=0):
1797        ddict = {}
1798        if locallist:
1799            (rc, self.plist) = semanage_ibendport_list_local(self.sh)
1800        else:
1801            (rc, self.plist) = semanage_ibendport_list(self.sh)
1802        if rc < 0:
1803            raise ValueError(_("Could not list ibendports"))
1804
1805        for ibendport in self.plist:
1806            con = semanage_ibendport_get_con(ibendport)
1807            ctype = semanage_context_get_type(con)
1808            (rc, ibdev_name) = semanage_ibendport_get_ibdev_name(self.sh, ibendport)
1809            port = semanage_ibendport_get_port(ibendport)
1810            if (ctype, ibdev_name) not in ddict.keys():
1811                ddict[(ctype, ibdev_name)] = []
1812            ddict[(ctype, ibdev_name)].append("0x%x" % port)
1813        return ddict
1814
1815    def customized(self):
1816        l = []
1817        ddict = self.get_all(True)
1818
1819        for k in sorted(ddict.keys()):
1820            if ddict[k][1]:
1821                l.append("-a -t %s -r '%s' -z %s %s" % (ddict[k][0], ddict[k][1], k[1], k[0]))
1822            else:
1823                l.append("-a -t %s -z %s %s" % (ddict[k][0], k[1], k[0]))
1824        return l
1825
1826    def list(self, heading=1, locallist=0):
1827        ddict = self.get_all_by_type(locallist)
1828        keys = ddict.keys()
1829        if len(keys) == 0:
1830            return
1831
1832        if heading:
1833            print("%-30s %-18s %s\n" % (_("SELinux IB End Port Type"), _("IB Device Name"), _("Port Number")))
1834        for i in sorted(keys):
1835            rec = "%-30s %-18s " % i
1836            rec += "%s" % ddict[i][0]
1837            for p in ddict[i][1:]:
1838                rec += ", %s" % p
1839            print(rec)
1840
1841class nodeRecords(semanageRecords):
1842
1843    valid_types = []
1844
1845    def __init__(self, args = None):
1846        semanageRecords.__init__(self, args)
1847        self.protocol = ["ipv4", "ipv6"]
1848        try:
1849            self.valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "node_type"))[0]["types"])
1850        except RuntimeError:
1851            pass
1852
1853    def validate(self, addr, mask, protocol):
1854        newaddr = addr
1855        newmask = mask
1856        newprotocol = ""
1857
1858        if addr == "":
1859            raise ValueError(_("Node Address is required"))
1860
1861        # verify valid combination
1862        if len(mask) == 0 or mask[0] == "/":
1863            i = IP(addr + mask)
1864            newaddr = i.strNormal(0)
1865            newmask = str(i.netmask())
1866            if newmask == "0.0.0.0" and i.version() == 6:
1867                newmask = "::"
1868
1869            protocol = "ipv%d" % i.version()
1870
1871        try:
1872            newprotocol = self.protocol.index(protocol)
1873        except:
1874            raise ValueError(_("Unknown or missing protocol"))
1875
1876        return newaddr, newmask, newprotocol
1877
1878    def __add(self, addr, mask, proto, serange, ctype):
1879        addr, mask, proto = self.validate(addr, mask, proto)
1880
1881        if is_mls_enabled == 1:
1882            if serange == "":
1883                serange = "s0"
1884            else:
1885                serange = untranslate(serange)
1886
1887        if ctype == "":
1888            raise ValueError(_("SELinux node type is required"))
1889
1890        ctype = sepolicy.get_real_type_name(ctype)
1891
1892        if ctype not in self.valid_types:
1893            raise ValueError(_("Type %s is invalid, must be a node type") % ctype)
1894
1895        (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
1896        if rc < 0:
1897            raise ValueError(_("Could not create key for %s") % addr)
1898        if rc < 0:
1899            raise ValueError(_("Could not check if addr %s is defined") % addr)
1900
1901        (rc, exists) = semanage_node_exists(self.sh, k)
1902        if exists:
1903            raise ValueError(_("Addr %s already defined") % addr)
1904
1905        (rc, node) = semanage_node_create(self.sh)
1906        if rc < 0:
1907            raise ValueError(_("Could not create addr for %s") % addr)
1908        semanage_node_set_proto(node, proto)
1909
1910        rc = semanage_node_set_addr(self.sh, node, proto, addr)
1911        (rc, con) = semanage_context_create(self.sh)
1912        if rc < 0:
1913            raise ValueError(_("Could not create context for %s") % addr)
1914
1915        rc = semanage_node_set_mask(self.sh, node, proto, mask)
1916        if rc < 0:
1917            raise ValueError(_("Could not set mask for %s") % addr)
1918
1919        rc = semanage_context_set_user(self.sh, con, "system_u")
1920        if rc < 0:
1921            raise ValueError(_("Could not set user in addr context for %s") % addr)
1922
1923        rc = semanage_context_set_role(self.sh, con, "object_r")
1924        if rc < 0:
1925            raise ValueError(_("Could not set role in addr context for %s") % addr)
1926
1927        rc = semanage_context_set_type(self.sh, con, ctype)
1928        if rc < 0:
1929            raise ValueError(_("Could not set type in addr context for %s") % addr)
1930
1931        if (is_mls_enabled == 1) and (serange != ""):
1932            rc = semanage_context_set_mls(self.sh, con, serange)
1933            if rc < 0:
1934                raise ValueError(_("Could not set mls fields in addr context for %s") % addr)
1935
1936        rc = semanage_node_set_con(self.sh, node, con)
1937        if rc < 0:
1938            raise ValueError(_("Could not set addr context for %s") % addr)
1939
1940        rc = semanage_node_modify_local(self.sh, k, node)
1941        if rc < 0:
1942            raise ValueError(_("Could not add addr %s") % addr)
1943
1944        semanage_context_free(con)
1945        semanage_node_key_free(k)
1946        semanage_node_free(node)
1947
1948        self.mylog.log_change("resrc=node op=add laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, socket.getprotobyname(self.protocol[proto]), "system_u", "object_r", ctype, serange))
1949
1950    def add(self, addr, mask, proto, serange, ctype):
1951        self.begin()
1952        self.__add(addr, mask, proto, serange, ctype)
1953        self.commit()
1954
1955    def __modify(self, addr, mask, proto, serange, setype):
1956        addr, mask, proto = self.validate(addr, mask, proto)
1957
1958        if serange == "" and setype == "":
1959            raise ValueError(_("Requires setype or serange"))
1960
1961        setype = sepolicy.get_real_type_name(setype)
1962
1963        if setype and setype not in self.valid_types:
1964            raise ValueError(_("Type %s is invalid, must be a node type") % setype)
1965
1966        (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
1967        if rc < 0:
1968            raise ValueError(_("Could not create key for %s") % addr)
1969
1970        (rc, exists) = semanage_node_exists(self.sh, k)
1971        if rc < 0:
1972            raise ValueError(_("Could not check if addr %s is defined") % addr)
1973        if not exists:
1974            raise ValueError(_("Addr %s is not defined") % addr)
1975
1976        (rc, node) = semanage_node_query(self.sh, k)
1977        if rc < 0:
1978            raise ValueError(_("Could not query addr %s") % addr)
1979
1980        con = semanage_node_get_con(node)
1981        if (is_mls_enabled == 1) and (serange != ""):
1982            semanage_context_set_mls(self.sh, con, untranslate(serange))
1983        if setype != "":
1984            semanage_context_set_type(self.sh, con, setype)
1985
1986        rc = semanage_node_modify_local(self.sh, k, node)
1987        if rc < 0:
1988            raise ValueError(_("Could not modify addr %s") % addr)
1989
1990        semanage_node_key_free(k)
1991        semanage_node_free(node)
1992
1993        self.mylog.log_change("resrc=node op=modify laddr=%s netmask=%s proto=%s tcontext=%s:%s:%s:%s" % (addr, mask, socket.getprotobyname(self.protocol[proto]), "system_u", "object_r", setype, serange))
1994
1995    def modify(self, addr, mask, proto, serange, setype):
1996        self.begin()
1997        self.__modify(addr, mask, proto, serange, setype)
1998        self.commit()
1999
2000    def __delete(self, addr, mask, proto):
2001
2002        addr, mask, proto = self.validate(addr, mask, proto)
2003
2004        (rc, k) = semanage_node_key_create(self.sh, addr, mask, proto)
2005        if rc < 0:
2006            raise ValueError(_("Could not create key for %s") % addr)
2007
2008        (rc, exists) = semanage_node_exists(self.sh, k)
2009        if rc < 0:
2010            raise ValueError(_("Could not check if addr %s is defined") % addr)
2011        if not exists:
2012            raise ValueError(_("Addr %s is not defined") % addr)
2013
2014        (rc, exists) = semanage_node_exists_local(self.sh, k)
2015        if rc < 0:
2016            raise ValueError(_("Could not check if addr %s is defined") % addr)
2017        if not exists:
2018            raise ValueError(_("Addr %s is defined in policy, cannot be deleted") % addr)
2019
2020        rc = semanage_node_del_local(self.sh, k)
2021        if rc < 0:
2022            raise ValueError(_("Could not delete addr %s") % addr)
2023
2024        semanage_node_key_free(k)
2025
2026        self.mylog.log_change("resrc=node op=delete laddr=%s netmask=%s proto=%s" % (addr, mask, socket.getprotobyname(self.protocol[proto])))
2027
2028    def delete(self, addr, mask, proto):
2029        self.begin()
2030        self.__delete(addr, mask, proto)
2031        self.commit()
2032
2033    def deleteall(self):
2034        (rc, nlist) = semanage_node_list_local(self.sh)
2035        if rc < 0:
2036            raise ValueError(_("Could not deleteall node mappings"))
2037
2038        self.begin()
2039        for node in nlist:
2040            self.__delete(semanage_node_get_addr(self.sh, node)[1], semanage_node_get_mask(self.sh, node)[1], self.protocol[semanage_node_get_proto(node)])
2041        self.commit()
2042
2043    def get_all(self, locallist=0):
2044        ddict = {}
2045        if locallist:
2046            (rc, self.ilist) = semanage_node_list_local(self.sh)
2047        else:
2048            (rc, self.ilist) = semanage_node_list(self.sh)
2049        if rc < 0:
2050            raise ValueError(_("Could not list addrs"))
2051
2052        for node in self.ilist:
2053            con = semanage_node_get_con(node)
2054            addr = semanage_node_get_addr(self.sh, node)
2055            mask = semanage_node_get_mask(self.sh, node)
2056            proto = self.protocol[semanage_node_get_proto(node)]
2057            ddict[(addr[1], mask[1], proto)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
2058
2059        return ddict
2060
2061    def customized(self):
2062        l = []
2063        ddict = self.get_all(True)
2064        for k in sorted(ddict.keys()):
2065            if ddict[k][3]:
2066                l.append("-a -M %s -p %s -t %s -r '%s' %s" % (k[1], k[2], ddict[k][2], ddict[k][3], k[0]))
2067            else:
2068                l.append("-a -M %s -p %s -t %s %s" % (k[1], k[2], ddict[k][2], k[0]))
2069        return l
2070
2071    def list(self, heading=1, locallist=0):
2072        ddict = self.get_all(locallist)
2073        if len(ddict) == 0:
2074            return
2075        keys = sorted(ddict.keys())
2076
2077        if heading:
2078            print("%-18s %-18s %-5s %-5s\n" % ("IP Address", "Netmask", "Protocol", "Context"))
2079        if is_mls_enabled:
2080            for k in keys:
2081                val = ''
2082                for fields in k:
2083                    val = val + '\t' + str(fields)
2084                print("%-18s %-18s %-5s %s:%s:%s:%s " % (k[0], k[1], k[2], ddict[k][0], ddict[k][1], ddict[k][2], translate(ddict[k][3], False)))
2085        else:
2086            for k in keys:
2087                print("%-18s %-18s %-5s %s:%s:%s " % (k[0], k[1], k[2], ddict[k][0], ddict[k][1], ddict[k][2]))
2088
2089
2090class interfaceRecords(semanageRecords):
2091
2092    def __init__(self, args = None):
2093        semanageRecords.__init__(self, args)
2094
2095    def __add(self, interface, serange, ctype):
2096        if is_mls_enabled == 1:
2097            if serange == "":
2098                serange = "s0"
2099            else:
2100                serange = untranslate(serange)
2101
2102        if ctype == "":
2103            raise ValueError(_("SELinux Type is required"))
2104
2105        (rc, k) = semanage_iface_key_create(self.sh, interface)
2106        if rc < 0:
2107            raise ValueError(_("Could not create key for %s") % interface)
2108
2109        (rc, exists) = semanage_iface_exists(self.sh, k)
2110        if rc < 0:
2111            raise ValueError(_("Could not check if interface %s is defined") % interface)
2112        if exists:
2113            raise ValueError(_("Interface %s already defined") % interface)
2114
2115        (rc, iface) = semanage_iface_create(self.sh)
2116        if rc < 0:
2117            raise ValueError(_("Could not create interface for %s") % interface)
2118
2119        rc = semanage_iface_set_name(self.sh, iface, interface)
2120        (rc, con) = semanage_context_create(self.sh)
2121        if rc < 0:
2122            raise ValueError(_("Could not create context for %s") % interface)
2123
2124        rc = semanage_context_set_user(self.sh, con, "system_u")
2125        if rc < 0:
2126            raise ValueError(_("Could not set user in interface context for %s") % interface)
2127
2128        rc = semanage_context_set_role(self.sh, con, "object_r")
2129        if rc < 0:
2130            raise ValueError(_("Could not set role in interface context for %s") % interface)
2131
2132        rc = semanage_context_set_type(self.sh, con, ctype)
2133        if rc < 0:
2134            raise ValueError(_("Could not set type in interface context for %s") % interface)
2135
2136        if (is_mls_enabled == 1) and (serange != ""):
2137            rc = semanage_context_set_mls(self.sh, con, serange)
2138            if rc < 0:
2139                raise ValueError(_("Could not set mls fields in interface context for %s") % interface)
2140
2141        rc = semanage_iface_set_ifcon(self.sh, iface, con)
2142        if rc < 0:
2143            raise ValueError(_("Could not set interface context for %s") % interface)
2144
2145        rc = semanage_iface_set_msgcon(self.sh, iface, con)
2146        if rc < 0:
2147            raise ValueError(_("Could not set message context for %s") % interface)
2148
2149        rc = semanage_iface_modify_local(self.sh, k, iface)
2150        if rc < 0:
2151            raise ValueError(_("Could not add interface %s") % interface)
2152
2153        semanage_context_free(con)
2154        semanage_iface_key_free(k)
2155        semanage_iface_free(iface)
2156
2157        self.mylog.log_change("resrc=interface op=add netif=%s tcontext=%s:%s:%s:%s" % (interface, "system_u", "object_r", ctype, serange))
2158
2159    def add(self, interface, serange, ctype):
2160        self.begin()
2161        self.__add(interface, serange, ctype)
2162        self.commit()
2163
2164    def __modify(self, interface, serange, setype):
2165        if serange == "" and setype == "":
2166            raise ValueError(_("Requires setype or serange"))
2167
2168        (rc, k) = semanage_iface_key_create(self.sh, interface)
2169        if rc < 0:
2170            raise ValueError(_("Could not create key for %s") % interface)
2171
2172        (rc, exists) = semanage_iface_exists(self.sh, k)
2173        if rc < 0:
2174            raise ValueError(_("Could not check if interface %s is defined") % interface)
2175        if not exists:
2176            raise ValueError(_("Interface %s is not defined") % interface)
2177
2178        (rc, iface) = semanage_iface_query(self.sh, k)
2179        if rc < 0:
2180            raise ValueError(_("Could not query interface %s") % interface)
2181
2182        con = semanage_iface_get_ifcon(iface)
2183
2184        if (is_mls_enabled == 1) and (serange != ""):
2185            semanage_context_set_mls(self.sh, con, untranslate(serange))
2186        if setype != "":
2187            semanage_context_set_type(self.sh, con, setype)
2188
2189        rc = semanage_iface_modify_local(self.sh, k, iface)
2190        if rc < 0:
2191            raise ValueError(_("Could not modify interface %s") % interface)
2192
2193        semanage_iface_key_free(k)
2194        semanage_iface_free(iface)
2195
2196        self.mylog.log_change("resrc=interface op=modify netif=%s tcontext=%s:%s:%s:%s" % (interface, "system_u", "object_r", setype, serange))
2197
2198    def modify(self, interface, serange, setype):
2199        self.begin()
2200        self.__modify(interface, serange, setype)
2201        self.commit()
2202
2203    def __delete(self, interface):
2204        (rc, k) = semanage_iface_key_create(self.sh, interface)
2205        if rc < 0:
2206            raise ValueError(_("Could not create key for %s") % interface)
2207
2208        (rc, exists) = semanage_iface_exists(self.sh, k)
2209        if rc < 0:
2210            raise ValueError(_("Could not check if interface %s is defined") % interface)
2211        if not exists:
2212            raise ValueError(_("Interface %s is not defined") % interface)
2213
2214        (rc, exists) = semanage_iface_exists_local(self.sh, k)
2215        if rc < 0:
2216            raise ValueError(_("Could not check if interface %s is defined") % interface)
2217        if not exists:
2218            raise ValueError(_("Interface %s is defined in policy, cannot be deleted") % interface)
2219
2220        rc = semanage_iface_del_local(self.sh, k)
2221        if rc < 0:
2222            raise ValueError(_("Could not delete interface %s") % interface)
2223
2224        semanage_iface_key_free(k)
2225
2226        self.mylog.log_change("resrc=interface op=delete netif=%s" % interface)
2227
2228    def delete(self, interface):
2229        self.begin()
2230        self.__delete(interface)
2231        self.commit()
2232
2233    def deleteall(self):
2234        (rc, ulist) = semanage_iface_list_local(self.sh)
2235        if rc < 0:
2236            raise ValueError(_("Could not delete all interface  mappings"))
2237
2238        self.begin()
2239        for i in ulist:
2240            self.__delete(semanage_iface_get_name(i))
2241        self.commit()
2242
2243    def get_all(self, locallist=0):
2244        ddict = {}
2245        if locallist:
2246            (rc, self.ilist) = semanage_iface_list_local(self.sh)
2247        else:
2248            (rc, self.ilist) = semanage_iface_list(self.sh)
2249        if rc < 0:
2250            raise ValueError(_("Could not list interfaces"))
2251
2252        for interface in self.ilist:
2253            con = semanage_iface_get_ifcon(interface)
2254            ddict[semanage_iface_get_name(interface)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
2255
2256        return ddict
2257
2258    def customized(self):
2259        l = []
2260        ddict = self.get_all(True)
2261        for k in sorted(ddict.keys()):
2262            if ddict[k][3]:
2263                l.append("-a -t %s -r '%s' %s" % (ddict[k][2], ddict[k][3], k))
2264            else:
2265                l.append("-a -t %s %s" % (ddict[k][2], k))
2266        return l
2267
2268    def list(self, heading=1, locallist=0):
2269        ddict = self.get_all(locallist)
2270        if len(ddict) == 0:
2271            return
2272        keys = sorted(ddict.keys())
2273
2274        if heading:
2275            print("%-30s %s\n" % (_("SELinux Interface"), _("Context")))
2276        if is_mls_enabled:
2277            for k in keys:
2278                print("%-30s %s:%s:%s:%s " % (k, ddict[k][0], ddict[k][1], ddict[k][2], translate(ddict[k][3], False)))
2279        else:
2280            for k in keys:
2281                print("%-30s %s:%s:%s " % (k, ddict[k][0], ddict[k][1], ddict[k][2]))
2282
2283
2284class fcontextRecords(semanageRecords):
2285
2286    valid_types = []
2287
2288    def __init__(self, args = None):
2289        semanageRecords.__init__(self, args)
2290        try:
2291            self.valid_types = list(list(sepolicy.info(sepolicy.ATTRIBUTE, "file_type"))[0]["types"])
2292            self.valid_types += list(list(sepolicy.info(sepolicy.ATTRIBUTE, "device_node"))[0]["types"])
2293        except RuntimeError:
2294            pass
2295
2296        self.equiv = {}
2297        self.equiv_dist = {}
2298        self.equal_ind = False
2299        try:
2300            fd = open(selinux.selinux_file_context_subs_path(), "r")
2301            for i in fd.readlines():
2302                i = i.strip()
2303                if len(i) == 0:
2304                    continue
2305                if i.startswith("#"):
2306                    continue
2307                target, substitute = i.split()
2308                self.equiv[target] = substitute
2309            fd.close()
2310        except IOError:
2311            pass
2312        try:
2313            fd = open(selinux.selinux_file_context_subs_dist_path(), "r")
2314            for i in fd.readlines():
2315                i = i.strip()
2316                if len(i) == 0:
2317                    continue
2318                if i.startswith("#"):
2319                    continue
2320                target, substitute = i.split()
2321                self.equiv_dist[target] = substitute
2322            fd.close()
2323        except IOError:
2324            pass
2325
2326    def commit(self):
2327        if self.equal_ind:
2328            subs_file = selinux.selinux_file_context_subs_path()
2329            tmpfile = "%s.tmp" % subs_file
2330            fd = open(tmpfile, "w")
2331            for target in self.equiv.keys():
2332                fd.write("%s %s\n" % (target, self.equiv[target]))
2333            fd.close()
2334            try:
2335                os.chmod(tmpfile, os.stat(subs_file)[stat.ST_MODE])
2336            except:
2337                pass
2338            os.rename(tmpfile, subs_file)
2339            self.equal_ind = False
2340        semanageRecords.commit(self)
2341
2342    def add_equal(self, target, substitute):
2343        self.begin()
2344        if target != "/" and target[-1] == "/":
2345            raise ValueError(_("Target %s is not valid. Target is not allowed to end with '/'") % target)
2346
2347        if substitute != "/" and substitute[-1] == "/":
2348            raise ValueError(_("Substitute %s is not valid. Substitute is not allowed to end with '/'") % substitute)
2349
2350        if target in self.equiv.keys():
2351            raise ValueError(_("Equivalence class for %s already exists") % target)
2352        self.validate(target)
2353
2354        for fdict in (self.equiv, self.equiv_dist):
2355            for i in fdict:
2356                if i.startswith(target + "/"):
2357                    raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'") % (target, i, fdict[i]))
2358
2359        self.mylog.log_change("resrc=fcontext op=add-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0)))
2360
2361        self.equiv[target] = substitute
2362        self.equal_ind = True
2363        self.commit()
2364
2365    def modify_equal(self, target, substitute):
2366        self.begin()
2367        if target not in self.equiv.keys():
2368            raise ValueError(_("Equivalence class for %s does not exist") % target)
2369        self.equiv[target] = substitute
2370        self.equal_ind = True
2371
2372        self.mylog.log_change("resrc=fcontext op=modify-equal %s %s" % (audit.audit_encode_nv_string("sglob", target, 0), audit.audit_encode_nv_string("tglob", substitute, 0)))
2373
2374        self.commit()
2375
2376    def createcon(self, target, seuser="system_u"):
2377        (rc, con) = semanage_context_create(self.sh)
2378        if rc < 0:
2379            raise ValueError(_("Could not create context for %s") % target)
2380        if seuser == "":
2381            seuser = "system_u"
2382
2383        rc = semanage_context_set_user(self.sh, con, seuser)
2384        if rc < 0:
2385            raise ValueError(_("Could not set user in file context for %s") % target)
2386
2387        rc = semanage_context_set_role(self.sh, con, "object_r")
2388        if rc < 0:
2389            raise ValueError(_("Could not set role in file context for %s") % target)
2390
2391        if is_mls_enabled == 1:
2392            rc = semanage_context_set_mls(self.sh, con, "s0")
2393            if rc < 0:
2394                raise ValueError(_("Could not set mls fields in file context for %s") % target)
2395
2396        return con
2397
2398    def validate(self, target):
2399        if target == "" or target.find("\n") >= 0:
2400            raise ValueError(_("Invalid file specification"))
2401        if target.find(" ") != -1:
2402            raise ValueError(_("File specification can not include spaces"))
2403        for fdict in (self.equiv, self.equiv_dist):
2404            for i in fdict:
2405                if target.startswith(i + "/"):
2406                    t = re.sub(i, fdict[i], target)
2407                    raise ValueError(_("File spec %s conflicts with equivalency rule '%s %s'; Try adding '%s' instead") % (target, i, fdict[i], t))
2408
2409    def __add(self, target, type, ftype="", serange="", seuser="system_u"):
2410        self.validate(target)
2411
2412        if is_mls_enabled == 1:
2413            serange = untranslate(serange)
2414
2415        if type == "":
2416            raise ValueError(_("SELinux Type is required"))
2417
2418        if type != "<<none>>":
2419            type = sepolicy.get_real_type_name(type)
2420            if type not in self.valid_types:
2421                raise ValueError(_("Type %s is invalid, must be a file or device type") % type)
2422
2423        (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
2424        if rc < 0:
2425            raise ValueError(_("Could not create key for %s") % target)
2426
2427        (rc, exists) = semanage_fcontext_exists(self.sh, k)
2428        if rc < 0:
2429            raise ValueError(_("Could not check if file context for %s is defined") % target)
2430
2431        if not exists:
2432            (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
2433            if rc < 0:
2434                raise ValueError(_("Could not check if file context for %s is defined") % target)
2435
2436        if exists:
2437            raise ValueError(_("File context for %s already defined") % target)
2438
2439        (rc, fcontext) = semanage_fcontext_create(self.sh)
2440        if rc < 0:
2441            raise ValueError(_("Could not create file context for %s") % target)
2442
2443        rc = semanage_fcontext_set_expr(self.sh, fcontext, target)
2444        if type != "<<none>>":
2445            con = self.createcon(target, seuser)
2446
2447            rc = semanage_context_set_type(self.sh, con, type)
2448            if rc < 0:
2449                raise ValueError(_("Could not set type in file context for %s") % target)
2450
2451            if (is_mls_enabled == 1) and (serange != ""):
2452                rc = semanage_context_set_mls(self.sh, con, serange)
2453                if rc < 0:
2454                    raise ValueError(_("Could not set mls fields in file context for %s") % target)
2455            rc = semanage_fcontext_set_con(self.sh, fcontext, con)
2456            if rc < 0:
2457                raise ValueError(_("Could not set file context for %s") % target)
2458
2459        semanage_fcontext_set_type(fcontext, file_types[ftype])
2460
2461        rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
2462        if rc < 0:
2463            raise ValueError(_("Could not add file context for %s") % target)
2464
2465        if type != "<<none>>":
2466            semanage_context_free(con)
2467        semanage_fcontext_key_free(k)
2468        semanage_fcontext_free(fcontext)
2469
2470        if not seuser:
2471            seuser = "system_u"
2472
2473        self.mylog.log_change("resrc=fcontext op=add %s ftype=%s tcontext=%s:%s:%s:%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype], seuser, "object_r", type, serange))
2474
2475    def add(self, target, type, ftype="", serange="", seuser="system_u"):
2476        self.begin()
2477        self.__add(target, type, ftype, serange, seuser)
2478        self.commit()
2479
2480    def __modify(self, target, setype, ftype, serange, seuser):
2481        if serange == "" and setype == "" and seuser == "":
2482            raise ValueError(_("Requires setype, serange or seuser"))
2483        if setype not in ["",  "<<none>>"]:
2484            setype = sepolicy.get_real_type_name(setype)
2485            if setype not in self.valid_types:
2486                raise ValueError(_("Type %s is invalid, must be a file or device type") % setype)
2487
2488        self.validate(target)
2489
2490        (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
2491        if rc < 0:
2492            raise ValueError(_("Could not create a key for %s") % target)
2493
2494        (rc, exists) = semanage_fcontext_exists(self.sh, k)
2495        if rc < 0:
2496            raise ValueError(_("Could not check if file context for %s is defined") % target)
2497        if not exists:
2498            (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
2499            if not exists:
2500                raise ValueError(_("File context for %s is not defined") % target)
2501
2502        try:
2503            (rc, fcontext) = semanage_fcontext_query_local(self.sh, k)
2504        except OSError:
2505            try:
2506                (rc, fcontext) = semanage_fcontext_query(self.sh, k)
2507            except OSError:
2508                raise ValueError(_("Could not query file context for %s") % target)
2509
2510        if setype != "<<none>>":
2511            con = semanage_fcontext_get_con(fcontext)
2512
2513            if con is None:
2514                con = self.createcon(target)
2515
2516            if (is_mls_enabled == 1) and (serange != ""):
2517                semanage_context_set_mls(self.sh, con, untranslate(serange))
2518            if seuser != "":
2519                semanage_context_set_user(self.sh, con, seuser)
2520
2521            if setype != "":
2522                semanage_context_set_type(self.sh, con, setype)
2523
2524            rc = semanage_fcontext_set_con(self.sh, fcontext, con)
2525            if rc < 0:
2526                raise ValueError(_("Could not set file context for %s") % target)
2527        else:
2528            rc = semanage_fcontext_set_con(self.sh, fcontext, None)
2529            if rc < 0:
2530                raise ValueError(_("Could not set file context for %s") % target)
2531
2532        rc = semanage_fcontext_modify_local(self.sh, k, fcontext)
2533        if rc < 0:
2534            raise ValueError(_("Could not modify file context for %s") % target)
2535
2536        semanage_fcontext_key_free(k)
2537        semanage_fcontext_free(fcontext)
2538
2539        if not seuser:
2540            seuser = "system_u"
2541
2542        self.mylog.log_change("resrc=fcontext op=modify %s ftype=%s tcontext=%s:%s:%s:%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype], seuser, "object_r", setype, serange))
2543
2544    def modify(self, target, setype, ftype, serange, seuser):
2545        self.begin()
2546        self.__modify(target, setype, ftype, serange, seuser)
2547        self.commit()
2548
2549    def deleteall(self):
2550        (rc, flist) = semanage_fcontext_list_local(self.sh)
2551        if rc < 0:
2552            raise ValueError(_("Could not list the file contexts"))
2553
2554        self.begin()
2555
2556        for fcontext in flist:
2557            target = semanage_fcontext_get_expr(fcontext)
2558            ftype = semanage_fcontext_get_type(fcontext)
2559            ftype_str = semanage_fcontext_get_type_str(ftype)
2560            (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype_str])
2561            if rc < 0:
2562                raise ValueError(_("Could not create a key for %s") % target)
2563
2564            rc = semanage_fcontext_del_local(self.sh, k)
2565            if rc < 0:
2566                raise ValueError(_("Could not delete the file context %s") % target)
2567            semanage_fcontext_key_free(k)
2568
2569            self.mylog.log_change("resrc=fcontext op=delete %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[file_type_str_to_option[ftype_str]]))
2570
2571        self.equiv = {}
2572        self.equal_ind = True
2573        self.commit()
2574
2575    def __delete(self, target, ftype):
2576        if target in self.equiv.keys():
2577            self.equiv.pop(target)
2578            self.equal_ind = True
2579
2580            self.mylog.log_change("resrc=fcontext op=delete-equal %s" % (audit.audit_encode_nv_string("tglob", target, 0)))
2581
2582            return
2583
2584        (rc, k) = semanage_fcontext_key_create(self.sh, target, file_types[ftype])
2585        if rc < 0:
2586            raise ValueError(_("Could not create a key for %s") % target)
2587
2588        (rc, exists) = semanage_fcontext_exists_local(self.sh, k)
2589        if rc < 0:
2590            raise ValueError(_("Could not check if file context for %s is defined") % target)
2591        if not exists:
2592            (rc, exists) = semanage_fcontext_exists(self.sh, k)
2593            if rc < 0:
2594                raise ValueError(_("Could not check if file context for %s is defined") % target)
2595            if exists:
2596                raise ValueError(_("File context for %s is defined in policy, cannot be deleted") % target)
2597            else:
2598                raise ValueError(_("File context for %s is not defined") % target)
2599
2600        rc = semanage_fcontext_del_local(self.sh, k)
2601        if rc < 0:
2602            raise ValueError(_("Could not delete file context for %s") % target)
2603
2604        semanage_fcontext_key_free(k)
2605
2606        self.mylog.log_change("resrc=fcontext op=delete %s ftype=%s" % (audit.audit_encode_nv_string("tglob", target, 0), ftype_to_audit[ftype]))
2607
2608    def delete(self, target, ftype):
2609        self.begin()
2610        self.__delete(target, ftype)
2611        self.commit()
2612
2613    def get_all(self, locallist=0):
2614        if locallist:
2615            (rc, self.flist) = semanage_fcontext_list_local(self.sh)
2616        else:
2617            (rc, self.flist) = semanage_fcontext_list(self.sh)
2618            if rc < 0:
2619                raise ValueError(_("Could not list file contexts"))
2620
2621            (rc, fchomedirs) = semanage_fcontext_list_homedirs(self.sh)
2622            if rc < 0:
2623                raise ValueError(_("Could not list file contexts for home directories"))
2624
2625            (rc, fclocal) = semanage_fcontext_list_local(self.sh)
2626            if rc < 0:
2627                raise ValueError(_("Could not list local file contexts"))
2628
2629            self.flist += fchomedirs
2630            self.flist += fclocal
2631
2632        ddict = {}
2633        for fcontext in self.flist:
2634            expr = semanage_fcontext_get_expr(fcontext)
2635            ftype = semanage_fcontext_get_type(fcontext)
2636            ftype_str = semanage_fcontext_get_type_str(ftype)
2637            con = semanage_fcontext_get_con(fcontext)
2638            if con:
2639                ddict[(expr, ftype_str)] = (semanage_context_get_user(con), semanage_context_get_role(con), semanage_context_get_type(con), semanage_context_get_mls(con))
2640            else:
2641                ddict[(expr, ftype_str)] = con
2642
2643        return ddict
2644
2645    def customized(self):
2646        l = []
2647        fcon_dict = self.get_all(True)
2648        for k in sorted(fcon_dict.keys()):
2649            if fcon_dict[k]:
2650                if fcon_dict[k][3]:
2651                    l.append("-a -f %s -t %s -r '%s' '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], fcon_dict[k][3], k[0]))
2652                else:
2653                    l.append("-a -f %s -t %s '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], k[0]))
2654
2655        if len(self.equiv):
2656            for target in self.equiv.keys():
2657                l.append("-a -e %s %s" % (self.equiv[target], target))
2658        return l
2659
2660    def list(self, heading=1, locallist=0):
2661        fcon_dict = self.get_all(locallist)
2662        if len(fcon_dict) != 0:
2663            if heading:
2664                print("%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context")))
2665            for k in sorted(fcon_dict.keys()):
2666                if fcon_dict[k]:
2667                    if is_mls_enabled:
2668                        print("%-50s %-18s %s:%s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2], translate(fcon_dict[k][3], False)))
2669                    else:
2670                        print("%-50s %-18s %s:%s:%s " % (k[0], k[1], fcon_dict[k][0], fcon_dict[k][1], fcon_dict[k][2]))
2671                else:
2672                    print("%-50s %-18s <<None>>" % (k[0], k[1]))
2673
2674        if len(self.equiv_dist):
2675            if not locallist:
2676                if heading:
2677                    print(_("\nSELinux Distribution fcontext Equivalence \n"))
2678                for target in self.equiv_dist.keys():
2679                    print("%s = %s" % (target, self.equiv_dist[target]))
2680        if len(self.equiv):
2681            if heading:
2682                print(_("\nSELinux Local fcontext Equivalence \n"))
2683
2684            for target in self.equiv.keys():
2685                print("%s = %s" % (target, self.equiv[target]))
2686
2687
2688class booleanRecords(semanageRecords):
2689
2690    def __init__(self, args = None):
2691        semanageRecords.__init__(self, args)
2692        self.dict = {}
2693        self.dict["TRUE"] = 1
2694        self.dict["FALSE"] = 0
2695        self.dict["ON"] = 1
2696        self.dict["OFF"] = 0
2697        self.dict["1"] = 1
2698        self.dict["0"] = 0
2699
2700        try:
2701            rc, self.current_booleans = selinux.security_get_boolean_names()
2702            rc, ptype = selinux.selinux_getpolicytype()
2703        except:
2704            self.current_booleans = []
2705            ptype = None
2706
2707        if self.store == "" or self.store == ptype:
2708            self.modify_local = True
2709        else:
2710            self.modify_local = False
2711
2712    def __mod(self, name, value):
2713        name = selinux.selinux_boolean_sub(name)
2714
2715        (rc, k) = semanage_bool_key_create(self.sh, name)
2716        if rc < 0:
2717            raise ValueError(_("Could not create a key for %s") % name)
2718        (rc, exists) = semanage_bool_exists(self.sh, k)
2719        if rc < 0:
2720            raise ValueError(_("Could not check if boolean %s is defined") % name)
2721        if not exists:
2722            raise ValueError(_("Boolean %s is not defined") % name)
2723
2724        (rc, b) = semanage_bool_query(self.sh, k)
2725        if rc < 0:
2726            raise ValueError(_("Could not query file context %s") % name)
2727
2728        if value.upper() in self.dict:
2729            semanage_bool_set_value(b, self.dict[value.upper()])
2730        else:
2731            raise ValueError(_("You must specify one of the following values: %s") % ", ".join(self.dict.keys()))
2732
2733        if self.modify_local and name in self.current_booleans:
2734            rc = semanage_bool_set_active(self.sh, k, b)
2735            if rc < 0:
2736                raise ValueError(_("Could not set active value of boolean %s") % name)
2737        rc = semanage_bool_modify_local(self.sh, k, b)
2738        if rc < 0:
2739            raise ValueError(_("Could not modify boolean %s") % name)
2740        semanage_bool_key_free(k)
2741        semanage_bool_free(b)
2742
2743    def modify(self, name, value=None, use_file=False):
2744        self.begin()
2745        if use_file:
2746            fd = open(name)
2747            for b in fd.read().split("\n"):
2748                b = b.strip()
2749                if len(b) == 0:
2750                    continue
2751
2752                try:
2753                    boolname, val = b.split("=")
2754                except ValueError:
2755                    raise ValueError(_("Bad format %s: Record %s" % (name, b)))
2756                self.__mod(boolname.strip(), val.strip())
2757            fd.close()
2758        else:
2759            self.__mod(name, value)
2760
2761        self.commit()
2762
2763    def __delete(self, name):
2764        name = selinux.selinux_boolean_sub(name)
2765
2766        (rc, k) = semanage_bool_key_create(self.sh, name)
2767        if rc < 0:
2768            raise ValueError(_("Could not create a key for %s") % name)
2769        (rc, exists) = semanage_bool_exists(self.sh, k)
2770        if rc < 0:
2771            raise ValueError(_("Could not check if boolean %s is defined") % name)
2772        if not exists:
2773            raise ValueError(_("Boolean %s is not defined") % name)
2774
2775        (rc, exists) = semanage_bool_exists_local(self.sh, k)
2776        if rc < 0:
2777            raise ValueError(_("Could not check if boolean %s is defined") % name)
2778        if not exists:
2779            raise ValueError(_("Boolean %s is defined in policy, cannot be deleted") % name)
2780
2781        rc = semanage_bool_del_local(self.sh, k)
2782        if rc < 0:
2783            raise ValueError(_("Could not delete boolean %s") % name)
2784
2785        semanage_bool_key_free(k)
2786
2787    def delete(self, name):
2788        self.begin()
2789        self.__delete(name)
2790        self.commit()
2791
2792    def deleteall(self):
2793        (rc, self.blist) = semanage_bool_list_local(self.sh)
2794        if rc < 0:
2795            raise ValueError(_("Could not list booleans"))
2796
2797        self.begin()
2798
2799        for boolean in self.blist:
2800            name = semanage_bool_get_name(boolean)
2801            self.__delete(name)
2802
2803        self.commit()
2804
2805    def get_all(self, locallist=0):
2806        ddict = {}
2807        if locallist:
2808            (rc, self.blist) = semanage_bool_list_local(self.sh)
2809        else:
2810            (rc, self.blist) = semanage_bool_list(self.sh)
2811        if rc < 0:
2812            raise ValueError(_("Could not list booleans"))
2813
2814        for boolean in self.blist:
2815            value = []
2816            name = semanage_bool_get_name(boolean)
2817            value.append(semanage_bool_get_value(boolean))
2818            if self.modify_local and name in self.current_booleans:
2819                value.append(selinux.security_get_boolean_pending(name))
2820                value.append(selinux.security_get_boolean_active(name))
2821            else:
2822                value.append(value[0])
2823                value.append(value[0])
2824            ddict[name] = value
2825
2826        return ddict
2827
2828    def get_desc(self, name):
2829        name = selinux.selinux_boolean_sub(name)
2830        return sepolicy.boolean_desc(name)
2831
2832    def get_category(self, name):
2833        name = selinux.selinux_boolean_sub(name)
2834        return sepolicy.boolean_category(name)
2835
2836    def customized(self):
2837        l = []
2838        ddict = self.get_all(True)
2839        for k in sorted(ddict.keys()):
2840            if ddict[k]:
2841                l.append("-m -%s %s" % (ddict[k][2], k))
2842        return l
2843
2844    def list(self, heading=True, locallist=False, use_file=False):
2845        on_off = (_("off"), _("on"))
2846        if use_file:
2847            ddict = self.get_all(locallist)
2848            for k in sorted(ddict.keys()):
2849                if ddict[k]:
2850                    print("%s=%s" % (k, ddict[k][2]))
2851            return
2852        ddict = self.get_all(locallist)
2853        if len(ddict) == 0:
2854            return
2855
2856        if heading:
2857            print("%-30s %s  %s %s\n" % (_("SELinux boolean"), _("State"), _("Default"), _("Description")))
2858        for k in sorted(ddict.keys()):
2859            if ddict[k]:
2860                print("%-30s (%-5s,%5s)  %s" % (k, on_off[ddict[k][2]], on_off[ddict[k][0]], self.get_desc(k)))
2861