diff mbox series

python/semanage: Do not sort local fcontext definitions

Message ID 20240207150003.174701-1-vmojzis@redhat.com (mailing list archive)
State Accepted
Commit 1a3d58945b84
Delegated to: Petr Lautrbach
Headers show
Series python/semanage: Do not sort local fcontext definitions | expand

Commit Message

Vit Mojzis Feb. 7, 2024, 2:46 p.m. UTC
Entries in file_contexts.local are processed from the most recent one to
the oldest, with first match being used. Therefore it is important to
preserve their order when listing (semanage fcontext -lC) and exporting
(semanage export).

Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
---
Not sure if this is the best solution since the local file context
customizations are still sorted in the output of "semanage fcontext -l".
Adding a new section for "Local file context changes" would make it
clear that such changes are treated differently, but it would make it
harder to find context definitions affecting specific path.
The most important part of this patch is the change to "customized"
since that stops "semanage export | semanage import" from reordering the
local customizations.

Note: The order of dictionary.keys() is only guaranteed in python 3.6+.

Note2: The change to fcontextPage can only be seen when the user
disables ordering by "File specification" column, which is enabled by
defalut.

 gui/fcontextPage.py         | 6 +++++-
 python/semanage/seobject.py | 9 +++++++--
 2 files changed, 12 insertions(+), 3 deletions(-)

Comments

Petr Lautrbach Feb. 14, 2024, 5:12 p.m. UTC | #1
Vit Mojzis <vmojzis@redhat.com> writes:

> Entries in file_contexts.local are processed from the most recent one to
> the oldest, with first match being used. Therefore it is important to
> preserve their order when listing (semanage fcontext -lC) and exporting
> (semanage export).
>
> Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
>

I think it's good approach. I just hit the following ui issue:


