Skip to content

Conversation

@nrwahl2
Copy link
Contributor

@nrwahl2 nrwahl2 commented Dec 26, 2025

No description provided.

Don't do other best practices yet. Those will be in upcoming commits.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Also use const for the GList iterator and the xml_acl_t variable.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
If the "else"/"docpriv->acls == NULL" block was executed, then target
was set to NULL, which meant we wouldn't do anything else before
returning true.

Also drop some redundancies:
* The dropped trace message doesn't seem very helpul.
* pcmk__xml_copy() is guaranteed to return non-NULL if its second
  argument is non-NULL.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Nothing in the loop can set it to NULL.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Only element nodes have attributes.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Call pcmk__xe_remove_matching_attrs(), which is made for this purpose.
Write a simple match function to ensure we only remove non-ID
attributes.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
This might lead to reading children that should be denied.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
And rename pcmk__apply_acl() to pcmk__apply_acls().

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
The pcmk__if_tracing() block makes sense but it feels like premature
optimization and makes the code harder to read. I'm not worried about
the overhead of allocating and freeing a small GString each time we
apply an ACL.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Also rename a variable and drop a trace message that seems unhelpful.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
We drop a trace log in order to do this. To get the number of matches
from pcmk__xpath_foreach_result(), we'd have to pass a struct as user
data to hold both the ACL itself and the match count. That doesn't seem
worth the trouble. We still have the trace message after applying an ACL
to a particular match.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
And rename to pcmk__unpack_acls(). In general, we assume that an XML
node has a non-NULL doc and that its doc has a non-NULL _private field.
If we ever want to start checking that (in case a node somehow
originated outside of pcmk__xe_create()), we should do it more broadly.

The two callers already ensure that target is not NULL.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
It is possible that these values won't get used, but fetching and
setting them is pretty lightweight.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Or at least try to clarify it a bit, by returning early if not target or
group.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Use the second argument of pcmk__xe_first_child() and pcmk__xe_next() to
specify what type of element to get (PCMK_XE_ACL_ROLE).

Also unindent a block with pcmk__trace() in it, and use pcmk__xe_id().

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
An acl_permission element's ID is currently used only for logging. So we
can be permissive and allow this. It seems that our usual approach to
things that the schema doesn't allow is to continue processing them if
it's possible (for example, if it doesn't result in a broken reference).
So warn here.

For missing or invalid "kind" attribute, we have to ignore the element,
so set a config error.

It doesn't look as if we're very consistent about when we set warnings
vs. errors, so I'm just doing what feels like it makes the most sense.
We could just as well call all of these warnings or call all of these
errors.

Also, log the parent type and ID parenthetically for errors other than
missing ID. If we proceeded with unpacking an acl_permission element
without an ID, we want any further log messages to have some identifying
information about where or what the acl_permission element is. It
doesn't hurt to log this even if the acl_permission's ID is set.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
So that it's beneath its helpers. No code changes otherwise.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Further improvements are coming. For now, we have a recursive call and a
new (temporary) forward declaration of parse_acl_entry().

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
This involves removing some const qualifiers, because
pcmk__xpath_search() takes a non-const xmlDoc.

Our convention is to use a non-const pointer argument whenever we use
one of the argument's fields (in this case, the doc field) as a non-
const.

At first, this feels like a use case for pcmk__xe_resolve_idref(), but
that function would need to be extended in at least two ways:
* It would need to match a PCMK_XA_ID attribute instead of a
  PCMK_XA_ID_REF attribute.
* It would need to match a referenced element whose type differs from
  that of the referencing element (PCMK_XE_ACL_ROLE vs. PCMK_XE_ROLE).

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
And rename to unpack_acl_target(). We could simplify further, except
that we've been allowing <acl_target> and <acl_group> elements to
contain <acl_permission> elements and unpacking them in violation of
the schema.

I've marked this as "fix" to add to the change log, because it does
change behavior: if <role> elements are nested within <acl_role>
elements, they will now be ignored. They should never have been
configured in the first place.

