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