11 #include <sys/types.h>
17 #include <libxml/tree.h>
24 #define MAX_XPATH_LEN 4096
26 typedef struct xml_acl_s {
32 __xml_acl_free(
void *
data)
45 g_list_free_full(acls, __xml_acl_free);
66 if ((tag == NULL) && (ref == NULL) && (xpath == NULL)) {
77 acl->xpath = strdup(xpath);
118 acl->xpath = strdup(buffer);
119 crm_trace(
"Built xpath: %s", acl->xpath);
122 acls = g_list_append(acls, acl);
128 __xml_acl_parse_entry(xmlNode *acl_top, xmlNode *acl_entry, GList *acls)
130 xmlNode *child = NULL;
132 for (child = __xml_first_child(acl_entry); child;
133 child = __xml_next(child)) {
134 const char *tag = crm_element_name(child);
141 crm_trace(
"Processing %s %p", tag, child);
150 xmlNode *role = NULL;
152 for (role = __xml_first_child(acl_top); role;
153 role = __xml_next(role)) {
158 if (role_id && strcmp(ref_role, role_id) == 0) {
159 crm_debug(
"Unpacking referenced role: %s", role_id);
160 acls = __xml_acl_parse_entry(acl_top, role, acls);
177 crm_warn(
"Unknown ACL entry: %s/%s", tag, kind);
206 #ifdef SUSE_ACL_COMPAT
228 xmlXPathObjectPtr xpathObj = NULL;
235 for (aIter = p->
acls; aIter != NULL; aIter = aIter->next) {
236 int max = 0, lpc = 0;
240 max = numXpathResults(xpathObj);
242 for (lpc = 0; lpc < max; lpc++) {
247 crm_trace(
"Applying %x to %s for %s", acl->mode, path, acl->xpath);
249 #ifdef SUSE_ACL_COMPAT
250 if (is_not_set(p->
flags, acl->mode)
255 "multiple ACL rules, only the first applies "
256 "('%s' wins over '%s')",
257 path, __xml_acl_to_text(p->
flags),
258 __xml_acl_to_text(acl->mode));
263 p->
flags |= acl->mode;
266 crm_trace(
"Now enforcing ACL: %s (%d matches)", acl->xpath, max);
275 p = xml->doc->_private;
276 crm_info(
"Enforcing default ACL for %s to %s",
277 p->
user, crm_element_name(xml));
288 if ((target == NULL) || (target->doc == NULL)
289 || (target->doc->_private == NULL)) {
293 p = target->doc->_private;
295 crm_trace(
"no acls needed for '%s'", user);
297 }
else if (p->
acls == NULL) {
302 p->
user = strdup(user);
305 xmlNode *child = NULL;
307 for (child = __xml_first_child(acls); child;
308 child = __xml_next(child)) {
309 const char *tag = crm_element_name(child);
315 if (
id && strcmp(
id, user) == 0) {
317 p->
acls = __xml_acl_parse_entry(acls, child, p->
acls);
333 }
else if (is_set(allowed, requested)) {
355 __xml_purge_attributes(xmlNode *xml)
357 xmlNode *child = NULL;
358 xmlAttr *xIter = NULL;
359 bool readable_children = FALSE;
363 crm_trace(
"%s[@id=%s] is readable", crm_element_name(xml),
ID(xml));
367 xIter = xml->properties;
368 while (xIter != NULL) {
369 xmlAttr *tmp = xIter;
370 const char *prop_name = (
const char *)xIter->name;
377 xmlUnsetProp(xml, tmp->name);
380 child = __xml_first_child(xml);
381 while ( child != NULL ) {
382 xmlNode *tmp = child;
384 child = __xml_next(child);
385 readable_children |= __xml_purge_attributes(tmp);
388 if (readable_children == FALSE) {
391 return readable_children;
399 xmlNode *target = NULL;
405 crm_trace(
"no acls needed for '%s'", user);
409 crm_trace(
"filtering copy of %p for '%s'", xml, user);
411 if (target == NULL) {
419 doc = target->doc->_private;
420 for(aIter = doc->
acls; aIter != NULL && target; aIter = aIter->next) {
427 }
else if (acl->xpath) {
429 xmlXPathObjectPtr xpathObj =
xpath_search(target, acl->xpath);
431 max = numXpathResults(xpathObj);
432 for(lpc = 0; lpc < max; lpc++) {
435 crm_trace(
"Purging attributes from %s", acl->xpath);
436 if (__xml_purge_attributes(match) == FALSE && match == target) {
437 crm_trace(
"No access to the entire document for %s", user);
442 crm_trace(
"Enforced ACL %s (%d matches)", acl->xpath, max);
447 p = target->_private;
449 && (__xml_purge_attributes(target) == FALSE)) {
450 crm_trace(
"No access to the entire document for %s", user);
455 g_list_free_full(doc->
acls, __xml_acl_free);
459 crm_trace(
"Ordinary user '%s' cannot access the CIB without any defined ACLs",
475 xmlNode *cIter = __xml_first_child(xml);
479 xmlAttr *xIter = NULL;
486 for (xIter = xml->properties; xIter != NULL; xIter = xIter->next) {
487 const char *prop_name = (
const char *)xIter->name;
495 crm_trace(
"Creation of %s=%s is allowed",
496 crm_element_name(xml),
ID(xml));
500 crm_trace(
"Cannot add new node %s at %s",
501 crm_element_name(xml), path);
503 if (xml != xmlDocGetRootElement(xml->doc)) {
514 while (cIter != NULL) {
515 xmlNode *child = cIter;
516 cIter = __xml_next(cIter);
524 if (xml && xml->doc && xml->doc->_private){
548 if (xml && xml->doc && xml->doc->_private){
566 xmlNode *parent = xml;
570 if (docp->
acls == NULL) {
571 crm_trace(
"Ordinary user %s cannot access the CIB without any defined ACLs",
591 xmlAttr *attr = xmlHasProp(xml, (
const xmlChar *)name);
598 while (parent && parent->_private) {
600 if (__xml_acl_mode_test(p->
flags, mode)) {
604 crm_trace(
"%x access denied to %s: parent", mode, buffer);
608 parent = parent->parent;
611 crm_trace(
"%x access denied to %s: default", mode, buffer);
624 if (user == NULL || strlen(user) == 0) {
631 }
else if (strcmp(user,
"root") == 0) {
646 struct passwd *pwent = getpwuid(uid);
649 crm_perror(LOG_INFO,
"Cannot get user details for user ID %d", uid);
652 return strdup(pwent->pw_name);
658 static const char *effective_user = NULL;
659 const char *requested_user = NULL;
660 const char *user = NULL;
662 if (effective_user == NULL) {
664 if (effective_user == NULL) {
665 effective_user = strdup(
"#unprivileged");
666 CRM_CHECK(effective_user != NULL,
return NULL);
667 crm_err(
"Unable to determine effective user, assuming unprivileged for ACLs");
672 if (requested_user == NULL) {
681 if (is_privileged(effective_user) == FALSE) {
685 user = effective_user;
687 }
else if (peer_user == NULL && requested_user == NULL) {
691 user = effective_user;
693 }
else if (peer_user == NULL) {
695 user = requested_user;
697 }
else if (is_privileged(peer_user) == FALSE) {
703 }
else if (requested_user == NULL) {
709 user = requested_user;
721 return requested_user;