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>    34 #define ACL_NS_PREFIX "http://clusterlabs.org/ns/pacemaker/access/"    35 #define ACL_NS_Q_PREFIX  "pcmk-access-"    36 #define ACL_NS_Q_WRITABLE (const xmlChar *) ACL_NS_Q_PREFIX   "writable"    37 #define ACL_NS_Q_READABLE (const xmlChar *) ACL_NS_Q_PREFIX   "readable"    38 #define ACL_NS_Q_DENIED   (const xmlChar *) ACL_NS_Q_PREFIX   "denied"    40 static const xmlChar *NS_WRITABLE = (
const xmlChar *) 
ACL_NS_PREFIX "writable";
    41 static const xmlChar *NS_READABLE = (
const xmlChar *) 
ACL_NS_PREFIX "readable";
    42 static const xmlChar *NS_DENIED =   (
const xmlChar *) 
ACL_NS_PREFIX "denied";
    56 pcmk__acl_mark_node_with_namespace(xmlNode *i_node, 
const xmlChar *ns, 
int *ret, xmlNs **ns_recycle_writable, xmlNs **ns_recycle_readable, xmlNs **ns_recycle_denied)
    58     if (ns == NS_WRITABLE)
    60         if (*ns_recycle_writable == NULL)
    62             *ns_recycle_writable = xmlNewNs(xmlDocGetRootElement(i_node->doc),
    65         xmlSetNs(i_node, *ns_recycle_writable);
    68     else if (ns == NS_READABLE)
    70         if (*ns_recycle_readable == NULL)
    72             *ns_recycle_readable = xmlNewNs(xmlDocGetRootElement(i_node->doc),
    75         xmlSetNs(i_node, *ns_recycle_readable);
    78     else if (ns == NS_DENIED)
    80         if (*ns_recycle_denied == NULL)
    82             *ns_recycle_denied = xmlNewNs(xmlDocGetRootElement(i_node->doc),
    85         xmlSetNs(i_node, *ns_recycle_denied);
   107 pcmk__acl_annotate_permissions_recursive(xmlNode *xml_modify)
   110     static xmlNs *ns_recycle_writable = NULL,
   111                  *ns_recycle_readable = NULL,
   112                  *ns_recycle_denied = NULL;
   113     static const xmlDoc *prev_doc = NULL;
   115     xmlNode *i_node = NULL;
   119     if (prev_doc == NULL || prev_doc != xml_modify->doc) {
   120         prev_doc = xml_modify->doc;
   121         ns_recycle_writable = ns_recycle_readable = ns_recycle_denied = NULL;
   124     for (i_node = xml_modify; i_node != NULL; i_node = i_node->next) {
   125         switch (i_node->type) {
   126         case XML_ELEMENT_NODE:
   136             pcmk__acl_mark_node_with_namespace(i_node, ns, &ret, &ns_recycle_writable, &ns_recycle_readable, &ns_recycle_denied);
   138             if (i_node->properties != NULL) {
   142                 ret |= pcmk__acl_annotate_permissions_recursive((xmlNodePtr) i_node->properties);
   144             if (i_node->children != NULL) {
   145                 ret |= pcmk__acl_annotate_permissions_recursive(i_node->children);
   148         case XML_ATTRIBUTE_NODE:
   151                                  (
const char *) i_node->name,
   155                                    (
const char *) i_node->name,
   161             pcmk__acl_mark_node_with_namespace(i_node, ns, &ret, &ns_recycle_writable, &ns_recycle_readable, &ns_recycle_denied);
   163         case XML_COMMENT_NODE:
   177             pcmk__acl_mark_node_with_namespace(i_node, ns, &ret, &ns_recycle_writable, &ns_recycle_readable, &ns_recycle_denied);
   189                               xmlDoc **acl_evaled_doc)
   192     xmlNode *
target, *comment;
   193     const char *validation;
   196     CRM_CHECK(cib_doc != NULL, 
return EINVAL);
   197     CRM_CHECK(acl_evaled_doc != NULL, 
return EINVAL);
   200     if (strpbrk(cred, 
"<>&") != NULL) {
   223     ret = pcmk__acl_annotate_permissions_recursive(
target);
   229         if (comment == NULL) {
   233         xmlAddPrevSibling(xmlDocGetRootElement(
target->doc), comment);
   234         *acl_evaled_doc = 
target->doc;
   244                         xmlChar **doc_txt_ptr)
   247     xsltStylesheet *xslt;
   248     xsltTransformContext *xslt_ctxt;
   251     static const char *params_namespace[] = {
   255         "accessrendercfg:c-reset",              
"",
   256         "accessrender:extra-spacing",           
"no",
   259     }, *params_useansi[] = {
   261         "accessrendercfg:c-writable",           
"\x1b[32m",
   262         "accessrendercfg:c-readable",           
"\x1b[34m",
   263         "accessrendercfg:c-denied",             
"\x1b[31m",
   264         "accessrendercfg:c-reset",              
"\x1b[0m",
   265         "accessrender:extra-spacing",           
"no",
   268     }, *params_noansi[] = {
   269         "accessrendercfg:c-writable",           
"vvv---[ WRITABLE ]---vvv",
   270         "accessrendercfg:c-readable",           
"vvv---[ READABLE ]---vvv",
   271         "accessrendercfg:c-denied",             
"vvv---[ ~DENIED~ ]---vvv",
   272         "accessrendercfg:c-reset",              
"",
   273         "accessrender:extra-spacing",           
"yes",
   274         "accessrender:self-reproducing-prefix", 
"",
   279     xmlParserCtxtPtr parser_ctxt;
   286     xmlChar *annotated_dump;
   289     xmlDocDumpFormatMemory(annotated_doc, &annotated_dump, &dump_size, 1);
   290     res = xmlReadDoc(annotated_dump, 
"on-the-fly-access-render", NULL,
   293     xmlFree(annotated_dump);
   294     xmlFreeDoc(annotated_doc);
   299     parser_ctxt = xmlNewParserCtxt();
   304     xslt_doc = xmlCtxtReadFile(parser_ctxt, sfile, NULL, XML_PARSE_NONET);
   306     xslt = xsltParseStylesheetDoc(xslt_doc);  
   308         crm_crit(
"Problem in parsing %s", sfile);
   313     xmlFreeParserCtxt(parser_ctxt);
   315     xslt_ctxt = xsltNewTransformContext(xslt, annotated_doc);
   319         params = params_noansi;
   321         params = params_namespace;
   323         params = params_useansi;
   326     xsltQuoteUserParams(xslt_ctxt, params);
   328     res = xsltApplyStylesheetUser(xslt, annotated_doc, NULL,
   329                                   NULL, NULL, xslt_ctxt);
   331     xmlFreeDoc(annotated_doc);
   332     annotated_doc = NULL;
   333     xsltFreeTransformContext(xslt_ctxt);
   337         char **param_i = (
char **) params;
   340         } 
while (*param_i++ != NULL);
   348         int temp = xsltSaveResultToString(doc_txt_ptr, &doc_txt_len, res, xslt);
   356     xsltFreeStylesheet(xslt);
 #define CRM_CHECK(expr, failure_action)
 
#define crm_crit(fmt, args...)
 
#define ACL_NS_Q_READABLE
 
int get_schema_version(const char *name)
 
void pcmk__set_xml_doc_flag(xmlNode *xml, enum xml_private_flags flag)
 
int pcmk__acl_annotate_permissions(const char *cred, xmlDoc *cib_doc, xmlDoc **acl_evaled_doc)
Mark CIB with namespace-encoded result of ACLs eval'd per credential. 
 
xmlNode * copy_xml(xmlNode *src_node)
 
#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. 
 
#define XML_ATTR_VALIDATION
 
int pcmk__acl_evaled_render(xmlDoc *annotated_doc, enum pcmk__acl_render_how how, xmlChar **doc_txt_ptr)
 
const xmlChar * pcmkXmlStr
 
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)
 
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.