|
10 | 10 | #include <crm_internal.h> |
11 | 11 |
|
12 | 12 | #include <stdbool.h> |
| 13 | +#include <stdint.h> // uint32_t |
13 | 14 | #include <stdio.h> |
14 | 15 | #include <sys/types.h> |
15 | 16 | #include <pwd.h> |
@@ -737,24 +738,55 @@ pcmk__enable_acls(xmlDoc *source, xmlDoc *target, const char *user) |
737 | 738 | pcmk__apply_acls(target); |
738 | 739 | } |
739 | 740 |
|
740 | | -static inline bool |
741 | | -test_acl_mode(enum pcmk__xml_flags allowed, enum pcmk__xml_flags requested) |
| 741 | +/*! |
| 742 | + * \internal |
| 743 | + * \brief Check whether a flag group allows the requested ACL access |
| 744 | + * |
| 745 | + * At most one ACL mode flag should be set in the flag group, but this function |
| 746 | + * defines an order of precedence multiple flags are set. |
| 747 | + * |
| 748 | + * \param[in] flags Group of <tt>enum pcmk__xml_flags</tt> |
| 749 | + * \param[in] mode Requested access type (one of \c pcmk__xf_acl_read, |
| 750 | + * \c pcmk__xf_acl_write, or \c pcmk__xf_acl_create) |
| 751 | + * |
| 752 | + * \return \c true if \p flags allows the access type in \p mode, or \c false |
| 753 | + * otherwise |
| 754 | + * |
| 755 | + * \note \c pcmk__xf_acl_deny is an allowed value for \p mode, but it would make |
| 756 | + * no sense. This function always returns \c false if \c pcmk__xf_acl_deny |
| 757 | + * is set in \p flags. |
| 758 | + */ |
| 759 | +static bool |
| 760 | +is_mode_allowed(uint32_t flags, enum pcmk__xml_flags mode) |
742 | 761 | { |
743 | | - if (pcmk__is_set(allowed, pcmk__xf_acl_deny)) { |
| 762 | + if (pcmk__is_set(flags, pcmk__xf_acl_deny)) { |
| 763 | + // All access is denied |
744 | 764 | return false; |
| 765 | + } |
745 | 766 |
|
746 | | - } else if (pcmk__all_flags_set(allowed, requested)) { |
| 767 | + if (pcmk__is_set(flags, mode)) { |
| 768 | + // The access we requested is explicitly allowed |
747 | 769 | return true; |
| 770 | + } |
748 | 771 |
|
749 | | - } else if (pcmk__is_set(requested, pcmk__xf_acl_read) |
750 | | - && pcmk__is_set(allowed, pcmk__xf_acl_write)) { |
| 772 | + if ((mode == pcmk__xf_acl_read) |
| 773 | + && pcmk__is_set(flags, pcmk__xf_acl_write)) { |
| 774 | + |
| 775 | + // Write access provides read access |
751 | 776 | return true; |
| 777 | + } |
752 | 778 |
|
753 | | - } else if (pcmk__is_set(requested, pcmk__xf_acl_create) |
754 | | - && pcmk__any_flags_set(allowed, |
755 | | - pcmk__xf_acl_write|pcmk__xf_created)) { |
| 779 | + if ((mode == pcmk__xf_acl_create) |
| 780 | + && pcmk__any_flags_set(flags, pcmk__xf_acl_write|pcmk__xf_created)) { |
| 781 | + |
| 782 | + /* Write access provides create access. |
| 783 | + * |
| 784 | + * @TODO Why does the \c pcmk__xf_created flag provide create access? |
| 785 | + * This was introduced by commit e2ed85fe. |
| 786 | + */ |
756 | 787 | return true; |
757 | 788 | } |
| 789 | + |
758 | 790 | return false; |
759 | 791 | } |
760 | 792 |
|
@@ -794,7 +826,7 @@ purge_xml_attributes(xmlNode *xml) |
794 | 826 | bool readable_children = false; |
795 | 827 | xml_node_private_t *nodepriv = xml->_private; |
796 | 828 |
|
797 | | - if (test_acl_mode(nodepriv->flags, pcmk__xf_acl_read)) { |
| 829 | + if (is_mode_allowed(nodepriv->flags, pcmk__xf_acl_read)) { |
798 | 830 | pcmk__trace("%s[@" PCMK_XA_ID "=%s] is readable", xml->name, |
799 | 831 | pcmk__xe_id(xml)); |
800 | 832 | return true; |
@@ -1122,7 +1154,7 @@ pcmk__check_acl(xmlNode *xml, const char *attr_name, enum pcmk__xml_flags mode) |
1122 | 1154 |
|
1123 | 1155 | const xml_node_private_t *nodepriv = parent->_private; |
1124 | 1156 |
|
1125 | | - if (test_acl_mode(nodepriv->flags, mode)) { |
| 1157 | + if (is_mode_allowed(nodepriv->flags, mode)) { |
1126 | 1158 | return true; |
1127 | 1159 | } |
1128 | 1160 |
|
|
0 commit comments