[root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t '/opt/selinux_testing(/.*)?'
[root@localhost ~]# semanage fcontext -a -t httpd_sys_content_rw_t '/opt/selinux_testing/webroot(/.*)?'
[root@localhost ~]# semanage fcontext -a -t httpd_log_t '/opt/selinux_testing/logs(/.*)?'
[root@localhost ~]# semanage fcontext -l -C
SELinux fcontext                                   type               Context

/opt/selinux_testing(/.*)?                         all files          system_u:object_r:httpd_sys_content_t:s0 
/opt/selinux_testing/webroot(/.*)?                 all files          system_u:object_r:httpd_sys_rw_content_t:s0 
/opt/selinux_testing/logs(/.*)?                    all files          system_u:object_r:httpd_log_t:s0

[root@localhost ~]# matchpathcon /opt/selinux_testing/logs /opt/selinux_testing/webroot/
/opt/selinux_testing/logs       system_u:object_r:httpd_log_t:s0
/opt/selinux_testing/webroot    system_u:object_r:httpd_sys_rw_content_t:s0


If it's first match, I'd expect that both would be matched with
'/opt/selinux_testing(/.*)?' -> httpd_sys_content_t



[root@localhost ~]# semanage fcontext -d '/opt/selinux_testing(/.*)?'
[root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t '/opt/selinux_testing(/.*)?'
[root@localhost ~]# semanage fcontext -l -C
SELinux fcontext                                   type               Context

/opt/selinux_testing/webroot(/.*)?                 all files          system_u:object_r:httpd_sys_rw_content_t:s0 
/opt/selinux_testing/logs(/.*)?                    all files          system_u:object_r:httpd_log_t:s0 
/opt/selinux_testing(/.*)?                         all files          system_u:object_r:httpd_sys_content_t:s0

[root@localhost ~]# matchpathcon /opt/selinux_testing/logs /opt/selinux_testing/webroot/
/opt/selinux_testing/logs       system_u:object_r:httpd_sys_content_t:s0
/opt/selinux_testing/webroot    system_u:object_r:httpd_sys_content_t:s0

And here it looks like it should match webroot, resp logs.


So it's first match but from bottom to top. It kind of make sense as the
last added item is at bottom. OTOH people generally reads from top to
bottom.

What do you think?





> ---
> Not sure if this is the best solution since the local file context
> customizations are still sorted in the output of "semanage fcontext -l".
> Adding a new section for "Local file context changes" would make it
> clear that such changes are treated differently, but it would make it
> harder to find context definitions affecting specific path.
> The most important part of this patch is the change to "customized"
> since that stops "semanage export | semanage import" from reordering the
> local customizations.
>
> Note: The order of dictionary.keys() is only guaranteed in python 3.6+.
>
> Note2: The change to fcontextPage can only be seen when the user
> disables ordering by "File specification" column, which is enabled by
> defalut.
>
>  gui/fcontextPage.py         | 6 +++++-
>  python/semanage/seobject.py | 9 +++++++--
>  2 files changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/gui/fcontextPage.py b/gui/fcontextPage.py
> index 767664f2..c88df580 100644
> --- a/gui/fcontextPage.py
> +++ b/gui/fcontextPage.py
> @@ -133,7 +133,11 @@ class fcontextPage(semanagePage):
>          self.fcontext = seobject.fcontextRecords()
>          self.store.clear()
>          fcon_dict = self.fcontext.get_all(self.local)
> -        for k in sorted(fcon_dict.keys()):
> +        if self.local:
> +            fkeys = fcon_dict.keys()
> +        else:
> +            fkeys = sorted(fcon_dict.keys())
> +        for k in fkeys:
>              if not self.match(fcon_dict, k, filter):
>                  continue
>              iter = self.store.append()
> diff --git a/python/semanage/seobject.py b/python/semanage/seobject.py
> index dfb15b1d..25ec4315 100644
> --- a/python/semanage/seobject.py
> +++ b/python/semanage/seobject.py
> @@ -2735,7 +2735,7 @@ class fcontextRecords(semanageRecords):
>      def customized(self):
>          l = []
>          fcon_dict = self.get_all(True)
> -        for k in sorted(fcon_dict.keys()):
> +        for k in fcon_dict.keys():
>              if fcon_dict[k]:
>                  if fcon_dict[k][3]:
>                      l.append("-a -f %s -t %s -r '%s' '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], fcon_dict[k][3], k[0]))
> @@ -2752,7 +2752,12 @@ class fcontextRecords(semanageRecords):
>          if len(fcon_dict) != 0:
>              if heading:
>                  print("%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context")))
> -            for k in sorted(fcon_dict.keys()):
> +            # do not sort local customizations since they are evaluated based on the order they where added in
> +            if locallist:
> +                fkeys = fcon_dict.keys()
> +            else:
> +                fkeys = sorted(fcon_dict.keys())
> +            for k in fkeys:
>                  if fcon_dict[k]:
>                      if is_mls_enabled:
>                          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)))
> -- 
> 2.43.0
Vit Mojzis Feb. 16, 2024, 1:12 p.m. UTC | #2
On 2/14/24 18:12, Petr Lautrbach wrote:
> Vit Mojzis <vmojzis@redhat.com> writes:
> 
>> Entries in file_contexts.local are processed from the most recent one to
>> the oldest, with first match being used. Therefore it is important to
>> preserve their order when listing (semanage fcontext -lC) and exporting
>> (semanage export).
>>
>> Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
>>
> 
> I think it's good approach. I just hit the following ui issue:
> 
> 
> [root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t '/opt/selinux_testing(/.*)?'
> [root@localhost ~]# semanage fcontext -a -t httpd_sys_content_rw_t '/opt/selinux_testing/webroot(/.*)?'
> [root@localhost ~]# semanage fcontext -a -t httpd_log_t '/opt/selinux_testing/logs(/.*)?'
> [root@localhost ~]# semanage fcontext -l -C
> SELinux fcontext                                   type               Context
> 
> /opt/selinux_testing(/.*)?                         all files          system_u:object_r:httpd_sys_content_t:s0
> /opt/selinux_testing/webroot(/.*)?                 all files          system_u:object_r:httpd_sys_rw_content_t:s0
> /opt/selinux_testing/logs(/.*)?                    all files          system_u:object_r:httpd_log_t:s0
> 
> [root@localhost ~]# matchpathcon /opt/selinux_testing/logs /opt/selinux_testing/webroot/
> /opt/selinux_testing/logs       system_u:object_r:httpd_log_t:s0
> /opt/selinux_testing/webroot    system_u:object_r:httpd_sys_rw_content_t:s0
> 
> 
> If it's first match, I'd expect that both would be matched with
> '/opt/selinux_testing(/.*)?' -> httpd_sys_content_ >
> 
> 
> [root@localhost ~]# semanage fcontext -d '/opt/selinux_testing(/.*)?'
> [root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t '/opt/selinux_testing(/.*)?'
> [root@localhost ~]# semanage fcontext -l -C
> SELinux fcontext                                   type               Context
> 
> /opt/selinux_testing/webroot(/.*)?                 all files          system_u:object_r:httpd_sys_rw_content_t:s0
> /opt/selinux_testing/logs(/.*)?                    all files          system_u:object_r:httpd_log_t:s0
> /opt/selinux_testing(/.*)?                         all files          system_u:object_r:httpd_sys_content_t:s0
> 
> [root@localhost ~]# matchpathcon /opt/selinux_testing/logs /opt/selinux_testing/webroot/
> /opt/selinux_testing/logs       system_u:object_r:httpd_sys_content_t:s0
> /opt/selinux_testing/webroot    system_u:object_r:httpd_sys_content_t:s0
> 
> And here it looks like it should match webroot, resp logs.
> 
> 
> So it's first match but from bottom to top. It kind of make sense as the
> last added item is at bottom. OTOH people generally reads from top to
> bottom.
> 
> What do you think?

To me it makes more sense to leave it as is, since the fist added item 
is at the top (same as file_contexts.local file).
The man page also says that entries are processed from the most recent 
one to the oldest, so you should read them from the bottom up.

But I'm happy to reverse the order if you feel it will be more intuitive 
for users.

Vit

> 
> 
> 
> 
> 
>> ---
>> Not sure if this is the best solution since the local file context
>> customizations are still sorted in the output of "semanage fcontext -l".
>> Adding a new section for "Local file context changes" would make it
>> clear that such changes are treated differently, but it would make it
>> harder to find context definitions affecting specific path.
>> The most important part of this patch is the change to "customized"
>> since that stops "semanage export | semanage import" from reordering the
>> local customizations.
>>
>> Note: The order of dictionary.keys() is only guaranteed in python 3.6+.
>>
>> Note2: The change to fcontextPage can only be seen when the user
>> disables ordering by "File specification" column, which is enabled by
>> defalut.
>>
>>   gui/fcontextPage.py         | 6 +++++-
>>   python/semanage/seobject.py | 9 +++++++--
>>   2 files changed, 12 insertions(+), 3 deletions(-)
>>
>> diff --git a/gui/fcontextPage.py b/gui/fcontextPage.py
>> index 767664f2..c88df580 100644
>> --- a/gui/fcontextPage.py
>> +++ b/gui/fcontextPage.py
>> @@ -133,7 +133,11 @@ class fcontextPage(semanagePage):
>>           self.fcontext = seobject.fcontextRecords()
>>           self.store.clear()
>>           fcon_dict = self.fcontext.get_all(self.local)
>> -        for k in sorted(fcon_dict.keys()):
>> +        if self.local:
>> +            fkeys = fcon_dict.keys()
>> +        else:
>> +            fkeys = sorted(fcon_dict.keys())
>> +        for k in fkeys:
>>               if not self.match(fcon_dict, k, filter):
>>                   continue
>>               iter = self.store.append()
>> diff --git a/python/semanage/seobject.py b/python/semanage/seobject.py
>> index dfb15b1d..25ec4315 100644
>> --- a/python/semanage/seobject.py
>> +++ b/python/semanage/seobject.py
>> @@ -2735,7 +2735,7 @@ class fcontextRecords(semanageRecords):
>>       def customized(self):
>>           l = []
>>           fcon_dict = self.get_all(True)
>> -        for k in sorted(fcon_dict.keys()):
>> +        for k in fcon_dict.keys():
>>               if fcon_dict[k]:
>>                   if fcon_dict[k][3]:
>>                       l.append("-a -f %s -t %s -r '%s' '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], fcon_dict[k][3], k[0]))
>> @@ -2752,7 +2752,12 @@ class fcontextRecords(semanageRecords):
>>           if len(fcon_dict) != 0:
>>               if heading:
>>                   print("%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context")))
>> -            for k in sorted(fcon_dict.keys()):
>> +            # do not sort local customizations since they are evaluated based on the order they where added in
>> +            if locallist:
>> +                fkeys = fcon_dict.keys()
>> +            else:
>> +                fkeys = sorted(fcon_dict.keys())
>> +            for k in fkeys:
>>                   if fcon_dict[k]:
>>                       if is_mls_enabled:
>>                           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)))
>> -- 
>> 2.43.0
>
James Carter Feb. 29, 2024, 2:15 p.m. UTC | #3
On Fri, Feb 16, 2024 at 8:13 AM Vit Mojzis <vmojzis@redhat.com> wrote:
>
> On 2/14/24 18:12, Petr Lautrbach wrote:
> > Vit Mojzis <vmojzis@redhat.com> writes:
> >
> >> Entries in file_contexts.local are processed from the most recent one to
> >> the oldest, with first match being used. Therefore it is important to
> >> preserve their order when listing (semanage fcontext -lC) and exporting
> >> (semanage export).
> >>
> >> Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
> >>
> >
> > I think it's good approach. I just hit the following ui issue:
> >
> >
> > [root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t '/opt/selinux_testing(/.*)?'
> > [root@localhost ~]# semanage fcontext -a -t httpd_sys_content_rw_t '/opt/selinux_testing/webroot(/.*)?'
> > [root@localhost ~]# semanage fcontext -a -t httpd_log_t '/opt/selinux_testing/logs(/.*)?'
> > [root@localhost ~]# semanage fcontext -l -C
> > SELinux fcontext                                   type               Context
> >
> > /opt/selinux_testing(/.*)?                         all files          system_u:object_r:httpd_sys_content_t:s0
> > /opt/selinux_testing/webroot(/.*)?                 all files          system_u:object_r:httpd_sys_rw_content_t:s0
> > /opt/selinux_testing/logs(/.*)?                    all files          system_u:object_r:httpd_log_t:s0
> >
> > [root@localhost ~]# matchpathcon /opt/selinux_testing/logs /opt/selinux_testing/webroot/
> > /opt/selinux_testing/logs       system_u:object_r:httpd_log_t:s0
> > /opt/selinux_testing/webroot    system_u:object_r:httpd_sys_rw_content_t:s0
> >
> >
> > If it's first match, I'd expect that both would be matched with
> > '/opt/selinux_testing(/.*)?' -> httpd_sys_content_ >
> >
> >
> > [root@localhost ~]# semanage fcontext -d '/opt/selinux_testing(/.*)?'
> > [root@localhost ~]# semanage fcontext -a -t httpd_sys_content_t '/opt/selinux_testing(/.*)?'
> > [root@localhost ~]# semanage fcontext -l -C
> > SELinux fcontext                                   type               Context
> >
> > /opt/selinux_testing/webroot(/.*)?                 all files          system_u:object_r:httpd_sys_rw_content_t:s0
> > /opt/selinux_testing/logs(/.*)?                    all files          system_u:object_r:httpd_log_t:s0
> > /opt/selinux_testing(/.*)?                         all files          system_u:object_r:httpd_sys_content_t:s0
> >
> > [root@localhost ~]# matchpathcon /opt/selinux_testing/logs /opt/selinux_testing/webroot/
> > /opt/selinux_testing/logs       system_u:object_r:httpd_sys_content_t:s0
> > /opt/selinux_testing/webroot    system_u:object_r:httpd_sys_content_t:s0
> >
> > And here it looks like it should match webroot, resp logs.
> >
> >
> > So it's first match but from bottom to top. It kind of make sense as the
> > last added item is at bottom. OTOH people generally reads from top to
> > bottom.
> >
> > What do you think?
>
> To me it makes more sense to leave it as is, since the fist added item
> is at the top (same as file_contexts.local file).
> The man page also says that entries are processed from the most recent
> one to the oldest, so you should read them from the bottom up.
>
> But I'm happy to reverse the order if you feel it will be more intuitive
> for users.
>
> Vit
>

The order with the most recently added item at the bottom makes the
most sense to me.
Jim


> >
> >
> >
> >
> >
> >> ---
> >> Not sure if this is the best solution since the local file context
> >> customizations are still sorted in the output of "semanage fcontext -l".
> >> Adding a new section for "Local file context changes" would make it
> >> clear that such changes are treated differently, but it would make it
> >> harder to find context definitions affecting specific path.
> >> The most important part of this patch is the change to "customized"
> >> since that stops "semanage export | semanage import" from reordering the
> >> local customizations.
> >>
> >> Note: The order of dictionary.keys() is only guaranteed in python 3.6+.
> >>
> >> Note2: The change to fcontextPage can only be seen when the user
> >> disables ordering by "File specification" column, which is enabled by
> >> defalut.
> >>
> >>   gui/fcontextPage.py         | 6 +++++-
> >>   python/semanage/seobject.py | 9 +++++++--
> >>   2 files changed, 12 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/gui/fcontextPage.py b/gui/fcontextPage.py
> >> index 767664f2..c88df580 100644
> >> --- a/gui/fcontextPage.py
> >> +++ b/gui/fcontextPage.py
> >> @@ -133,7 +133,11 @@ class fcontextPage(semanagePage):
> >>           self.fcontext = seobject.fcontextRecords()
> >>           self.store.clear()
> >>           fcon_dict = self.fcontext.get_all(self.local)
> >> -        for k in sorted(fcon_dict.keys()):
> >> +        if self.local:
> >> +            fkeys = fcon_dict.keys()
> >> +        else:
> >> +            fkeys = sorted(fcon_dict.keys())
> >> +        for k in fkeys:
> >>               if not self.match(fcon_dict, k, filter):
> >>                   continue
> >>               iter = self.store.append()
> >> diff --git a/python/semanage/seobject.py b/python/semanage/seobject.py
> >> index dfb15b1d..25ec4315 100644
> >> --- a/python/semanage/seobject.py
> >> +++ b/python/semanage/seobject.py
> >> @@ -2735,7 +2735,7 @@ class fcontextRecords(semanageRecords):
> >>       def customized(self):
> >>           l = []
> >>           fcon_dict = self.get_all(True)
> >> -        for k in sorted(fcon_dict.keys()):
> >> +        for k in fcon_dict.keys():
> >>               if fcon_dict[k]:
> >>                   if fcon_dict[k][3]:
> >>                       l.append("-a -f %s -t %s -r '%s' '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], fcon_dict[k][3], k[0]))
> >> @@ -2752,7 +2752,12 @@ class fcontextRecords(semanageRecords):
> >>           if len(fcon_dict) != 0:
> >>               if heading:
> >>                   print("%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context")))
> >> -            for k in sorted(fcon_dict.keys()):
> >> +            # do not sort local customizations since they are evaluated based on the order they where added in
> >> +            if locallist:
> >> +                fkeys = fcon_dict.keys()
> >> +            else:
> >> +                fkeys = sorted(fcon_dict.keys())
> >> +            for k in fkeys:
> >>                   if fcon_dict[k]:
> >>                       if is_mls_enabled:
> >>                           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)))
> >> --
> >> 2.43.0
> >
>
>
James Carter Feb. 29, 2024, 2:17 p.m. UTC | #4
On Wed, Feb 7, 2024 at 10:11 AM Vit Mojzis <vmojzis@redhat.com> wrote:
>
> Entries in file_contexts.local are processed from the most recent one to
> the oldest, with first match being used. Therefore it is important to
> preserve their order when listing (semanage fcontext -lC) and exporting
> (semanage export).
>
> Signed-off-by: Vit Mojzis <vmojzis@redhat.com>

