13 #include <sys/types.h> 19 #include <libxml/tree.h> 26 #define MAX_XPATH_LEN 4096 28 typedef struct xml_acl_s {
34 __xml_acl_free(
void *
data)
47 g_list_free_full(acls, __xml_acl_free);
68 if ((tag == NULL) && (ref == NULL) && (xpath == NULL)) {
79 acl->xpath = strdup(xpath);
120 acl->xpath = strdup(buffer);
121 crm_trace(
"Built xpath: %s", acl->xpath);
124 acls = g_list_append(acls, acl);
130 __xml_acl_parse_entry(xmlNode *acl_top, xmlNode *acl_entry, GList *acls)
132 xmlNode *child = NULL;
134 for (child = __xml_first_child_element(acl_entry); child;
135 child = __xml_next_element(child)) {
136 const char *tag = crm_element_name(child);
143 crm_trace(
"Processing %s %p", tag, child);
152 xmlNode *role = NULL;
154 for (role = __xml_first_child_element(acl_top); role;
155 role = __xml_next_element(role)) {
160 if (role_id && strcmp(ref_role, role_id) == 0) {
161 crm_debug(
"Unpacking referenced role: %s", role_id);
162 acls = __xml_acl_parse_entry(acl_top, role, acls);
179 crm_warn(
"Unknown ACL entry: %s/%s", tag, kind);
208 #ifdef SUSE_ACL_COMPAT 230 xmlXPathObjectPtr xpathObj = NULL;
237 for (aIter = p->
acls; aIter != NULL; aIter = aIter->next) {
238 int max = 0, lpc = 0;
242 max = numXpathResults(xpathObj);
244 for (lpc = 0; lpc < max; lpc++) {
249 crm_trace(
"Applying %x to %s for %s", acl->mode, path, acl->xpath);
251 #ifdef SUSE_ACL_COMPAT 252 if (is_not_set(p->
flags, acl->mode)
257 "multiple ACL rules, only the first applies " 258 "('%s' wins over '%s')",
259 path, __xml_acl_to_text(p->
flags),
260 __xml_acl_to_text(acl->mode));
265 p->
flags |= acl->mode;
268 crm_trace(
"Now enforcing ACL: %s (%d matches)", acl->xpath, max);
277 p = xml->doc->_private;
278 crm_info(
"Enforcing default ACL for %s to %s",
279 p->
user, crm_element_name(xml));
290 if ((target == NULL) || (target->doc == NULL)
291 || (target->doc->_private == NULL)) {
295 p = target->doc->_private;
297 crm_trace(
"no acls needed for '%s'", user);
299 }
else if (p->
acls == NULL) {
304 p->
user = strdup(user);
307 xmlNode *child = NULL;
309 for (child = __xml_first_child_element(acls); child;
310 child = __xml_next_element(child)) {
311 const char *tag = crm_element_name(child);
317 if (
id && strcmp(
id, user) == 0) {
319 p->
acls = __xml_acl_parse_entry(acls, child, p->
acls);
335 }
else if (is_set(allowed, requested)) {
357 __xml_purge_attributes(xmlNode *xml)
359 xmlNode *child = NULL;
360 xmlAttr *xIter = NULL;
361 bool readable_children = FALSE;
365 crm_trace(
"%s[@id=%s] is readable", crm_element_name(xml),
ID(xml));
369 xIter = xml->properties;
370 while (xIter != NULL) {
371 xmlAttr *tmp = xIter;
372 const char *prop_name = (
const char *)xIter->name;
379 xmlUnsetProp(xml, tmp->name);
382 child = __xml_first_child(xml);
383 while ( child != NULL ) {
384 xmlNode *tmp = child;
386 child = __xml_next(child);
387 readable_children |= __xml_purge_attributes(tmp);
390 if (readable_children == FALSE) {
393 return readable_children;
401 xmlNode *target = NULL;
407 crm_trace(
"no acls needed for '%s'", user);
411 crm_trace(
"filtering copy of %p for '%s'", xml, user);
413 if (target == NULL) {
421 doc = target->doc->_private;
422 for(aIter = doc->
acls; aIter != NULL && target; aIter = aIter->next) {
429 }
else if (acl->xpath) {
431 xmlXPathObjectPtr xpathObj =
xpath_search(target, acl->xpath);
433 max = numXpathResults(xpathObj);
434 for(lpc = 0; lpc < max; lpc++) {
437 crm_trace(
"Purging attributes from %s", acl->xpath);
438 if (__xml_purge_attributes(match) == FALSE && match == target) {
439 crm_trace(
"No access to the entire document for %s", user);
444 crm_trace(
"Enforced ACL %s (%d matches)", acl->xpath, max);
449 p = target->_private;
451 && (__xml_purge_attributes(target) == FALSE)) {
452 crm_trace(
"No access to the entire document for %s", user);
457 g_list_free_full(doc->
acls, __xml_acl_free);
461 crm_trace(
"Ordinary user '%s' cannot access the CIB without any defined ACLs",
487 implicitly_allowed(xmlNode *xml)
491 for (xmlAttr *prop = xml->properties; prop != NULL; prop = prop->next) {
492 if (strcmp((
const char *) prop->name,
XML_ATTR_ID) != 0) {
507 #define display_id(xml) (ID(xml)? ID(xml) : "<unset>") 528 if (implicitly_allowed(xml)) {
529 crm_trace(
"Creation of <%s> scaffolding with id=\"%s\"" 530 " is implicitly allowed",
534 crm_trace(
"ACLs allow creation of <%s> with id=\"%s\"",
537 }
else if (check_top) {
538 crm_trace(
"ACLs disallow creation of <%s> with id=\"%s\"",
544 crm_trace(
"ACLs would disallow creation of <%s> with id=\"%s\"",
549 for (xmlNode *cIter = __xml_first_child(xml); cIter != NULL; ) {
550 xmlNode *child = cIter;
551 cIter = __xml_next(cIter);
559 if (xml && xml->doc && xml->doc->_private){
583 if (xml && xml->doc && xml->doc->_private){
601 xmlNode *parent = xml;
605 if (docp->
acls == NULL) {
606 crm_trace(
"Ordinary user %s cannot access the CIB without any defined ACLs",
626 xmlAttr *attr = xmlHasProp(xml, (
const xmlChar *)name);
633 while (parent && parent->_private) {
635 if (__xml_acl_mode_test(p->
flags, mode)) {
639 crm_trace(
"%x access denied to %s: parent", mode, buffer);
643 parent = parent->parent;
646 crm_trace(
"%x access denied to %s: default", mode, buffer);
659 if (user == NULL || strlen(user) == 0) {
666 }
else if (strcmp(user,
"root") == 0) {
681 struct passwd *pwent = getpwuid(uid);
684 crm_perror(LOG_INFO,
"Cannot get user details for user ID %d", uid);
687 return strdup(pwent->pw_name);
693 static const char *effective_user = NULL;
694 const char *requested_user = NULL;
695 const char *user = NULL;
697 if (effective_user == NULL) {
699 if (effective_user == NULL) {
700 effective_user = strdup(
"#unprivileged");
701 CRM_CHECK(effective_user != NULL,
return NULL);
702 crm_err(
"Unable to determine effective user, assuming unprivileged for ACLs");
707 if (requested_user == NULL) {
716 if (is_privileged(effective_user) == FALSE) {
720 user = effective_user;
722 }
else if (peer_user == NULL && requested_user == NULL) {
726 user = effective_user;
728 }
else if (peer_user == NULL) {
730 user = requested_user;
732 }
else if (is_privileged(peer_user) == FALSE) {
738 }
else if (requested_user == NULL) {
744 user = requested_user;
756 return requested_user;
#define CRM_CHECK(expr, failure_action)
void xml_acl_disable(xmlNode *xml)
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)
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
#define CRM_LOG_ASSERT(expr)
#define clear_bit(word, bit)
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
void pcmk__post_process_acl(xmlNode *xml, bool check_top)
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...)
#define XML_ACL_TAG_USERv1
Wrappers for and extensions to libxml2.
G_GNUC_INTERNAL void pcmk__set_xml_flag(xmlNode *xml, enum xml_private_flags flag)
#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
#define crm_config_warn(fmt...)
#define crm_perror(level, fmt, args...)
Log a system error message.
#define crm_err(fmt, args...)
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
#define XML_ACL_TAG_ROLE_REFv1
void pcmk__apply_acl(xmlNode *xml)
xmlNode * getXpathResult(xmlXPathObjectPtr xpathObj, int index)
char * xml_get_path(xmlNode *xml)
const char * crm_acl_get_set_user(xmlNode *request, const char *field, const char *peer_user)
#define XML_ACL_TAG_ROLE_REF
G_GNUC_INTERNAL bool pcmk__tracking_xml_changes(xmlNode *xml, bool lazy)
void freeXpathObject(xmlXPathObjectPtr xpathObj)
#define crm_info(fmt, args...)
char * uid2username(uid_t uid)
struct xml_acl_s xml_acl_t