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