Acked-by: James Carter <jwcart2@gmail.com>

> ---
> Not sure if this is the best solution since the local file context
> customizations are still sorted in the output of "semanage fcontext -l".
> Adding a new section for "Local file context changes" would make it
> clear that such changes are treated differently, but it would make it
> harder to find context definitions affecting specific path.
> The most important part of this patch is the change to "customized"
> since that stops "semanage export | semanage import" from reordering the
> local customizations.
>
> Note: The order of dictionary.keys() is only guaranteed in python 3.6+.
>
> Note2: The change to fcontextPage can only be seen when the user
> disables ordering by "File specification" column, which is enabled by
> defalut.
>
>  gui/fcontextPage.py         | 6 +++++-
>  python/semanage/seobject.py | 9 +++++++--
>  2 files changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/gui/fcontextPage.py b/gui/fcontextPage.py
> index 767664f2..c88df580 100644
> --- a/gui/fcontextPage.py
> +++ b/gui/fcontextPage.py
> @@ -133,7 +133,11 @@ class fcontextPage(semanagePage):
>          self.fcontext = seobject.fcontextRecords()
>          self.store.clear()
>          fcon_dict = self.fcontext.get_all(self.local)
> -        for k in sorted(fcon_dict.keys()):
> +        if self.local:
> +            fkeys = fcon_dict.keys()
> +        else:
> +            fkeys = sorted(fcon_dict.keys())
> +        for k in fkeys:
>              if not self.match(fcon_dict, k, filter):
>                  continue
>              iter = self.store.append()
> diff --git a/python/semanage/seobject.py b/python/semanage/seobject.py
> index dfb15b1d..25ec4315 100644
> --- a/python/semanage/seobject.py
> +++ b/python/semanage/seobject.py
> @@ -2735,7 +2735,7 @@ class fcontextRecords(semanageRecords):
>      def customized(self):
>          l = []
>          fcon_dict = self.get_all(True)
> -        for k in sorted(fcon_dict.keys()):
> +        for k in fcon_dict.keys():
>              if fcon_dict[k]:
>                  if fcon_dict[k][3]:
>                      l.append("-a -f %s -t %s -r '%s' '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], fcon_dict[k][3], k[0]))
> @@ -2752,7 +2752,12 @@ class fcontextRecords(semanageRecords):
>          if len(fcon_dict) != 0:
>              if heading:
>                  print("%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context")))
> -            for k in sorted(fcon_dict.keys()):
> +            # do not sort local customizations since they are evaluated based on the order they where added in
> +            if locallist:
> +                fkeys = fcon_dict.keys()
> +            else:
> +                fkeys = sorted(fcon_dict.keys())
> +            for k in fkeys:
>                  if fcon_dict[k]:
>                      if is_mls_enabled:
>                          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)))
> --
> 2.43.0
>
>
James Carter March 4, 2024, 7:16 p.m. UTC | #5
On Thu, Feb 29, 2024 at 9:17 AM James Carter <jwcart2@gmail.com> wrote:
>
> On Wed, Feb 7, 2024 at 10:11 AM Vit Mojzis <vmojzis@redhat.com> wrote:
> >
> > Entries in file_contexts.local are processed from the most recent one to
> > the oldest, with first match being used. Therefore it is important to
> > preserve their order when listing (semanage fcontext -lC) and exporting
> > (semanage export).
> >
> > Signed-off-by: Vit Mojzis <vmojzis@redhat.com>
>
> Acked-by: James Carter <jwcart2@gmail.com>
>

