13 #include <sys/types.h>    19 #include <libxml/tree.h>    26 typedef struct xml_acl_s {
    45     g_list_free_full(acls, free_acl);
    67     if ((tag == NULL) && (ref == NULL) && (xpath == NULL)) {
    69         crm_trace(
"Ignoring ACL <%s> element without selection criteria",
    78         acl->xpath = g_strdup(xpath);
    79         crm_trace(
"Unpacked ACL <%s> element using xpath: %s",
    80                   xml->name, acl->xpath);
    83         GString *buf = g_string_sized_new(128);
    85         if ((ref != NULL) && (attr != NULL)) {
    88                            ref, 
"' and @", attr, 
"]", NULL);
    90         } 
else if (ref != NULL) {
    94         } 
else if (attr != NULL) {
    95             pcmk__g_strcat(buf, 
"//", pcmk__s(tag, 
"*"), 
"[@", attr, 
"]", NULL);
   101         acl->xpath = buf->str;
   103         g_string_free(buf, FALSE);
   104         crm_trace(
"Unpacked ACL <%s> element as xpath: %s",
   105                   xml->name, acl->xpath);
   108     return g_list_append(acls, acl);
   124 parse_acl_entry(
const xmlNode *acl_top, 
const xmlNode *acl_entry, GList *acls)
   126     xmlNode *child = NULL;
   129          child != NULL; child = pcmk__xe_next(child)) {
   131         const char *tag = (
const char *) child->name;
   136             crm_trace(
"Unpacking ACL <%s> element of kind '%s'", tag, kind);
   139             crm_trace(
"Unpacking ACL <%s> element", tag);
   149                 xmlNode *role = NULL;
   152                      role != NULL; role = pcmk__xe_next(role)) {
   158                         if (role_id && strcmp(ref_role, role_id) == 0) {
   159                             crm_trace(
"Unpacking referenced role '%s' in ACL <%s> element",
   160                                       role_id, acl_entry->name);
   161                             acls = parse_acl_entry(acl_top, role, acls);
   184             crm_warn(
"Ignoring unknown ACL %s '%s'",
   185                      (kind? 
"kind" : 
"element"), tag);
   235     xmlXPathObjectPtr xpathObj = NULL;
   238         crm_trace(
"Skipping ACLs for user '%s' because not enabled for this XML",
   243     for (aIter = docpriv->
acls; aIter != NULL; aIter = aIter->next) {
   244         int max = 0, lpc = 0;
   248         max = numXpathResults(xpathObj);
   250         for (lpc = 0; lpc < max; lpc++) {
   253             nodepriv = match->_private;
   260                     crm_trace(
"Applying %s ACL to %s matched by %s",
   261                               acl_to_text(acl->mode), 
path->str, acl->xpath);
   262                     g_string_free(
path, TRUE);
   267         crm_trace(
"Applied %s ACL %s (%d match%s)",
   268                   acl_to_text(acl->mode), acl->xpath, max,
   269                   ((max == 1)? 
"" : 
"es"));
   293         || (
target->doc->_private == NULL)) {
   297     docpriv = 
target->doc->_private;
   299         crm_trace(
"Not unpacking ACLs because not required for user '%s'",
   302     } 
else if (docpriv->
acls == NULL) {
   308             xmlNode *child = NULL;
   311                  child != NULL; child = pcmk__xe_next(child)) {
   324                     if (
id && strcmp(
id, user) == 0) {
   325                         crm_debug(
"Unpacking ACLs for user '%s'", 
id);
   326                         docpriv->
acls = parse_acl_entry(acls, child, docpriv->
acls);
   336                         crm_debug(
"Unpacking ACLs for group '%s'", 
id);
   337                         docpriv->
acls = parse_acl_entry(acls, child, docpriv->
acls);
   367     } 
else if (pcmk_all_flags_set(allowed, requested)) {
   393 purge_xml_attributes(xmlNode *xml)
   395     xmlNode *child = NULL;
   396     xmlAttr *xIter = NULL;
   397     bool readable_children = 
false;
   402                   xml->name, pcmk__xe_id(xml));
   406     xIter = xml->properties;
   407     while (xIter != NULL) {
   408         xmlAttr *tmp = xIter;
   409         const char *prop_name = (
const char *)xIter->name;
   419     child = pcmk__xml_first_child(xml);
   420     while ( child != NULL ) {
   421         xmlNode *tmp = child;
   423         child = pcmk__xml_next(child);
   424         readable_children |= purge_xml_attributes(tmp);
   427     if (!readable_children) {
   430     return readable_children;
   454         crm_trace(
"Not filtering XML because ACLs not required for user '%s'",
   459     crm_trace(
"Filtering XML copy using user '%s' ACLs", user);
   467     docpriv = 
target->doc->_private;
   468     for(aIter = docpriv->
acls; aIter != NULL && 
target; aIter = aIter->next) {
   475         } 
else if (acl->xpath) {
   479             max = numXpathResults(xpathObj);
   480             for(lpc = 0; lpc < max; lpc++) {
   483                 if (!purge_xml_attributes(match) && (match == 
target)) {
   484                     crm_trace(
"ACLs deny user '%s' access to entire XML document",
   490             crm_trace(
"ACLs deny user '%s' access to %s (%d %s)",
   491                       user, acl->xpath, max,
   497     if (!purge_xml_attributes(
target)) {
   498         crm_trace(
"ACLs deny user '%s' access to entire XML document", user);
   503         g_list_free_full(docpriv->
acls, free_acl);
   504         docpriv->
acls = NULL;
   507         crm_trace(
"User '%s' without ACLs denied access to entire XML document",
   533 implicitly_allowed(
const xmlNode *xml)
   535     GString *
path = NULL;
   537     for (xmlAttr *prop = xml->properties; prop != NULL; prop = prop->next) {
   538         if (strcmp((
const char *) prop->name, 
PCMK_XA_ID) != 0) {
   547         g_string_free(
path, TRUE);
   551     g_string_free(
path, TRUE);
   555 #define display_id(xml) pcmk__s(pcmk__xe_id(xml), "<unset>")   578         if (implicitly_allowed(xml)) {
   580                       " is implicitly allowed",
   587         } 
else if (check_top) {
   588             crm_trace(
"ACLs disallow creation of <%s> with "   594             crm_notice(
"ACLs would disallow creation of %s<%s> with "   596                        ((xml == xmlDocGetRootElement(xml->doc))? 
"root element " : 
""),
   601     for (xmlNode *cIter = pcmk__xml_first_child(xml); cIter != NULL; ) {
   602         xmlNode *child = cIter;
   603         cIter = pcmk__xml_next(cIter); 
   618     if (xml && xml->doc && xml->doc->_private){
   649     if (xml && xml->doc && xml->doc->_private){
   661                  && (xml->doc->_private != NULL));
   666         GString *xpath = NULL;
   668         if (docpriv->
acls == NULL) {
   677             qb_log_from_external_source(__func__, __FILE__,
   678                                         "User '%s' without ACLs denied %s "   680                                         docpriv->
user, acl_to_text(mode),
   681                                         (
const char *) xpath->str);
   682             g_string_free(xpath, TRUE);
   701             if (test_acl_mode(nodepriv->
flags, mode)) {
   713                 qb_log_from_external_source(__func__, __FILE__,
   714                                             "%sACL denies user '%s' %s access "   716                                             (
parent != xml)? 
"Parent ": 
"",
   717                                             docpriv->
user, acl_to_text(mode),
   718                                             (
const char *) xpath->str);
   719                 g_string_free(xpath, TRUE);
   733         qb_log_from_external_source(__func__, __FILE__,
   734                                     "Default ACL denies user '%s' %s access to "   736                                     docpriv->
user, acl_to_text(mode),
   737                                     (
const char *) xpath->str);
   738         g_string_free(xpath, TRUE);
   755     if (pcmk__str_empty(user)) {
   756         crm_trace(
"ACLs not required because no user set");
   760         crm_trace(
"ACLs not required for privileged user %s", user);
   770     struct passwd *pwent = getpwuid(uid);
   773         crm_perror(LOG_INFO, 
"Cannot get user details for user ID %d", uid);
   799                       const char *peer_user)
   801     static const char *effective_user = NULL;
   802     const char *requested_user = NULL;
   803     const char *user = NULL;
   805     if (effective_user == NULL) {
   807         if (effective_user == NULL) {
   809             crm_err(
"Unable to determine effective user, assuming unprivileged for ACLs");
   814     if (requested_user == NULL) {
   823     if (!pcmk__is_privileged(effective_user)) {
   827         user = effective_user;
   829     } 
else if (peer_user == NULL && requested_user == NULL) {
   833         user = effective_user;
   835     } 
else if (peer_user == NULL) {
   837         user = requested_user;
   839     } 
else if (!pcmk__is_privileged(peer_user)) {
   845     } 
else if (requested_user == NULL) {
   851         user = requested_user;
   863     return requested_user;
 
void xml_acl_disable(xmlNode *xml)
 
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
 
#define crm_notice(fmt, args...)
 
#define pcmk__if_tracing(if_action, else_action)
 
void pcmk__free_acls(GList *acls)
 
#define PCMK__XE_ACL_USER
 
#define PCMK_XA_REFERENCE
 
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. 
 
void pcmk__apply_creation_acl(xmlNode *xml, bool check_top)
 
G_GNUC_INTERNAL bool pcmk__is_user_in_group(const char *user, const char *group)
 
void pcmk__set_xml_doc_flag(xmlNode *xml, enum xml_private_flags flag)
 
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
 
#define PCMK_XE_ACL_PERMISSION
 
char * pcmk__uid2username(uid_t uid)
 
bool xml_acl_filtered_copy(const char *user, xmlNode *acl_source, xmlNode *xml, xmlNode **result)
Copy ACL-allowed portions of specified 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. 
 
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
 
#define crm_trace(fmt, args...)
 
void pcmk__g_strcat(GString *buffer,...) G_GNUC_NULL_TERMINATED
 
#define PCMK__XE_ROLE_REF
 
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag. 
 
void pcmk__enable_acl(xmlNode *acl_source, xmlNode *target, const char *user)
 
void pcmk__str_update(char **str, const char *value)
 
Wrappers for and extensions to libxml2. 
 
const char * pcmk__update_acl_user(xmlNode *request, const char *field, const char *peer_user)
 
void pcmk__unpack_acl(xmlNode *source, xmlNode *target, const char *user)
 
void free_xml(xmlNode *child)
 
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
 
bool xml_acl_denied(const xmlNode *xml)
Check whether or not an XML node is ACL-denied. 
 
#define pcmk__str_copy(str)
 
const xmlChar * pcmkXmlStr
 
#define pcmk__assert(expr)
 
xmlXPathObjectPtr xpath_search(const xmlNode *xml_top, const char *path)
 
#define PCMK_XE_ACL_TARGET
 
pcmk__action_result_t result
 
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr. 
 
#define crm_err(fmt, args...)
 
#define pcmk__plural_alt(i, s1, s2)
 
#define PCMK_XE_ACL_GROUP
 
void pcmk__apply_acl(xmlNode *xml)
 
xmlNode * getXpathResult(xmlXPathObjectPtr xpathObj, int index)
 
#define PCMK_XA_ATTRIBUTE
 
bool xml_acl_enabled(const xmlNode *xml)
Check whether or not an XML node is ACL-enabled. 
 
GString * pcmk__element_xpath(const xmlNode *xml)
 
G_GNUC_INTERNAL bool pcmk__tracking_xml_changes(xmlNode *xml, bool lazy)
 
#define pcmk__set_xml_flags(xml_priv, flags_to_set)
 
#define PCMK_XA_OBJECT_TYPE
 
#define pcmk__clear_xml_flags(xml_priv, flags_to_clear)
 
#define pcmk__assert_alloc(nmemb, size)
 
void freeXpathObject(xmlXPathObjectPtr xpathObj)
 
struct xml_acl_s xml_acl_t
 
G_GNUC_INTERNAL int pcmk__xa_remove(xmlAttr *attr, bool force)