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;