Merged.
Thanks,
Jim

> > ---
> > Not sure if this is the best solution since the local file context
> > customizations are still sorted in the output of "semanage fcontext -l".
> > Adding a new section for "Local file context changes" would make it
> > clear that such changes are treated differently, but it would make it
> > harder to find context definitions affecting specific path.
> > The most important part of this patch is the change to "customized"
> > since that stops "semanage export | semanage import" from reordering the
> > local customizations.
> >
> > Note: The order of dictionary.keys() is only guaranteed in python 3.6+.
> >
> > Note2: The change to fcontextPage can only be seen when the user
> > disables ordering by "File specification" column, which is enabled by
> > defalut.
> >
> >  gui/fcontextPage.py         | 6 +++++-
> >  python/semanage/seobject.py | 9 +++++++--
> >  2 files changed, 12 insertions(+), 3 deletions(-)
> >
> > diff --git a/gui/fcontextPage.py b/gui/fcontextPage.py
> > index 767664f2..c88df580 100644
> > --- a/gui/fcontextPage.py
> > +++ b/gui/fcontextPage.py
> > @@ -133,7 +133,11 @@ class fcontextPage(semanagePage):
> >          self.fcontext = seobject.fcontextRecords()
> >          self.store.clear()
> >          fcon_dict = self.fcontext.get_all(self.local)
> > -        for k in sorted(fcon_dict.keys()):
> > +        if self.local:
> > +            fkeys = fcon_dict.keys()
> > +        else:
> > +            fkeys = sorted(fcon_dict.keys())
> > +        for k in fkeys:
> >              if not self.match(fcon_dict, k, filter):
> >                  continue
> >              iter = self.store.append()
> > diff --git a/python/semanage/seobject.py b/python/semanage/seobject.py
> > index dfb15b1d..25ec4315 100644
> > --- a/python/semanage/seobject.py
> > +++ b/python/semanage/seobject.py
> > @@ -2735,7 +2735,7 @@ class fcontextRecords(semanageRecords):
> >      def customized(self):
> >          l = []
> >          fcon_dict = self.get_all(True)
> > -        for k in sorted(fcon_dict.keys()):
> > +        for k in fcon_dict.keys():
> >              if fcon_dict[k]:
> >                  if fcon_dict[k][3]:
> >                      l.append("-a -f %s -t %s -r '%s' '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], fcon_dict[k][3], k[0]))
> > @@ -2752,7 +2752,12 @@ class fcontextRecords(semanageRecords):
> >          if len(fcon_dict) != 0:
> >              if heading:
> >                  print("%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context")))
> > -            for k in sorted(fcon_dict.keys()):
> > +            # do not sort local customizations since they are evaluated based on the order they where added in
> > +            if locallist:
> > +                fkeys = fcon_dict.keys()
> > +            else:
> > +                fkeys = sorted(fcon_dict.keys())
> > +            for k in fkeys:
> >                  if fcon_dict[k]:
> >                      if is_mls_enabled:
> >                          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)))
> > --
> > 2.43.0
> >
> >
diff mbox series