Thus far, I have made an effort to maintain backward compatibility even
for configurations that the schema doesn't allow. I have not done so
here. A workaround would risk an infinite loop of following references,
and trying to prevent that is not worth the trouble.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
After significant refactoring, I feel more confident about when a given
function is always called with a given element type.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
If show_xml_element() wanted to show an attribute with a NULL value, it
would use "<null>" for the value. This didn't make sense. Immediately
prior, we XML-escaped the value. "<null>" has XML special characters and
would need to be escaped in order to be valid. (Of course,
pcmk__xml_show() and its helpers are currently used only with text-like
output formats; for those, having perfectly valid XML is less
important.)

We could use a different fallback string, such as "(null)". However, for
any XML element that we create, every attribute in its properties list
should have a non-NULL value. So this should have little or no practical
effect. "<null>" was a fallback in case of bugs, strange inputs via the
public API (for example, do_crm_log_xml()), or other unexpected
scenarios. As far as I know, we never promised that NULL attributes
would be represented in the output. So I prefer to simply not show them.

This will soon allow us to call pcmk__xml_dump_attr() in
show_xml_element().

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
They do the same thing for attributes, except that show_xml_element()
hides hidden attributes. If pcmk__dump_xml_attr() ever hides hidden
attributes, then we can reduce duplication even further. For now, I'm
not sure what side effects might occur if we hide attributs in
pcmk__dump_xml_attr().

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
An attribute's value really shouldn't be NULL unless the XML came from
public API (and even then, it would be strange). pcmk__dump_xml_attr()
already ignores attributes with NULL values. So dropping the NULL check
simply means that if an attribute's name is in PCMK__XA_HIDDEN and its
value is NULL, we'll now show "*****" for its value instead of skipping
it. That should basically never happen in practice, and if it does, this
behavior is arguably more correct anyway.

Also, an attribute's name can't be empty in valid XML.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
From data to xml. I want to use the name data for something else in an
upcoming commit, and we typically use "xml" for xmlNode * arguments.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
And make it static.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
This is similar to pcmk__xml_tree_foreach(), except for the following:
* It removes a node and its subtree if the function returns true.
  pcmk__xml_tree_foreach() would have a use-after-free if its function
  freed its xmlNode * argument. (This has not been observed with any
  existing calls.)
* pcmk__xml_tree_foreach_remove() currently offers no way to stop
  iterating. The function's return value instead tells us whether to
  remove a node. Obviously we don't recurse down a freed node's subtree,
  however.
* The function does not currently accept user data. A user data argument
  may be added later if needed.
* pcmk__xml_tree_foreach_remove() returns void. We can later return a
  boolean or integer value if we need to know whether any nodes were
  removed.

Nothing uses this yet.

Also correct the Doxygen of pcmk__xml_tree_foreach() (fn is an [in]
parameter) and add a note that fn may not remove its argument.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
And change its name to pcmk__check_creation_acls(), since it's checking
rather than applying ACLs.

Use pcmk__xml_tree_foreach_remove() to "drive" the recursion, instead of
building it into pcmk__check_creation_acls(). Functionize the main logic
into the helper check_creation_disallowed().

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
If xml->doc or xml->doc->_private were NULL, then we would not have
called this function. See pcmk__xml_doc_all_flags_set().

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Nothing uses this yet.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Use pcmk__xpath_foreach_result(). Also drop a trace message, for two
reasons:
* We don't have easy access to num_results anymore. (We'd have to get it
  via a counter variable or something.)
* The message tells us how many nodes were filtered by a given XPath,
  but not which nodes. So it doesn't seem especially useful. If we want
  tracing for ACL filtering (which seems like a reasonable thing to
  want), then we should make it more granular so that it's informative.

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
acl_filter_match() can free XPath result elements, so it's safer to
process XPath search results in reverse document order. See Doxygen for
pcmk__xpath_foreach_result().

Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Signed-off-by: Reid Wahl <nrwahl@protonmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant