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);
69 if ((tag == NULL) && (ref == NULL) && (xpath == NULL)) {
71 crm_trace(
"Ignoring ACL <%s> element without selection criteria",
72 crm_element_name(xml));
81 acl->xpath = strdup(xpath);
83 crm_trace(
"Unpacked ACL <%s> element using xpath: %s",
84 crm_element_name(xml), acl->xpath);
125 acl->xpath = strdup(buffer);
128 crm_trace(
"Unpacked ACL <%s> element as xpath: %s",
129 crm_element_name(xml), acl->xpath);
132 return g_list_append(acls, acl);
146 __xml_acl_parse_entry(xmlNode *acl_top, xmlNode *acl_entry, GList *acls)
148 xmlNode *child = NULL;
150 for (child = __xml_first_child_element(acl_entry); child;
151 child = __xml_next_element(child)) {
152 const char *tag = crm_element_name(child);
157 crm_trace(
"Unpacking ACL <%s> element of kind '%s'", tag, kind);
160 crm_trace(
"Unpacking ACL <%s> element", tag);
168 xmlNode *role = NULL;
170 for (role = __xml_first_child_element(acl_top); role;
171 role = __xml_next_element(role)) {
176 if (role_id && strcmp(ref_role, role_id) == 0) {
177 crm_trace(
"Unpacking referenced role '%s' in ACL <%s> element",
178 role_id, crm_element_name(acl_entry));
179 acls = __xml_acl_parse_entry(acl_top, role, acls);
196 crm_warn(
"Ignoring unknown ACL %s '%s'",
197 (kind?
"kind" :
"element"), tag);
246 xmlXPathObjectPtr xpathObj = NULL;
249 crm_trace(
"Skipping ACLs for user '%s' because not enabled for this XML",
254 for (aIter = p->
acls; aIter != NULL; aIter = aIter->next) {
255 int max = 0, lpc = 0;
259 max = numXpathResults(xpathObj);
261 for (lpc = 0; lpc < max; lpc++) {
266 crm_trace(
"Applying %s ACL to %s matched by %s",
267 __xml_acl_to_text(acl->mode), path, acl->xpath);
269 #ifdef SUSE_ACL_COMPAT
270 if (is_not_set(p->
flags, acl->mode)
275 "multiple ACL rules, only the first applies "
276 "('%s' wins over '%s')",
277 path, __xml_acl_to_text(p->
flags),
278 __xml_acl_to_text(acl->mode));
283 p->
flags |= acl->mode;
286 crm_trace(
"Applied %s ACL %s (%d match%s)",
287 __xml_acl_to_text(acl->mode), acl->xpath, max,
288 ((max == 1)?
"" :
"es"));
297 p = xml->doc->_private;
298 crm_info(
"Applied default deny ACL for user '%s' to <%s>",
299 p->
user, crm_element_name(xml));
319 || (
target->doc->_private == NULL)) {
323 p =
target->doc->_private;
325 crm_trace(
"Not unpacking ACLs because not required for user '%s'",
328 }
else if (p->
acls == NULL) {
333 p->
user = strdup(user);
336 xmlNode *child = NULL;
338 for (child = __xml_first_child_element(acls); child;
339 child = __xml_next_element(child)) {
340 const char *tag = crm_element_name(child);
346 if (
id && strcmp(
id, user) == 0) {
347 crm_debug(
"Unpacking ACLs for user '%s'",
id);
348 p->
acls = __xml_acl_parse_entry(acls, child, p->
acls);
364 }
else if (is_set(allowed, requested)) {
386 __xml_purge_attributes(xmlNode *xml)
388 xmlNode *child = NULL;
389 xmlAttr *xIter = NULL;
390 bool readable_children = FALSE;
394 crm_trace(
"%s[@id=%s] is readable", crm_element_name(xml),
ID(xml));
398 xIter = xml->properties;
399 while (xIter != NULL) {
400 xmlAttr *tmp = xIter;
401 const char *prop_name = (
const char *)xIter->name;
408 xmlUnsetProp(xml, tmp->name);
411 child = __xml_first_child(xml);
412 while ( child != NULL ) {
413 xmlNode *tmp = child;
415 child = __xml_next(child);
416 readable_children |= __xml_purge_attributes(tmp);
419 if (readable_children == FALSE) {
422 return readable_children;
447 crm_trace(
"Not filtering XML because ACLs not required for user '%s'",
452 crm_trace(
"Filtering XML copy using user '%s' ACLs", user);
462 doc =
target->doc->_private;
463 for(aIter = doc->
acls; aIter != NULL &&
target; aIter = aIter->next) {
470 }
else if (acl->xpath) {
474 max = numXpathResults(xpathObj);
475 for(lpc = 0; lpc < max; lpc++) {
478 if (__xml_purge_attributes(match) == FALSE && match ==
target) {
479 crm_trace(
"ACLs deny user '%s' access to entire XML document",
485 crm_trace(
"ACLs deny user '%s' access to %s (%d match%s)",
486 user, acl->xpath, max, ((max == 1)?
"" :
"es"));
493 && (__xml_purge_attributes(
target) == FALSE)) {
494 crm_trace(
"ACLs deny user '%s' access to entire XML document", user);
499 g_list_free_full(doc->
acls, __xml_acl_free);
503 crm_trace(
"User '%s' without ACLs denied access to entire XML document",
529 implicitly_allowed(xmlNode *xml)
533 for (xmlAttr *prop = xml->properties; prop != NULL; prop = prop->next) {
534 if (strcmp((
const char *) prop->name,
XML_ATTR_ID) != 0) {
549 #define display_id(xml) (ID(xml)? ID(xml) : "<unset>")
570 if (implicitly_allowed(xml)) {
571 crm_trace(
"Creation of <%s> scaffolding with id=\"%s\""
572 " is implicitly allowed",
576 crm_trace(
"ACLs allow creation of <%s> with id=\"%s\"",
579 }
else if (check_top) {
580 crm_trace(
"ACLs disallow creation of <%s> with id=\"%s\"",
586 crm_notice(
"ACLs would disallow creation of %s<%s> with id=\"%s\" ",
587 ((xml == xmlDocGetRootElement(xml->doc))?
"root element " :
""),
592 for (xmlNode *cIter = __xml_first_child(xml); cIter != NULL; ) {
593 xmlNode *child = cIter;
594 cIter = __xml_next(cIter);
602 if (xml && xml->doc && xml->doc->_private){
626 if (xml && xml->doc && xml->doc->_private){
644 xmlNode *parent = xml;
656 if (docp->
acls == NULL) {
657 crm_trace(
"User '%s' without ACLs denied %s access to %s",
658 docp->
user, __xml_acl_to_text(mode), buffer);
676 while (parent && parent->_private) {
678 if (__xml_acl_mode_test(p->
flags, mode)) {
682 crm_trace(
"Parent ACL denies user '%s' %s access to %s",
683 docp->
user, __xml_acl_to_text(mode), buffer);
687 parent = parent->parent;
690 crm_trace(
"Default ACL denies user '%s' %s access to %s",
691 docp->
user, __xml_acl_to_text(mode), buffer);
711 if (pcmk__str_empty(user)) {
712 crm_trace(
"ACLs not required because no user set");
716 crm_trace(
"ACLs not required for privileged user %s", user);
722 crm_trace(
"ACLs not required because not supported by this build");
731 struct passwd *pwent = getpwuid(uid);
734 crm_perror(LOG_INFO,
"Cannot get user details for user ID %d", uid);
737 return strdup(pwent->pw_name);
760 const char *peer_user)
762 static const char *effective_user = NULL;
763 const char *requested_user = NULL;
764 const char *user = NULL;
766 if (effective_user == NULL) {
768 if (effective_user == NULL) {
769 effective_user = strdup(
"#unprivileged");
770 CRM_CHECK(effective_user != NULL,
return NULL);
771 crm_err(
"Unable to determine effective user, assuming unprivileged for ACLs");
776 if (requested_user == NULL) {
785 if (!pcmk__is_privileged(effective_user)) {
789 user = effective_user;
791 }
else if (peer_user == NULL && requested_user == NULL) {
795 user = effective_user;
797 }
else if (peer_user == NULL) {
799 user = requested_user;
801 }
else if (!pcmk__is_privileged(peer_user)) {
807 }
else if (requested_user == NULL) {
813 user = requested_user;
825 return requested_user;