Patch

diff --git a/gui/fcontextPage.py b/gui/fcontextPage.py
index 767664f2..c88df580 100644
--- a/gui/fcontextPage.py
+++ b/gui/fcontextPage.py
@@ -133,7 +133,11 @@  class fcontextPage(semanagePage):
         self.fcontext = seobject.fcontextRecords()
         self.store.clear()
         fcon_dict = self.fcontext.get_all(self.local)
-        for k in sorted(fcon_dict.keys()):
+        if self.local:
+            fkeys = fcon_dict.keys()
+        else:
+            fkeys = sorted(fcon_dict.keys())
+        for k in fkeys:
             if not self.match(fcon_dict, k, filter):
                 continue
             iter = self.store.append()
diff --git a/python/semanage/seobject.py b/python/semanage/seobject.py
index dfb15b1d..25ec4315 100644
--- a/python/semanage/seobject.py
+++ b/python/semanage/seobject.py
@@ -2735,7 +2735,7 @@  class fcontextRecords(semanageRecords):
     def customized(self):
         l = []
         fcon_dict = self.get_all(True)
-        for k in sorted(fcon_dict.keys()):
+        for k in fcon_dict.keys():
             if fcon_dict[k]:
                 if fcon_dict[k][3]:
                     l.append("-a -f %s -t %s -r '%s' '%s'" % (file_type_str_to_option[k[1]], fcon_dict[k][2], fcon_dict[k][3], k[0]))
@@ -2752,7 +2752,12 @@  class fcontextRecords(semanageRecords):
         if len(fcon_dict) != 0:
             if heading:
                 print("%-50s %-18s %s\n" % (_("SELinux fcontext"), _("type"), _("Context")))
-            for k in sorted(fcon_dict.keys()):
+            # do not sort local customizations since they are evaluated based on the order they where added in
+            if locallist:
+                fkeys = fcon_dict.keys()
+            else:
+                fkeys = sorted(fcon_dict.keys())
+            for k in fkeys:
                 if fcon_dict[k]:
                     if is_mls_enabled:
                         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)))