13 #include <sys/types.h> 19 #include <libxml/parser.h> 20 #include <libxml/tree.h> 21 #include <libxml/xpath.h> 22 #include <libxslt/transform.h> 23 #include <libxslt/variables.h> 24 #include <libxslt/xsltutils.h> 33 #define ACL_NS_PREFIX "http://clusterlabs.org/ns/pacemaker/access/" 34 #define ACL_NS_Q_PREFIX "pcmk-access-" 35 #define ACL_NS_Q_WRITABLE (const xmlChar *) ACL_NS_Q_PREFIX "writable" 36 #define ACL_NS_Q_READABLE (const xmlChar *) ACL_NS_Q_PREFIX "readable" 37 #define ACL_NS_Q_DENIED (const xmlChar *) ACL_NS_Q_PREFIX "denied" 39 static const xmlChar *NS_WRITABLE = (
const xmlChar *)
ACL_NS_PREFIX "writable";
40 static const xmlChar *NS_READABLE = (
const xmlChar *)
ACL_NS_PREFIX "readable";
41 static const xmlChar *NS_DENIED = (
const xmlChar *)
ACL_NS_PREFIX "denied";
55 pcmk__acl_mark_node_with_namespace(xmlNode *i_node,
const xmlChar *ns,
int *ret,
56 xmlNs **ns_recycle_writable,
57 xmlNs **ns_recycle_readable,
58 xmlNs **ns_recycle_denied)
60 if (ns == NS_WRITABLE)
62 if (*ns_recycle_writable == NULL)
64 *ns_recycle_writable = xmlNewNs(xmlDocGetRootElement(i_node->doc),
67 xmlSetNs(i_node, *ns_recycle_writable);
70 else if (ns == NS_READABLE)
72 if (*ns_recycle_readable == NULL)
74 *ns_recycle_readable = xmlNewNs(xmlDocGetRootElement(i_node->doc),
77 xmlSetNs(i_node, *ns_recycle_readable);
80 else if (ns == NS_DENIED)
82 if (*ns_recycle_denied == NULL)
84 *ns_recycle_denied = xmlNewNs(xmlDocGetRootElement(i_node->doc),
87 xmlSetNs(i_node, *ns_recycle_denied);
109 annotate_with_siblings(xmlNode *xml_modify)
112 static xmlNs *ns_recycle_writable = NULL,
113 *ns_recycle_readable = NULL,
114 *ns_recycle_denied = NULL;
115 static const xmlDoc *prev_doc = NULL;
117 xmlNode *i_node = NULL;
121 if (prev_doc == NULL || prev_doc != xml_modify->doc) {
122 prev_doc = xml_modify->doc;
123 ns_recycle_writable = ns_recycle_readable = ns_recycle_denied = NULL;
126 for (i_node = xml_modify; i_node != NULL; i_node = i_node->next) {
127 switch (i_node->type) {
128 case XML_ELEMENT_NODE:
138 pcmk__acl_mark_node_with_namespace(i_node, ns, &ret,
139 &ns_recycle_writable,
140 &ns_recycle_readable,
143 if (i_node->properties != NULL) {
148 ret |= annotate_with_siblings((xmlNodePtr)
151 if (i_node->children != NULL) {
152 ret |= annotate_with_siblings(i_node->children);
156 case XML_ATTRIBUTE_NODE:
159 (
const char *) i_node->name,
163 (
const char *) i_node->name,
169 pcmk__acl_mark_node_with_namespace(i_node, ns, &ret,
170 &ns_recycle_writable,
171 &ns_recycle_readable,
175 case XML_COMMENT_NODE:
178 (
const char *) i_node->name,
182 (
const char *) i_node->name,
188 pcmk__acl_mark_node_with_namespace(i_node, ns, &ret,
189 &ns_recycle_writable,
190 &ns_recycle_readable,
204 xmlDoc **acl_evaled_doc)
207 xmlNode *
target, *comment;
208 const char *validation;
211 CRM_CHECK(cib_doc != NULL,
return EINVAL);
212 CRM_CHECK(acl_evaled_doc != NULL,
return EINVAL);
215 if (strpbrk(cred,
"<>&") != NULL) {
240 ret = annotate_with_siblings(
target);
247 xmlAddPrevSibling(xmlDocGetRootElement(
target->doc), comment);
248 *acl_evaled_doc =
target->doc;
259 xmlChar **doc_txt_ptr)
262 xsltStylesheet *xslt;
263 xsltTransformContext *xslt_ctxt;
266 static const char *params_namespace[] = {
270 "accessrendercfg:c-reset",
"",
271 "accessrender:extra-spacing",
"no",
274 }, *params_useansi[] = {
276 "accessrendercfg:c-writable",
"\x1b[32m",
277 "accessrendercfg:c-readable",
"\x1b[34m",
278 "accessrendercfg:c-denied",
"\x1b[31m",
279 "accessrendercfg:c-reset",
"\x1b[0m",
280 "accessrender:extra-spacing",
"no",
283 }, *params_noansi[] = {
284 "accessrendercfg:c-writable",
"vvv---[ WRITABLE ]---vvv",
285 "accessrendercfg:c-readable",
"vvv---[ READABLE ]---vvv",
286 "accessrendercfg:c-denied",
"vvv---[ ~DENIED~ ]---vvv",
287 "accessrendercfg:c-reset",
"",
288 "accessrender:extra-spacing",
"yes",
289 "accessrender:self-reproducing-prefix",
"",
294 xmlParserCtxtPtr parser_ctxt;
301 xmlChar *annotated_dump;
308 if (isatty(STDOUT_FILENO)) {
315 xmlDocDumpFormatMemory(annotated_doc, &annotated_dump, &dump_size, 1);
320 res = xmlReadDoc(annotated_dump,
"on-the-fly-access-render", NULL,
323 xmlFree(annotated_dump);
329 parser_ctxt = xmlNewParserCtxt();
334 xslt_doc = xmlCtxtReadFile(parser_ctxt, sfile, NULL, XML_PARSE_NONET);
336 xslt = xsltParseStylesheetDoc(xslt_doc);
338 crm_crit(
"Problem in parsing %s", sfile);
342 xmlFreeParserCtxt(parser_ctxt);
344 xslt_ctxt = xsltNewTransformContext(xslt, annotated_doc);
349 params = params_namespace;
352 params = params_noansi;
359 params = params_useansi;
363 xsltQuoteUserParams(xslt_ctxt, params);
365 res = xsltApplyStylesheetUser(xslt, annotated_doc, NULL,
366 NULL, NULL, xslt_ctxt);
369 annotated_doc = NULL;
370 xsltFreeTransformContext(xslt_ctxt);
374 char **param_i = (
char **) params;
377 }
while (*param_i++ != NULL);
385 int temp = xsltSaveResultToString(doc_txt_ptr, &doc_txt_len, res, xslt);
395 xsltFreeStylesheet(xslt);
#define CRM_CHECK(expr, failure_action)
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
#define crm_crit(fmt, args...)
int pcmk__cmp_schemas_by_name(const char *schema1_name, const char *schema2_name)
#define ACL_NS_Q_READABLE
void pcmk__set_xml_doc_flag(xmlNode *xml, enum xml_private_flags flag)
#define ACL_NS_Q_WRITABLE
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
#define PCMK__COMPAT_ACL_2_MIN_INCL
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
Wrappers for and extensions to libxml2.
void free_xml(xmlNode *child)
int pcmk__acl_evaled_render(xmlDoc *annotated_doc, enum pcmk__acl_render_how how, xmlChar **doc_txt_ptr)
#define PCMK_XA_VALIDATE_WITH
#define pcmk__assert(expr)
void pcmk__enable_acl(xmlNode *acl_source, xmlNode *target, const char *user)
bool pcmk__check_acl(xmlNode *xml, const char *name, enum xml_private_flags mode)
#define pcmk__mem_assert(ptr)
void pcmk__xml_free_doc(xmlDoc *doc)
char * pcmk__xml_artefact_path(enum pcmk__xml_artefact_ns ns, const char *filespec)
bool pcmk_acl_required(const char *user)
Check whether ACLs are required for a given user.
int pcmk__acl_annotate_permissions(const char *cred, const xmlDoc *cib_doc, xmlDoc **acl_evaled_doc)
Annotate CIB with XML namespaces indicating ACL evaluation results.