pacemaker  2.0.5-ba59be712
Scalable High-Availability cluster resource manager
acl.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2020 the Pacemaker project contributors
3  *
4  * The version control history for this file may have further details.
5  *
6  * This source code is licensed under the GNU Lesser General Public License
7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8  */
9 
10 #include <crm_internal.h>
11 
12 #include <stdio.h>
13 #include <sys/types.h>
14 #include <pwd.h>
15 #include <string.h>
16 #include <stdlib.h>
17 #include <stdarg.h>
18 
19 #include <libxml/tree.h>
20 
21 #include <crm/crm.h>
22 #include <crm/msg_xml.h>
23 #include <crm/common/xml.h>
25 #include "crmcommon_private.h"
26 
27 #define MAX_XPATH_LEN 4096
28 
29 typedef struct xml_acl_s {
30  enum xml_private_flags mode;
31  char *xpath;
32 } xml_acl_t;
33 
34 static void
35 free_acl(void *data)
36 {
37  if (data) {
38  xml_acl_t *acl = data;
39 
40  free(acl->xpath);
41  free(acl);
42  }
43 }
44 
45 void
46 pcmk__free_acls(GList *acls)
47 {
48  g_list_free_full(acls, free_acl);
49 }
50 
51 static GList *
52 create_acl(xmlNode *xml, GList *acls, enum xml_private_flags mode)
53 {
54  xml_acl_t *acl = NULL;
55 
56  const char *tag = crm_element_value(xml, XML_ACL_ATTR_TAG);
57  const char *ref = crm_element_value(xml, XML_ACL_ATTR_REF);
58  const char *xpath = crm_element_value(xml, XML_ACL_ATTR_XPATH);
59  const char *attr = crm_element_value(xml, XML_ACL_ATTR_ATTRIBUTE);
60 
61  if (tag == NULL) {
62  // @COMPAT rolling upgrades <=1.1.11
64  }
65  if (ref == NULL) {
66  // @COMPAT rolling upgrades <=1.1.11
68  }
69 
70  if ((tag == NULL) && (ref == NULL) && (xpath == NULL)) {
71  // Schema should prevent this, but to be safe ...
72  crm_trace("Ignoring ACL <%s> element without selection criteria",
73  crm_element_name(xml));
74  return NULL;
75  }
76 
77  acl = calloc(1, sizeof (xml_acl_t));
78  CRM_ASSERT(acl != NULL);
79 
80  acl->mode = mode;
81  if (xpath) {
82  acl->xpath = strdup(xpath);
83  CRM_ASSERT(acl->xpath != NULL);
84  crm_trace("Unpacked ACL <%s> element using xpath: %s",
85  crm_element_name(xml), acl->xpath);
86 
87  } else {
88  int offset = 0;
89  char buffer[MAX_XPATH_LEN];
90 
91  if (tag) {
92  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
93  "//%s", tag);
94  } else {
95  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
96  "//*");
97  }
98 
99  if (ref || attr) {
100  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
101  "[");
102  }
103 
104  if (ref) {
105  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
106  "@id='%s'", ref);
107  }
108 
109  // NOTE: schema currently does not allow this
110  if (ref && attr) {
111  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
112  " and ");
113  }
114 
115  if (attr) {
116  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
117  "@%s", attr);
118  }
119 
120  if (ref || attr) {
121  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
122  "]");
123  }
124 
125  CRM_LOG_ASSERT(offset > 0);
126  acl->xpath = strdup(buffer);
127  CRM_ASSERT(acl->xpath != NULL);
128 
129  crm_trace("Unpacked ACL <%s> element as xpath: %s",
130  crm_element_name(xml), acl->xpath);
131  }
132 
133  return g_list_append(acls, acl);
134 }
135 
146 static GList *
147 parse_acl_entry(xmlNode *acl_top, xmlNode *acl_entry, GList *acls)
148 {
149  xmlNode *child = NULL;
150 
151  for (child = pcmk__xe_first_child(acl_entry); child;
152  child = pcmk__xe_next(child)) {
153  const char *tag = crm_element_name(child);
154  const char *kind = crm_element_value(child, XML_ACL_ATTR_KIND);
155 
156  if (strcmp(XML_ACL_TAG_PERMISSION, tag) == 0){
157  CRM_ASSERT(kind != NULL);
158  crm_trace("Unpacking ACL <%s> element of kind '%s'", tag, kind);
159  tag = kind;
160  } else {
161  crm_trace("Unpacking ACL <%s> element", tag);
162  }
163 
164  if (strcmp(XML_ACL_TAG_ROLE_REF, tag) == 0
165  || strcmp(XML_ACL_TAG_ROLE_REFv1, tag) == 0) {
166  const char *ref_role = crm_element_value(child, XML_ATTR_ID);
167 
168  if (ref_role) {
169  xmlNode *role = NULL;
170 
171  for (role = pcmk__xe_first_child(acl_top); role;
172  role = pcmk__xe_next(role)) {
173  if (!strcmp(XML_ACL_TAG_ROLE, (const char *) role->name)) {
174  const char *role_id = crm_element_value(role,
175  XML_ATTR_ID);
176 
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);
181  break;
182  }
183  }
184  }
185  }
186 
187  } else if (strcmp(XML_ACL_TAG_READ, tag) == 0) {
188  acls = create_acl(child, acls, xpf_acl_read);
189 
190  } else if (strcmp(XML_ACL_TAG_WRITE, tag) == 0) {
191  acls = create_acl(child, acls, xpf_acl_write);
192 
193  } else if (strcmp(XML_ACL_TAG_DENY, tag) == 0) {
194  acls = create_acl(child, acls, xpf_acl_deny);
195 
196  } else {
197  crm_warn("Ignoring unknown ACL %s '%s'",
198  (kind? "kind" : "element"), tag);
199  }
200  }
201 
202  return acls;
203 }
204 
205 /*
206  <acls>
207  <acl_target id="l33t-haxor"><role id="auto-l33t-haxor"/></acl_target>
208  <acl_role id="auto-l33t-haxor">
209  <acl_permission id="crook-nothing" kind="deny" xpath="/cib"/>
210  </acl_role>
211  <acl_target id="niceguy">
212  <role id="observer"/>
213  </acl_target>
214  <acl_role id="observer">
215  <acl_permission id="observer-read-1" kind="read" xpath="/cib"/>
216  <acl_permission id="observer-write-1" kind="write" xpath="//nvpair[@name='stonith-enabled']"/>
217  <acl_permission id="observer-write-2" kind="write" xpath="//nvpair[@name='target-role']"/>
218  </acl_role>
219  <acl_target id="badidea"><role id="auto-badidea"/></acl_target>
220  <acl_role id="auto-badidea">
221  <acl_permission id="badidea-resources" kind="read" xpath="//meta_attributes"/>
222  <acl_permission id="badidea-resources-2" kind="deny" reference="dummy-meta_attributes"/>
223  </acl_role>
224  </acls>
225 */
226 
227 static const char *
228 acl_to_text(enum xml_private_flags flags)
229 {
231  return "deny";
232 
233  } else if (pcmk_any_flags_set(flags, xpf_acl_write|xpf_acl_create)) {
234  return "read/write";
235 
236  } else if (pcmk_is_set(flags, xpf_acl_read)) {
237  return "read";
238  }
239  return "none";
240 }
241 
242 void
243 pcmk__apply_acl(xmlNode *xml)
244 {
245  GListPtr aIter = NULL;
246  xml_private_t *p = xml->doc->_private;
247  xmlXPathObjectPtr xpathObj = NULL;
248 
249  if (!xml_acl_enabled(xml)) {
250  crm_trace("Skipping ACLs for user '%s' because not enabled for this XML",
251  p->user);
252  return;
253  }
254 
255  for (aIter = p->acls; aIter != NULL; aIter = aIter->next) {
256  int max = 0, lpc = 0;
257  xml_acl_t *acl = aIter->data;
258 
259  xpathObj = xpath_search(xml, acl->xpath);
260  max = numXpathResults(xpathObj);
261 
262  for (lpc = 0; lpc < max; lpc++) {
263  xmlNode *match = getXpathResult(xpathObj, lpc);
264  char *path = xml_get_path(match);
265 
266  p = match->_private;
267  crm_trace("Applying %s ACL to %s matched by %s",
268  acl_to_text(acl->mode), path, acl->xpath);
269 
270 #ifdef SUSE_ACL_COMPAT
271  if (!pcmk_is_set(p->flags, acl->mode)
272  && pcmk_any_flags_set(p->flags,
274  pcmk__config_warn("Configuration element %s is matched by "
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));
279  free(path);
280  continue;
281  }
282 #endif
283  pcmk__set_xml_flags(p, acl->mode);
284  free(path);
285  }
286  crm_trace("Applied %s ACL %s (%d match%s)",
287  acl_to_text(acl->mode), acl->xpath, max,
288  ((max == 1)? "" : "es"));
289  freeXpathObject(xpathObj);
290  }
291 }
292 
301 void
302 pcmk__unpack_acl(xmlNode *source, xmlNode *target, const char *user)
303 {
304 #if ENABLE_ACL
305  xml_private_t *p = NULL;
306 
307  if ((target == NULL) || (target->doc == NULL)
308  || (target->doc->_private == NULL)) {
309  return;
310  }
311 
312  p = target->doc->_private;
313  if (!pcmk_acl_required(user)) {
314  crm_trace("Not unpacking ACLs because not required for user '%s'",
315  user);
316 
317  } else if (p->acls == NULL) {
318  xmlNode *acls = get_xpath_object("//" XML_CIB_TAG_ACLS,
319  source, LOG_NEVER);
320 
321  free(p->user);
322  p->user = strdup(user);
323 
324  if (acls) {
325  xmlNode *child = NULL;
326 
327  for (child = pcmk__xe_first_child(acls); child;
328  child = pcmk__xe_next(child)) {
329  const char *tag = crm_element_name(child);
330 
331  if (!strcmp(tag, XML_ACL_TAG_USER)
332  || !strcmp(tag, XML_ACL_TAG_USERv1)) {
333  const char *id = crm_element_value(child, XML_ATTR_ID);
334 
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);
338  }
339  }
340  }
341  }
342  }
343 #endif
344 }
345 
346 static inline bool
347 test_acl_mode(enum xml_private_flags allowed, enum xml_private_flags requested)
348 {
349  if (pcmk_is_set(allowed, xpf_acl_deny)) {
350  return false;
351 
352  } else if (pcmk_all_flags_set(allowed, requested)) {
353  return true;
354 
355  } else if (pcmk_is_set(requested, xpf_acl_read)
356  && pcmk_is_set(allowed, xpf_acl_write)) {
357  return true;
358 
359  } else if (pcmk_is_set(requested, xpf_acl_create)
360  && pcmk_any_flags_set(allowed, xpf_acl_write|xpf_created)) {
361  return true;
362  }
363  return false;
364 }
365 
366 static bool
367 purge_xml_attributes(xmlNode *xml)
368 {
369  xmlNode *child = NULL;
370  xmlAttr *xIter = NULL;
371  bool readable_children = false;
372  xml_private_t *p = xml->_private;
373 
374  if (test_acl_mode(p->flags, xpf_acl_read)) {
375  crm_trace("%s[@id=%s] is readable", crm_element_name(xml), ID(xml));
376  return true;
377  }
378 
379  xIter = xml->properties;
380  while (xIter != NULL) {
381  xmlAttr *tmp = xIter;
382  const char *prop_name = (const char *)xIter->name;
383 
384  xIter = xIter->next;
385  if (strcmp(prop_name, XML_ATTR_ID) == 0) {
386  continue;
387  }
388 
389  xmlUnsetProp(xml, tmp->name);
390  }
391 
392  child = pcmk__xml_first_child(xml);
393  while ( child != NULL ) {
394  xmlNode *tmp = child;
395 
396  child = pcmk__xml_next(child);
397  readable_children |= purge_xml_attributes(tmp);
398  }
399 
400  if (!readable_children) {
401  free_xml(xml); /* Nothing readable under here, purge completely */
402  }
403  return readable_children;
404 }
405 
418 bool
419 xml_acl_filtered_copy(const char *user, xmlNode *acl_source, xmlNode *xml,
420  xmlNode **result)
421 {
422  GListPtr aIter = NULL;
423  xmlNode *target = NULL;
424  xml_private_t *doc = NULL;
425 
426  *result = NULL;
427  if ((xml == NULL) || !pcmk_acl_required(user)) {
428  crm_trace("Not filtering XML because ACLs not required for user '%s'",
429  user);
430  return false;
431  }
432 
433  crm_trace("Filtering XML copy using user '%s' ACLs", user);
434  target = copy_xml(xml);
435  if (target == NULL) {
436  return true;
437  }
438 
439  pcmk__unpack_acl(acl_source, target, user);
442 
443  doc = target->doc->_private;
444  for(aIter = doc->acls; aIter != NULL && target; aIter = aIter->next) {
445  int max = 0;
446  xml_acl_t *acl = aIter->data;
447 
448  if (acl->mode != xpf_acl_deny) {
449  /* Nothing to do */
450 
451  } else if (acl->xpath) {
452  int lpc = 0;
453  xmlXPathObjectPtr xpathObj = xpath_search(target, acl->xpath);
454 
455  max = numXpathResults(xpathObj);
456  for(lpc = 0; lpc < max; lpc++) {
457  xmlNode *match = getXpathResult(xpathObj, lpc);
458 
459  if (!purge_xml_attributes(match) && (match == target)) {
460  crm_trace("ACLs deny user '%s' access to entire XML document",
461  user);
462  freeXpathObject(xpathObj);
463  return true;
464  }
465  }
466  crm_trace("ACLs deny user '%s' access to %s (%d %s)",
467  user, acl->xpath, max,
468  pcmk__plural_alt(max, "match", "matches"));
469  freeXpathObject(xpathObj);
470  }
471  }
472 
473  if (!purge_xml_attributes(target)) {
474  crm_trace("ACLs deny user '%s' access to entire XML document", user);
475  return true;
476  }
477 
478  if (doc->acls) {
479  g_list_free_full(doc->acls, free_acl);
480  doc->acls = NULL;
481 
482  } else {
483  crm_trace("User '%s' without ACLs denied access to entire XML document",
484  user);
485  free_xml(target);
486  target = NULL;
487  }
488 
489  if (target) {
490  *result = target;
491  }
492 
493  return true;
494 }
495 
508 static bool
509 implicitly_allowed(xmlNode *xml)
510 {
511  char *path = NULL;
512 
513  for (xmlAttr *prop = xml->properties; prop != NULL; prop = prop->next) {
514  if (strcmp((const char *) prop->name, XML_ATTR_ID) != 0) {
515  return false;
516  }
517  }
518 
519  path = xml_get_path(xml);
520  if (strstr(path, "/" XML_CIB_TAG_ACLS "/") != NULL) {
521  free(path);
522  return false;
523  }
524  free(path);
525 
526  return true;
527 }
528 
529 #define display_id(xml) (ID(xml)? ID(xml) : "<unset>")
530 
544 void
545 pcmk__apply_creation_acl(xmlNode *xml, bool check_top)
546 {
547  xml_private_t *p = xml->_private;
548 
549  if (pcmk_is_set(p->flags, xpf_created)) {
550  if (implicitly_allowed(xml)) {
551  crm_trace("Creation of <%s> scaffolding with id=\"%s\""
552  " is implicitly allowed",
553  crm_element_name(xml), display_id(xml));
554 
555  } else if (pcmk__check_acl(xml, NULL, xpf_acl_write)) {
556  crm_trace("ACLs allow creation of <%s> with id=\"%s\"",
557  crm_element_name(xml), display_id(xml));
558 
559  } else if (check_top) {
560  crm_trace("ACLs disallow creation of <%s> with id=\"%s\"",
561  crm_element_name(xml), display_id(xml));
563  return;
564 
565  } else {
566  crm_notice("ACLs would disallow creation of %s<%s> with id=\"%s\" ",
567  ((xml == xmlDocGetRootElement(xml->doc))? "root element " : ""),
568  crm_element_name(xml), display_id(xml));
569  }
570  }
571 
572  for (xmlNode *cIter = pcmk__xml_first_child(xml); cIter != NULL; ) {
573  xmlNode *child = cIter;
574  cIter = pcmk__xml_next(cIter); /* In case it is free'd */
575  pcmk__apply_creation_acl(child, true);
576  }
577 }
578 
579 bool
580 xml_acl_denied(xmlNode *xml)
581 {
582  if (xml && xml->doc && xml->doc->_private){
583  xml_private_t *p = xml->doc->_private;
584 
585  return pcmk_is_set(p->flags, xpf_acl_denied);
586  }
587  return false;
588 }
589 
590 void
591 xml_acl_disable(xmlNode *xml)
592 {
593  if (xml_acl_enabled(xml)) {
594  xml_private_t *p = xml->doc->_private;
595 
596  /* Catch anything that was created but shouldn't have been */
597  pcmk__apply_acl(xml);
598  pcmk__apply_creation_acl(xml, false);
600  }
601 }
602 
603 bool
604 xml_acl_enabled(xmlNode *xml)
605 {
606  if (xml && xml->doc && xml->doc->_private){
607  xml_private_t *p = xml->doc->_private;
608 
609  return pcmk_is_set(p->flags, xpf_acl_enabled);
610  }
611  return false;
612 }
613 
614 bool
615 pcmk__check_acl(xmlNode *xml, const char *name, enum xml_private_flags mode)
616 {
617  CRM_ASSERT(xml);
618  CRM_ASSERT(xml->doc);
619  CRM_ASSERT(xml->doc->_private);
620 
621 #if ENABLE_ACL
622  if (pcmk__tracking_xml_changes(xml, false) && xml_acl_enabled(xml)) {
623  int offset = 0;
624  xmlNode *parent = xml;
625  char buffer[MAX_XPATH_LEN];
626  xml_private_t *docp = xml->doc->_private;
627 
628  offset = pcmk__element_xpath(NULL, xml, buffer, offset,
629  sizeof(buffer));
630  if (name) {
631  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
632  "[@%s]", name);
633  }
634  CRM_LOG_ASSERT(offset > 0);
635 
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);
640  return false;
641  }
642 
643  /* Walk the tree upwards looking for xml_acl_* flags
644  * - Creating an attribute requires write permissions for the node
645  * - Creating a child requires write permissions for the parent
646  */
647 
648  if (name) {
649  xmlAttr *attr = xmlHasProp(xml, (pcmkXmlStr) name);
650 
651  if (attr && mode == xpf_acl_create) {
652  mode = xpf_acl_write;
653  }
654  }
655 
656  while (parent && parent->_private) {
657  xml_private_t *p = parent->_private;
658  if (test_acl_mode(p->flags, mode)) {
659  return true;
660 
661  } else if (pcmk_is_set(p->flags, xpf_acl_deny)) {
662  crm_trace("%sACL denies user '%s' %s access to %s",
663  (parent != xml) ? "Parent " : "", docp->user,
664  acl_to_text(mode), buffer);
666  return false;
667  }
668  parent = parent->parent;
669  }
670 
671  crm_trace("Default ACL denies user '%s' %s access to %s",
672  docp->user, acl_to_text(mode), buffer);
674  return false;
675  }
676 #endif
677 
678  return true;
679 }
680 
688 bool
689 pcmk_acl_required(const char *user)
690 {
691 #if ENABLE_ACL
692  if (pcmk__str_empty(user)) {
693  crm_trace("ACLs not required because no user set");
694  return false;
695 
696  } else if (!strcmp(user, CRM_DAEMON_USER) || !strcmp(user, "root")) {
697  crm_trace("ACLs not required for privileged user %s", user);
698  return false;
699  }
700  crm_trace("ACLs required for %s", user);
701  return true;
702 #else
703  crm_trace("ACLs not required because not supported by this build");
704  return false;
705 #endif
706 }
707 
708 #if ENABLE_ACL
709 char *
710 pcmk__uid2username(uid_t uid)
711 {
712  struct passwd *pwent = getpwuid(uid);
713 
714  if (pwent == NULL) {
715  crm_perror(LOG_INFO, "Cannot get user details for user ID %d", uid);
716  return NULL;
717  }
718  return strdup(pwent->pw_name);
719 }
720 
739 const char *
740 pcmk__update_acl_user(xmlNode *request, const char *field,
741  const char *peer_user)
742 {
743  static const char *effective_user = NULL;
744  const char *requested_user = NULL;
745  const char *user = NULL;
746 
747  if (effective_user == NULL) {
748  effective_user = pcmk__uid2username(geteuid());
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");
753  }
754  }
755 
756  requested_user = crm_element_value(request, XML_ACL_TAG_USER);
757  if (requested_user == NULL) {
758  /* @COMPAT rolling upgrades <=1.1.11
759  *
760  * field is checked for backward compatibility with older versions that
761  * did not use XML_ACL_TAG_USER.
762  */
763  requested_user = crm_element_value(request, field);
764  }
765 
766  if (!pcmk__is_privileged(effective_user)) {
767  /* We're not running as a privileged user, set or overwrite any existing
768  * value for $XML_ACL_TAG_USER
769  */
770  user = effective_user;
771 
772  } else if (peer_user == NULL && requested_user == NULL) {
773  /* No user known or requested, use 'effective_user' and make sure one is
774  * set for the request
775  */
776  user = effective_user;
777 
778  } else if (peer_user == NULL) {
779  /* No user known, trusting 'requested_user' */
780  user = requested_user;
781 
782  } else if (!pcmk__is_privileged(peer_user)) {
783  /* The peer is not a privileged user, set or overwrite any existing
784  * value for $XML_ACL_TAG_USER
785  */
786  user = peer_user;
787 
788  } else if (requested_user == NULL) {
789  /* Even if we're privileged, make sure there is always a value set */
790  user = peer_user;
791 
792  } else {
793  /* Legal delegation to 'requested_user' */
794  user = requested_user;
795  }
796 
797  // This requires pointer comparison, not string comparison
798  if (user != crm_element_value(request, XML_ACL_TAG_USER)) {
799  crm_xml_add(request, XML_ACL_TAG_USER, user);
800  }
801 
802  if (field != NULL && user != crm_element_value(request, field)) {
803  crm_xml_add(request, field, user);
804  }
805 
806  return requested_user;
807 }
808 #endif
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:215
void xml_acl_disable(xmlNode *xml)
Definition: acl.c:591
A dumping ground.
#define XML_ACL_ATTR_REF
Definition: msg_xml.h:388
#define crm_notice(fmt, args...)
Definition: logging.h:349
#define MAX_XPATH_LEN
Definition: acl.c:27
void pcmk__free_acls(GList *acls)
Definition: acl.c:46
G_GNUC_INTERNAL int pcmk__element_xpath(const char *prefix, xmlNode *xml, char *buffer, int offset, size_t buffer_size)
Definition: xpath.c:268
bool xml_acl_enabled(xmlNode *xml)
Definition: acl.c:604
bool pcmk_acl_required(const char *user)
Check whether ACLs are required for a given user.
Definition: acl.c:689
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: nvpair.c:317
#define XML_ACL_TAG_WRITE
Definition: msg_xml.h:386
void pcmk__apply_creation_acl(xmlNode *xml, bool check_top)
Definition: acl.c:545
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:199
#define LOG_NEVER
Definition: logging.h:46
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:213
G_GNUC_INTERNAL void pcmk__set_xml_doc_flag(xmlNode *xml, enum xml_private_flags flag)
Definition: xml.c:118
xmlNode * copy_xml(xmlNode *src_node)
Definition: xml.c:796
#define XML_ACL_ATTR_REFv1
Definition: msg_xml.h:389
#define XML_ACL_TAG_ROLE
Definition: msg_xml.h:380
#define XML_ACL_ATTR_KIND
Definition: msg_xml.h:384
bool xml_acl_filtered_copy(const char *user, xmlNode *acl_source, xmlNode *xml, xmlNode **result)
Definition: acl.c:419
bool xml_acl_denied(xmlNode *xml)
Definition: acl.c:580
bool pcmk__check_acl(xmlNode *xml, const char *name, enum xml_private_flags mode)
Definition: acl.c:615
#define crm_warn(fmt, args...)
Definition: logging.h:348
void pcmk_free_xml_subtree(xmlNode *xml)
Definition: xml.c:722
#define crm_debug(fmt, args...)
Definition: logging.h:352
#define XML_ATTR_ID
Definition: msg_xml.h:96
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:523
#define XML_ACL_ATTR_XPATH
Definition: msg_xml.h:392
#define XML_ACL_TAG_PERMISSION
Definition: msg_xml.h:381
#define crm_trace(fmt, args...)
Definition: logging.h:353
const char * pcmk__update_acl_user(xmlNode *request, const char *field, const char *peer_user)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:196
#define XML_ACL_TAG_USERv1
Definition: msg_xml.h:378
Wrappers for and extensions to libxml2.
#define display_id(xml)
Definition: acl.c:529
#define XML_ACL_TAG_DENY
Definition: msg_xml.h:387
#define XML_ACL_ATTR_ATTRIBUTE
Definition: msg_xml.h:393
#define CRM_DAEMON_USER
Definition: config.h:32
void pcmk__unpack_acl(xmlNode *source, xmlNode *target, const char *user)
Definition: acl.c:302
void free_xml(xmlNode *child)
Definition: xml.c:790
xml_private_flags
#define XML_CIB_TAG_ACLS
Definition: msg_xml.h:154
#define XML_ACL_ATTR_TAGv1
Definition: msg_xml.h:391
const xmlChar * pcmkXmlStr
Definition: xml.h:51
const char * target
Definition: pcmk_fence.c:29
#define crm_perror(level, fmt, args...)
Send a system error message to both the log and stderr.
Definition: logging.h:298
#define crm_err(fmt, args...)
Definition: logging.h:347
#define CRM_ASSERT(expr)
Definition: results.h:42
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
Definition: xpath.c:138
#define pcmk__plural_alt(i, s1, s2)
#define XML_ACL_TAG_ROLE_REFv1
Definition: msg_xml.h:383
void pcmk__apply_acl(xmlNode *xml)
Definition: acl.c:243
xmlNode * getXpathResult(xmlXPathObjectPtr xpathObj, int index)
Definition: xpath.c:57
char * xml_get_path(xmlNode *xml)
Definition: xpath.c:290
char data[0]
Definition: internal.h:90
#define XML_ACL_TAG_READ
Definition: msg_xml.h:385
#define XML_ACL_TAG_ROLE_REF
Definition: msg_xml.h:382
G_GNUC_INTERNAL bool pcmk__tracking_xml_changes(xmlNode *xml, bool lazy)
Definition: xml.c:52
#define ID(x)
Definition: msg_xml.h:425
#define XML_ACL_TAG_USER
Definition: msg_xml.h:377
#define pcmk__set_xml_flags(xml_priv, flags_to_set)
char * pcmk__uid2username(uid_t uid)
#define pcmk__clear_xml_flags(xml_priv, flags_to_clear)
char * name
Definition: pcmk_fence.c:31
void freeXpathObject(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:38
#define XML_ACL_ATTR_TAG
Definition: msg_xml.h:390
GList * GListPtr
Definition: crm.h:214
struct xml_acl_s xml_acl_t
#define pcmk__config_warn(fmt...)
Definition: internal.h:119
uint64_t flags
Definition: remote.c:149