diff --git a/lib/pacemaker/pcmk_acl.c b/lib/pacemaker/pcmk_acl.c
index 442c4769d9..e88d7805c3 100644
--- a/lib/pacemaker/pcmk_acl.c
+++ b/lib/pacemaker/pcmk_acl.c
@@ -1,324 +1,326 @@
 /*
  * Copyright 2004-2021 the Pacemaker project contributors
  *
  * The version control history for this file may have further details.
  *
  * This source code is licensed under the GNU Lesser General Public License
  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
  */
 
 #include <crm_internal.h>
 
 #include <stdio.h>
 #include <sys/types.h>
 #include <pwd.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
 
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 #include <libxml/xpath.h>
 #if HAVE_LIBXSLT
 #  include <libxslt/transform.h>
 #  include <libxslt/variables.h>
 #  include <libxslt/xsltutils.h>
 #endif
 
 #include <crm/crm.h>
 #include <crm/msg_xml.h>
 #include <crm/common/xml.h>
 #include <crm/common/xml_internal.h>
 #include <crm/common/internal.h>
 
 #include <pacemaker-internal.h>
 
 #define ACL_NS_PREFIX "http://clusterlabs.org/ns/pacemaker/access/"
 #define ACL_NS_Q_PREFIX  "pcmk-access-"
 #define ACL_NS_Q_WRITABLE (const xmlChar *) ACL_NS_Q_PREFIX   "writable"
 #define ACL_NS_Q_READABLE (const xmlChar *) ACL_NS_Q_PREFIX   "readable"
 #define ACL_NS_Q_DENIED   (const xmlChar *) ACL_NS_Q_PREFIX   "denied"
 
 static const xmlChar *NS_WRITABLE = (const xmlChar *) ACL_NS_PREFIX "writable";
 static const xmlChar *NS_READABLE = (const xmlChar *) ACL_NS_PREFIX "readable";
 static const xmlChar *NS_DENIED =   (const xmlChar *) ACL_NS_PREFIX "denied";
 
 static int
 pcmk__eval_acl_as_namespaces_2(xmlNode *xml_modify)
 {
 
     static xmlNs *ns_recycle_writable = NULL,
                  *ns_recycle_readable = NULL,
                  *ns_recycle_denied = NULL;
     static const xmlDoc *prev_doc = NULL;
 
     xmlNode *i_node = NULL;
     const xmlChar *ns;
-    int ret = 0;
+    int ret = EINVAL; // nodes have not been processed yet
 
     if (prev_doc == NULL || prev_doc != xml_modify->doc) {
         prev_doc = xml_modify->doc;
         ns_recycle_writable = ns_recycle_readable = ns_recycle_denied = NULL;
     }
 
     for (i_node = xml_modify; i_node != NULL; i_node = i_node->next) {
         switch (i_node->type) {
         case XML_ELEMENT_NODE:
             pcmk__set_xml_doc_flag(i_node, pcmk__xf_tracking);
 
             if (!pcmk__check_acl(i_node, NULL, pcmk__xf_acl_read)) {
                 ns = NS_DENIED;
             } else if (!pcmk__check_acl(i_node, NULL, pcmk__xf_acl_write)) {
                 ns = NS_READABLE;
             } else {
                 ns = NS_WRITABLE;
             }
             if (ns == NS_WRITABLE) {
                 if (ns_recycle_writable == NULL) {
                     ns_recycle_writable = xmlNewNs(xmlDocGetRootElement(i_node->doc),
                                                    NS_WRITABLE, ACL_NS_Q_WRITABLE);
                 }
                 xmlSetNs(i_node, ns_recycle_writable);
                 ret = pcmk_rc_ok;
             } else if (ns == NS_READABLE) {
                 if (ns_recycle_readable == NULL) {
                     ns_recycle_readable = xmlNewNs(xmlDocGetRootElement(i_node->doc),
                                                    NS_READABLE, ACL_NS_Q_READABLE);
                 }
                 xmlSetNs(i_node, ns_recycle_readable);
                 ret = pcmk_rc_ok;
             } else if (ns == NS_DENIED) {
                 if (ns_recycle_denied == NULL) {
                     ns_recycle_denied = xmlNewNs(xmlDocGetRootElement(i_node->doc),
                                                  NS_DENIED, ACL_NS_Q_DENIED);
                 };
                 xmlSetNs(i_node, ns_recycle_denied);
                 ret = pcmk_rc_ok;
             }
             /* XXX recursion can be turned into plain iteration to save stack */
             if (i_node->properties != NULL) {
                 /* this is not entirely clear, but relies on the very same
                    class-hierarchy emulation that libxml2 has firmly baked in
                    its API/ABI */
                 ret |= pcmk__eval_acl_as_namespaces_2((xmlNodePtr) i_node->properties);
             }
             if (i_node->children != NULL) {
                 ret |= pcmk__eval_acl_as_namespaces_2(i_node->children);
             }
             break;
         case XML_ATTRIBUTE_NODE:
             /* we can utilize that parent has already been assigned the ns */
             if (!pcmk__check_acl(i_node->parent,
                                  (const char *) i_node->name,
                                  pcmk__xf_acl_read)) {
                 ns = NS_DENIED;
             } else if (!pcmk__check_acl(i_node,
                                    (const char *) i_node->name,
                                    pcmk__xf_acl_write)) {
                 ns = NS_READABLE;
             } else {
                 ns = NS_WRITABLE;
             }
             if (ns == NS_WRITABLE) {
                 if (ns_recycle_writable == NULL) {
                     ns_recycle_writable = xmlNewNs(xmlDocGetRootElement(i_node->doc),
                                                    NS_WRITABLE, ACL_NS_Q_WRITABLE);
                 }
                 xmlSetNs(i_node, ns_recycle_writable);
                 ret = pcmk_rc_ok;
             } else if (ns == NS_READABLE) {
                 if (ns_recycle_readable == NULL) {
                     ns_recycle_readable = xmlNewNs(xmlDocGetRootElement(i_node->doc),
                                                    NS_READABLE, ACL_NS_Q_READABLE);
                 }
                 xmlSetNs(i_node, ns_recycle_readable);
                 ret = pcmk_rc_ok;
             } else if (ns == NS_DENIED) {
                 if (ns_recycle_denied == NULL) {
                     ns_recycle_denied = xmlNewNs(xmlDocGetRootElement(i_node->doc),
                                                  NS_DENIED, ACL_NS_Q_DENIED);
                 }
                 xmlSetNs(i_node, ns_recycle_denied);
                 ret = pcmk_rc_ok;
             }
             break;
         default:
             break;
         }
     }
 
     return ret;
 }
 
 int
 pcmk__acl_evaled_as_namespaces(const char *cred, xmlDoc *cib_doc,
                               xmlDoc **acl_evaled_doc)
 {
     int ret, version;
     xmlNode *target, *comment;
     const char *validation;
 
     CRM_CHECK(cred != NULL, return EINVAL);
     CRM_CHECK(cib_doc != NULL, return EINVAL);
     CRM_CHECK(acl_evaled_doc != NULL, return EINVAL);
 
     /* avoid trivial accidental XML injection */
     if (strpbrk(cred, "<>&") != NULL) {
         return EINVAL;
     }
 
     if (!pcmk_acl_required(cred)) {
         /* nothing to evaluate */
         return pcmk_rc_already;
     }
 
     /* XXX see the comment for this function, pacemaker-4.0 may need
            updating respectively in the future */
     validation = crm_element_value(xmlDocGetRootElement(cib_doc),
                                    XML_ATTR_VALIDATION);
     version = get_schema_version(validation);
     if (get_schema_version(PCMK__COMPAT_ACL_2_MIN_INCL) > version) {
         return pcmk_rc_schema_validation;
     }
 
     target = copy_xml(xmlDocGetRootElement(cib_doc));
     if (target == NULL) {
         return EINVAL;
     }
 
     ret = pcmk__eval_acl_as_namespaces_2(target);  /* XXX may need "switch" */
 
     if (ret > 0) {
-        comment = xmlNewDocComment(target->doc, (pcmkXmlStr) crm_strdup_printf("%s", cred));
+        char* credentials = crm_strdup_printf("%s", cred);
+        comment = xmlNewDocComment(target->doc, (pcmkXmlStr) credentials);
+        free(credentials);
         if (comment == NULL) {
             xmlFreeNode(target);
-            return -1;
+            return EINVAL;
         }
         xmlAddPrevSibling(xmlDocGetRootElement(target->doc), comment);
         *acl_evaled_doc = target->doc;
     } else {
         xmlFreeNode(target);
     }
     return pcmk_rc_ok;
 }
 
 int
 pcmk__acl_evaled_render(xmlDoc *annotated_doc, enum pcmk__acl_render_how how,
                         xmlChar **doc_txt_ptr)
 {
 #if HAVE_LIBXSLT
     xmlDoc *xslt_doc;
     xsltStylesheet *xslt;
     xsltTransformContext *xslt_ctxt;
     xmlDoc *res;
     char *sfile;
     static const char *params_ns_simple[] = {
         "accessrendercfg:c-writable",           ACL_NS_Q_PREFIX "writable:",
         "accessrendercfg:c-readable",           ACL_NS_Q_PREFIX "readable:",
         "accessrendercfg:c-denied",             ACL_NS_Q_PREFIX "denied:",
         "accessrendercfg:c-reset",              "",
         "accessrender:extra-spacing",           "no",
         "accessrender:self-reproducing-prefix", ACL_NS_Q_PREFIX,
         NULL
     }, *params_useansi[] = {
         /* start with hard-coded defaults, then adapt per the template ones */
         "accessrendercfg:c-writable",           "\x1b[32m",
         "accessrendercfg:c-readable",           "\x1b[34m",
         "accessrendercfg:c-denied",             "\x1b[31m",
         "accessrendercfg:c-reset",              "\x1b[0m",
         "accessrender:extra-spacing",           "no",
         "accessrender:self-reproducing-prefix", ACL_NS_Q_PREFIX,
         NULL
     }, *params_noansi[] = {
         "accessrendercfg:c-writable",           "vvv---[ WRITABLE ]---vvv",
         "accessrendercfg:c-readable",           "vvv---[ READABLE ]---vvv",
         "accessrendercfg:c-denied",             "vvv---[ ~DENIED~ ]---vvv",
         "accessrendercfg:c-reset",              "",
         "accessrender:extra-spacing",           "yes",
         "accessrender:self-reproducing-prefix", "",
         NULL
     };
     const char **params;
     int ret;
     xmlParserCtxtPtr parser_ctxt;
 
     /* unfortunately, the input (coming from CIB originally) was parsed with
        blanks ignored, and since the output is a conversion of XML to text
        format (we would be covered otherwise thanks to implicit
        pretty-printing), we need to dump the tree to string output first,
        only to subsequently reparse it -- this time with blanks honoured */
     xmlChar *annotated_dump;
     int dump_size;
     xmlDocDumpFormatMemory(annotated_doc, &annotated_dump, &dump_size, 1);
     res = xmlReadDoc(annotated_dump, "on-the-fly-access-render", NULL,
                      XML_PARSE_NONET);
     CRM_ASSERT(res != NULL);
     xmlFree(annotated_dump);
     xmlFreeDoc(annotated_doc);
     annotated_doc = res;
 
     sfile = pcmk__xml_artefact_path(pcmk__xml_artefact_ns_base_xslt,
                                     "access-render-2");
     parser_ctxt = xmlNewParserCtxt();
 
     CRM_ASSERT(sfile != NULL);
     CRM_ASSERT(parser_ctxt != NULL);
 
     xslt_doc = xmlCtxtReadFile(parser_ctxt, sfile, NULL, XML_PARSE_NONET);
 
     xslt = xsltParseStylesheetDoc(xslt_doc);  /* acquires xslt_doc! */
     if (xslt == NULL) {
         crm_crit("Problem in parsing %s", sfile);
         return EINVAL;
     }
     free(sfile);
     sfile = NULL;
     xmlFreeParserCtxt(parser_ctxt);
 
     xslt_ctxt = xsltNewTransformContext(xslt, annotated_doc);
     CRM_ASSERT(xslt_ctxt != NULL);
 
     if (how == pcmk__acl_render_ns_simple) {
         params = params_ns_simple;
     } else if (how == pcmk__acl_render_text) {
         params = params_noansi;
     } else {
         params = params_useansi;
     }
 
     xsltQuoteUserParams(xslt_ctxt, params);
 
     res = xsltApplyStylesheetUser(xslt, annotated_doc, NULL,
                                   NULL, NULL, xslt_ctxt);
 
     xmlFreeDoc(annotated_doc);
     annotated_doc = NULL;
     xsltFreeTransformContext(xslt_ctxt);
     xslt_ctxt = NULL;
 
     if (how == pcmk__acl_render_color && params != params_useansi) {
         char **param_i = (char **) params;
         do {
             free(*param_i);
         } while (*param_i++ != NULL);
         free(params);
     }
 
     if (res == NULL) {
         ret = EINVAL;
     } else {
         int doc_txt_len;
         int temp = xsltSaveResultToString(doc_txt_ptr, &doc_txt_len, res, xslt);
         xmlFreeDoc(res);
         if (temp == 0) {
             ret = pcmk_rc_ok;
         } else {
             ret = EINVAL;
         }
     }
     xsltFreeStylesheet(xslt);
     return ret;
 #else
-    return -1;
+    return EINVAL;
 #endif
 }
\ No newline at end of file