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