13 #include <sys/types.h>    19 #include <libxml/tree.h>    27 #define MAX_XPATH_LEN   4096    29 typedef struct xml_acl_s {
    48     g_list_free_full(acls, free_acl);
    70     if ((tag == NULL) && (ref == NULL) && (xpath == NULL)) {
    72         crm_trace(
"Ignoring ACL <%s> element without selection criteria",
    73                   crm_element_name(xml));
    82         acl->xpath = strdup(xpath);
    84         crm_trace(
"Unpacked ACL <%s> element using xpath: %s",
    85                   crm_element_name(xml), acl->xpath);
   126         acl->xpath = strdup(buffer);
   129         crm_trace(
"Unpacked ACL <%s> element as xpath: %s",
   130                   crm_element_name(xml), acl->xpath);
   133     return g_list_append(acls, acl);
   147 parse_acl_entry(xmlNode *acl_top, xmlNode *acl_entry, GList *acls)
   149     xmlNode *child = NULL;
   151     for (child = pcmk__xe_first_child(acl_entry); child;
   152          child = pcmk__xe_next(child)) {
   153         const char *tag = crm_element_name(child);
   158             crm_trace(
"Unpacking ACL <%s> element of kind '%s'", tag, kind);
   161             crm_trace(
"Unpacking ACL <%s> element", tag);
   169                 xmlNode *role = NULL;
   171                 for (role = pcmk__xe_first_child(acl_top); role;
   172                      role = pcmk__xe_next(role)) {
   177                         if (role_id && strcmp(ref_role, role_id) == 0) {
   178                             crm_trace(
"Unpacking referenced role '%s' in ACL <%s> element",
   179                                       role_id, crm_element_name(acl_entry));
   180                             acls = parse_acl_entry(acl_top, role, acls);
   197             crm_warn(
"Ignoring unknown ACL %s '%s'",
   198                      (kind? 
"kind" : 
"element"), tag);
   247     xmlXPathObjectPtr xpathObj = NULL;
   250         crm_trace(
"Skipping ACLs for user '%s' because not enabled for this XML",
   255     for (aIter = p->
acls; aIter != NULL; aIter = aIter->next) {
   256         int max = 0, lpc = 0;
   260         max = numXpathResults(xpathObj);
   262         for (lpc = 0; lpc < max; lpc++) {
   267             crm_trace(
"Applying %s ACL to %s matched by %s",
   268                       acl_to_text(acl->mode), path, acl->xpath);
   270 #ifdef SUSE_ACL_COMPAT   272                 && pcmk_any_flags_set(p->
flags,
   275                                   "multiple ACL rules, only the first applies "   276                                   "('%s' wins over '%s')",
   277                                   path, acl_to_text(p->
flags),
   278                                   acl_to_text(acl->mode));
   286         crm_trace(
"Applied %s ACL %s (%d match%s)",
   287                   acl_to_text(acl->mode), acl->xpath, max,
   288                   ((max == 1)? 
"" : 
"es"));
   308         || (
target->doc->_private == NULL)) {
   312     p = 
target->doc->_private;
   314         crm_trace(
"Not unpacking ACLs because not required for user '%s'",
   317     } 
else if (p->
acls == NULL) {
   322         p->
user = strdup(user);
   325             xmlNode *child = NULL;
   327             for (child = pcmk__xe_first_child(acls); child;
   328                  child = pcmk__xe_next(child)) {
   329                 const char *tag = crm_element_name(child);
   335                     if (
id && strcmp(
id, user) == 0) {
   336                         crm_debug(
"Unpacking ACLs for user '%s'", 
id);
   337                         p->
acls = parse_acl_entry(acls, child, p->
acls);
   352     } 
else if (pcmk_all_flags_set(allowed, requested)) {
   367 purge_xml_attributes(xmlNode *xml)
   369     xmlNode *child = NULL;
   370     xmlAttr *xIter = NULL;
   371     bool readable_children = 
false;
   375         crm_trace(
"%s[@id=%s] is readable", crm_element_name(xml), 
ID(xml));
   379     xIter = xml->properties;
   380     while (xIter != NULL) {
   381         xmlAttr *tmp = xIter;
   382         const char *prop_name = (
const char *)xIter->name;
   389         xmlUnsetProp(xml, tmp->name);
   392     child = pcmk__xml_first_child(xml);
   393     while ( child != NULL ) {
   394         xmlNode *tmp = child;
   396         child = pcmk__xml_next(child);
   397         readable_children |= purge_xml_attributes(tmp);
   400     if (!readable_children) {
   403     return readable_children;
   428         crm_trace(
"Not filtering XML because ACLs not required for user '%s'",
   433     crm_trace(
"Filtering XML copy using user '%s' ACLs", user);
   443     doc = 
target->doc->_private;
   444     for(aIter = doc->
acls; aIter != NULL && 
target; aIter = aIter->next) {
   451         } 
else if (acl->xpath) {
   455             max = numXpathResults(xpathObj);
   456             for(lpc = 0; lpc < max; lpc++) {
   459                 if (!purge_xml_attributes(match) && (match == 
target)) {
   460                     crm_trace(
"ACLs deny user '%s' access to entire XML document",
   466             crm_trace(
"ACLs deny user '%s' access to %s (%d %s)",
   467                       user, acl->xpath, max,
   473     if (!purge_xml_attributes(
target)) {
   474         crm_trace(
"ACLs deny user '%s' access to entire XML document", user);
   479         g_list_free_full(doc->
acls, free_acl);
   483         crm_trace(
"User '%s' without ACLs denied access to entire XML document",
   509 implicitly_allowed(xmlNode *xml)
   513     for (xmlAttr *prop = xml->properties; prop != NULL; prop = prop->next) {
   514         if (strcmp((
const char *) prop->name, 
XML_ATTR_ID) != 0) {
   529 #define display_id(xml) (ID(xml)? ID(xml) : "<unset>")   550         if (implicitly_allowed(xml)) {
   551             crm_trace(
"Creation of <%s> scaffolding with id=\"%s\""   552                       " is implicitly allowed",
   556             crm_trace(
"ACLs allow creation of <%s> with id=\"%s\"",
   559         } 
else if (check_top) {
   560             crm_trace(
"ACLs disallow creation of <%s> with id=\"%s\"",
   566             crm_notice(
"ACLs would disallow creation of %s<%s> with id=\"%s\" ",
   567                        ((xml == xmlDocGetRootElement(xml->doc))? 
"root element " : 
""),
   572     for (xmlNode *cIter = pcmk__xml_first_child(xml); cIter != NULL; ) {
   573         xmlNode *child = cIter;
   574         cIter = pcmk__xml_next(cIter); 
   582     if (xml && xml->doc && xml->doc->_private){
   606     if (xml && xml->doc && xml->doc->_private){
   624         xmlNode *parent = xml;
   636         if (docp->
acls == NULL) {
   637             crm_trace(
"User '%s' without ACLs denied %s access to %s",
   638                       docp->
user, acl_to_text(mode), buffer);
   656         while (parent && parent->_private) {
   658             if (test_acl_mode(p->
flags, mode)) {
   662                 crm_trace(
"%sACL denies user '%s' %s access to %s",
   663                           (parent != xml) ? 
"Parent " : 
"", docp->
user,
   664                           acl_to_text(mode), buffer);
   668             parent = parent->parent;
   671         crm_trace(
"Default ACL denies user '%s' %s access to %s",
   672                   docp->
user, acl_to_text(mode), buffer);
   692     if (pcmk__str_empty(user)) {
   693         crm_trace(
"ACLs not required because no user set");
   697         crm_trace(
"ACLs not required for privileged user %s", user);
   703     crm_trace(
"ACLs not required because not supported by this build");
   712     struct passwd *pwent = getpwuid(uid);
   715         crm_perror(LOG_INFO, 
"Cannot get user details for user ID %d", uid);
   718     return strdup(pwent->pw_name);
   741                       const char *peer_user)
   743     static const char *effective_user = NULL;
   744     const char *requested_user = NULL;
   745     const char *user = NULL;
   747     if (effective_user == NULL) {
   749         if (effective_user == NULL) {
   750             effective_user = strdup(
"#unprivileged");
   751             CRM_CHECK(effective_user != NULL, 
return NULL);
   752             crm_err(
"Unable to determine effective user, assuming unprivileged for ACLs");
   757     if (requested_user == NULL) {
   766     if (!pcmk__is_privileged(effective_user)) {
   770         user = effective_user;
   772     } 
else if (peer_user == NULL && requested_user == NULL) {
   776         user = effective_user;
   778     } 
else if (peer_user == NULL) {
   780         user = requested_user;
   782     } 
else if (!pcmk__is_privileged(peer_user)) {
   788     } 
else if (requested_user == NULL) {
   794         user = requested_user;
   806     return requested_user;
 #define CRM_CHECK(expr, failure_action)
 
void xml_acl_disable(xmlNode *xml)
 
#define crm_notice(fmt, args...)
 
void pcmk__free_acls(GList *acls)
 
G_GNUC_INTERNAL int pcmk__element_xpath(const char *prefix, xmlNode *xml, char *buffer, int offset, size_t buffer_size)
 
bool xml_acl_enabled(xmlNode *xml)
 
bool pcmk_acl_required(const char *user)
Check whether ACLs are required for a given user.
 
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
 
#define XML_ACL_TAG_WRITE
 
void pcmk__apply_creation_acl(xmlNode *xml, bool check_top)
 
#define CRM_LOG_ASSERT(expr)
 
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
 
G_GNUC_INTERNAL void pcmk__set_xml_doc_flag(xmlNode *xml, enum xml_private_flags flag)
 
xmlNode * copy_xml(xmlNode *src_node)
 
#define XML_ACL_ATTR_REFv1
 
#define XML_ACL_ATTR_KIND
 
bool xml_acl_filtered_copy(const char *user, xmlNode *acl_source, xmlNode *xml, xmlNode **result)
 
bool xml_acl_denied(xmlNode *xml)
 
bool pcmk__check_acl(xmlNode *xml, const char *name, enum xml_private_flags mode)
 
#define crm_warn(fmt, args...)
 
void pcmk_free_xml_subtree(xmlNode *xml)
 
#define crm_debug(fmt, args...)
 
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
 
#define XML_ACL_ATTR_XPATH
 
#define XML_ACL_TAG_PERMISSION
 
#define crm_trace(fmt, args...)
 
const char * pcmk__update_acl_user(xmlNode *request, const char *field, const char *peer_user)
 
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
 
#define XML_ACL_TAG_USERv1
 
Wrappers for and extensions to libxml2.
 
#define XML_ACL_ATTR_ATTRIBUTE
 
void pcmk__unpack_acl(xmlNode *source, xmlNode *target, const char *user)
 
void free_xml(xmlNode *child)
 
#define XML_ACL_ATTR_TAGv1
 
const xmlChar * pcmkXmlStr
 
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
 
#define crm_err(fmt, args...)
 
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
 
#define pcmk__plural_alt(i, s1, s2)
 
#define XML_ACL_TAG_ROLE_REFv1
 
void pcmk__apply_acl(xmlNode *xml)
 
xmlNode * getXpathResult(xmlXPathObjectPtr xpathObj, int index)
 
char * xml_get_path(xmlNode *xml)
 
#define XML_ACL_TAG_ROLE_REF
 
G_GNUC_INTERNAL bool pcmk__tracking_xml_changes(xmlNode *xml, bool lazy)
 
#define pcmk__set_xml_flags(xml_priv, flags_to_set)
 
char * pcmk__uid2username(uid_t uid)
 
#define pcmk__clear_xml_flags(xml_priv, flags_to_clear)
 
void freeXpathObject(xmlXPathObjectPtr xpathObj)
 
struct xml_acl_s xml_acl_t
 
#define pcmk__config_warn(fmt...)