pacemaker  2.0.2-debe490
Scalable High-Availability cluster resource manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
acl.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This source code is licensed under the GNU Lesser General Public License
5  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
6  */
7 
8 #include <crm_internal.h>
9 
10 #include <stdio.h>
11 #include <sys/types.h>
12 #include <pwd.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdarg.h>
16 
17 #include <libxml/tree.h>
18 
19 #include <crm/crm.h>
20 #include <crm/msg_xml.h>
21 #include <crm/common/xml.h>
22 #include "crmcommon_private.h"
23 
24 #define MAX_XPATH_LEN 4096
25 
26 typedef struct xml_acl_s {
27  enum xml_private_flags mode;
28  char *xpath;
29 } xml_acl_t;
30 
31 static void
32 __xml_acl_free(void *data)
33 {
34  if (data) {
35  xml_acl_t *acl = data;
36 
37  free(acl->xpath);
38  free(acl);
39  }
40 }
41 
42 void
43 pcmk__free_acls(GList *acls)
44 {
45  g_list_free_full(acls, __xml_acl_free);
46 }
47 
48 static GList *
49 __xml_acl_create(xmlNode *xml, GList *acls, enum xml_private_flags mode)
50 {
51  xml_acl_t *acl = NULL;
52 
53  const char *tag = crm_element_value(xml, XML_ACL_ATTR_TAG);
54  const char *ref = crm_element_value(xml, XML_ACL_ATTR_REF);
55  const char *xpath = crm_element_value(xml, XML_ACL_ATTR_XPATH);
56 
57  if (tag == NULL) {
58  // @COMPAT rolling upgrades <=1.1.11
60  }
61  if (ref == NULL) {
62  // @COMPAT rolling upgrades <=1.1.11
64  }
65 
66  if ((tag == NULL) && (ref == NULL) && (xpath == NULL)) {
67  crm_trace("No criteria %p", xml);
68  return NULL;
69  }
70 
71  acl = calloc(1, sizeof (xml_acl_t));
72  if (acl) {
73  const char *attr = crm_element_value(xml, XML_ACL_ATTR_ATTRIBUTE);
74 
75  acl->mode = mode;
76  if (xpath) {
77  acl->xpath = strdup(xpath);
78  crm_trace("Using xpath: %s", acl->xpath);
79 
80  } else {
81  int offset = 0;
82  char buffer[MAX_XPATH_LEN];
83 
84  if (tag) {
85  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
86  "//%s", tag);
87  } else {
88  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
89  "//*");
90  }
91 
92  if (ref || attr) {
93  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
94  "[");
95  }
96 
97  if (ref) {
98  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
99  "@id='%s'", ref);
100  }
101 
102  if (ref && attr) {
103  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
104  " and ");
105  }
106 
107  if (attr) {
108  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
109  "@%s", attr);
110  }
111 
112  if (ref || attr) {
113  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
114  "]");
115  }
116 
117  CRM_LOG_ASSERT(offset > 0);
118  acl->xpath = strdup(buffer);
119  crm_trace("Built xpath: %s", acl->xpath);
120  }
121 
122  acls = g_list_append(acls, acl);
123  }
124  return acls;
125 }
126 
127 static GList *
128 __xml_acl_parse_entry(xmlNode *acl_top, xmlNode *acl_entry, GList *acls)
129 {
130  xmlNode *child = NULL;
131 
132  for (child = __xml_first_child(acl_entry); child;
133  child = __xml_next(child)) {
134  const char *tag = crm_element_name(child);
135  const char *kind = crm_element_value(child, XML_ACL_ATTR_KIND);
136 
137  if (strcmp(XML_ACL_TAG_PERMISSION, tag) == 0){
138  tag = kind;
139  }
140 
141  crm_trace("Processing %s %p", tag, child);
142  if (tag == NULL) {
143  CRM_ASSERT(tag != NULL);
144 
145  } else if (strcmp(XML_ACL_TAG_ROLE_REF, tag) == 0
146  || strcmp(XML_ACL_TAG_ROLE_REFv1, tag) == 0) {
147  const char *ref_role = crm_element_value(child, XML_ATTR_ID);
148 
149  if (ref_role) {
150  xmlNode *role = NULL;
151 
152  for (role = __xml_first_child(acl_top); role;
153  role = __xml_next(role)) {
154  if (!strcmp(XML_ACL_TAG_ROLE, (const char *) role->name)) {
155  const char *role_id = crm_element_value(role,
156  XML_ATTR_ID);
157 
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);
161  break;
162  }
163  }
164  }
165  }
166 
167  } else if (strcmp(XML_ACL_TAG_READ, tag) == 0) {
168  acls = __xml_acl_create(child, acls, xpf_acl_read);
169 
170  } else if (strcmp(XML_ACL_TAG_WRITE, tag) == 0) {
171  acls = __xml_acl_create(child, acls, xpf_acl_write);
172 
173  } else if (strcmp(XML_ACL_TAG_DENY, tag) == 0) {
174  acls = __xml_acl_create(child, acls, xpf_acl_deny);
175 
176  } else {
177  crm_warn("Unknown ACL entry: %s/%s", tag, kind);
178  }
179  }
180 
181  return acls;
182 }
183 
184 /*
185  <acls>
186  <acl_target id="l33t-haxor"><role id="auto-l33t-haxor"/></acl_target>
187  <acl_role id="auto-l33t-haxor">
188  <acl_permission id="crook-nothing" kind="deny" xpath="/cib"/>
189  </acl_role>
190  <acl_target id="niceguy">
191  <role id="observer"/>
192  </acl_target>
193  <acl_role id="observer">
194  <acl_permission id="observer-read-1" kind="read" xpath="/cib"/>
195  <acl_permission id="observer-write-1" kind="write" xpath="//nvpair[@name='stonith-enabled']"/>
196  <acl_permission id="observer-write-2" kind="write" xpath="//nvpair[@name='target-role']"/>
197  </acl_role>
198  <acl_target id="badidea"><role id="auto-badidea"/></acl_target>
199  <acl_role id="auto-badidea">
200  <acl_permission id="badidea-resources" kind="read" xpath="//meta_attributes"/>
201  <acl_permission id="badidea-resources-2" kind="deny" reference="dummy-meta_attributes"/>
202  </acl_role>
203  </acls>
204 */
205 
206 #ifdef SUSE_ACL_COMPAT
207 static const char *
208 __xml_acl_to_text(enum xml_private_flags flags)
209 {
210  if (is_set(flags, xpf_acl_deny)) {
211  return "deny";
212 
213  } else if (is_set(flags, xpf_acl_write)) {
214  return "read/write";
215 
216  } else if (is_set(flags, xpf_acl_read)) {
217  return "read";
218  }
219  return "none";
220 }
221 #endif
222 
223 void
224 pcmk__apply_acl(xmlNode *xml)
225 {
226  GListPtr aIter = NULL;
227  xml_private_t *p = xml->doc->_private;
228  xmlXPathObjectPtr xpathObj = NULL;
229 
230  if (xml_acl_enabled(xml) == FALSE) {
231  crm_trace("Not applying ACLs for %s", p->user);
232  return;
233  }
234 
235  for (aIter = p->acls; aIter != NULL; aIter = aIter->next) {
236  int max = 0, lpc = 0;
237  xml_acl_t *acl = aIter->data;
238 
239  xpathObj = xpath_search(xml, acl->xpath);
240  max = numXpathResults(xpathObj);
241 
242  for (lpc = 0; lpc < max; lpc++) {
243  xmlNode *match = getXpathResult(xpathObj, lpc);
244  char *path = xml_get_path(match);
245 
246  p = match->_private;
247  crm_trace("Applying %x to %s for %s", acl->mode, path, acl->xpath);
248 
249 #ifdef SUSE_ACL_COMPAT
250  if (is_not_set(p->flags, acl->mode)
251  && (is_set(p->flags, xpf_acl_read)
252  || is_set(p->flags, xpf_acl_write)
253  || is_set(p->flags, xpf_acl_deny))) {
254  crm_config_warn("Configuration element %s is matched by "
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));
259  free(path);
260  continue;
261  }
262 #endif
263  p->flags |= acl->mode;
264  free(path);
265  }
266  crm_trace("Now enforcing ACL: %s (%d matches)", acl->xpath, max);
267  freeXpathObject(xpathObj);
268  }
269 
270  p = xml->_private;
271  if (is_not_set(p->flags, xpf_acl_read)
272  && is_not_set(p->flags, xpf_acl_write)) {
273 
274  p->flags |= xpf_acl_deny;
275  p = xml->doc->_private;
276  crm_info("Enforcing default ACL for %s to %s",
277  p->user, crm_element_name(xml));
278  }
279 
280 }
281 
282 void
283 pcmk__unpack_acl(xmlNode *source, xmlNode *target, const char *user)
284 {
285 #if ENABLE_ACL
286  xml_private_t *p = NULL;
287 
288  if ((target == NULL) || (target->doc == NULL)
289  || (target->doc->_private == NULL)) {
290  return;
291  }
292 
293  p = target->doc->_private;
294  if (pcmk_acl_required(user) == FALSE) {
295  crm_trace("no acls needed for '%s'", user);
296 
297  } else if (p->acls == NULL) {
298  xmlNode *acls = get_xpath_object("//" XML_CIB_TAG_ACLS,
299  source, LOG_TRACE);
300 
301  free(p->user);
302  p->user = strdup(user);
303 
304  if (acls) {
305  xmlNode *child = NULL;
306 
307  for (child = __xml_first_child(acls); child;
308  child = __xml_next(child)) {
309  const char *tag = crm_element_name(child);
310 
311  if (!strcmp(tag, XML_ACL_TAG_USER)
312  || !strcmp(tag, XML_ACL_TAG_USERv1)) {
313  const char *id = crm_element_value(child, XML_ATTR_ID);
314 
315  if (id && strcmp(id, user) == 0) {
316  crm_debug("Unpacking ACLs for %s", id);
317  p->acls = __xml_acl_parse_entry(acls, child, p->acls);
318  }
319  }
320  }
321  }
322  }
323 #endif
324 }
325 
326 static inline bool
327 __xml_acl_mode_test(enum xml_private_flags allowed,
328  enum xml_private_flags requested)
329 {
330  if (is_set(allowed, xpf_acl_deny)) {
331  return FALSE;
332 
333  } else if (is_set(allowed, requested)) {
334  return TRUE;
335 
336  } else if (is_set(requested, xpf_acl_read)
337  && is_set(allowed, xpf_acl_write)) {
338  return TRUE;
339 
340  } else if (is_set(requested, xpf_acl_create)
341  && is_set(allowed, xpf_acl_write)) {
342  return TRUE;
343 
344  } else if (is_set(requested, xpf_acl_create)
345  && is_set(allowed, xpf_created)) {
346  return TRUE;
347  }
348  return FALSE;
349 }
350 
351 /* rc = TRUE if orig_cib has been filtered
352  * That means '*result' rather than 'xml' should be exploited afterwards
353  */
354 static bool
355 __xml_purge_attributes(xmlNode *xml)
356 {
357  xmlNode *child = NULL;
358  xmlAttr *xIter = NULL;
359  bool readable_children = FALSE;
360  xml_private_t *p = xml->_private;
361 
362  if (__xml_acl_mode_test(p->flags, xpf_acl_read)) {
363  crm_trace("%s[@id=%s] is readable", crm_element_name(xml), ID(xml));
364  return TRUE;
365  }
366 
367  xIter = xml->properties;
368  while (xIter != NULL) {
369  xmlAttr *tmp = xIter;
370  const char *prop_name = (const char *)xIter->name;
371 
372  xIter = xIter->next;
373  if (strcmp(prop_name, XML_ATTR_ID) == 0) {
374  continue;
375  }
376 
377  xmlUnsetProp(xml, tmp->name);
378  }
379 
380  child = __xml_first_child(xml);
381  while ( child != NULL ) {
382  xmlNode *tmp = child;
383 
384  child = __xml_next(child);
385  readable_children |= __xml_purge_attributes(tmp);
386  }
387 
388  if (readable_children == FALSE) {
389  free_xml(xml); /* Nothing readable under here, purge completely */
390  }
391  return readable_children;
392 }
393 
394 bool
395 xml_acl_filtered_copy(const char *user, xmlNode *acl_source, xmlNode *xml,
396  xmlNode **result)
397 {
398  GListPtr aIter = NULL;
399  xmlNode *target = NULL;
400  xml_private_t *p = NULL;
401  xml_private_t *doc = NULL;
402 
403  *result = NULL;
404  if (xml == NULL || pcmk_acl_required(user) == FALSE) {
405  crm_trace("no acls needed for '%s'", user);
406  return FALSE;
407  }
408 
409  crm_trace("filtering copy of %p for '%s'", xml, user);
410  target = copy_xml(xml);
411  if (target == NULL) {
412  return TRUE;
413  }
414 
415  pcmk__unpack_acl(acl_source, target, user);
417  pcmk__apply_acl(target);
418 
419  doc = target->doc->_private;
420  for(aIter = doc->acls; aIter != NULL && target; aIter = aIter->next) {
421  int max = 0;
422  xml_acl_t *acl = aIter->data;
423 
424  if (acl->mode != xpf_acl_deny) {
425  /* Nothing to do */
426 
427  } else if (acl->xpath) {
428  int lpc = 0;
429  xmlXPathObjectPtr xpathObj = xpath_search(target, acl->xpath);
430 
431  max = numXpathResults(xpathObj);
432  for(lpc = 0; lpc < max; lpc++) {
433  xmlNode *match = getXpathResult(xpathObj, lpc);
434 
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);
438  freeXpathObject(xpathObj);
439  return TRUE;
440  }
441  }
442  crm_trace("Enforced ACL %s (%d matches)", acl->xpath, max);
443  freeXpathObject(xpathObj);
444  }
445  }
446 
447  p = target->_private;
448  if (is_set(p->flags, xpf_acl_deny)
449  && (__xml_purge_attributes(target) == FALSE)) {
450  crm_trace("No access to the entire document for %s", user);
451  return TRUE;
452  }
453 
454  if (doc->acls) {
455  g_list_free_full(doc->acls, __xml_acl_free);
456  doc->acls = NULL;
457 
458  } else {
459  crm_trace("Ordinary user '%s' cannot access the CIB without any defined ACLs",
460  doc->user);
461  free_xml(target);
462  target = NULL;
463  }
464 
465  if (target) {
466  *result = target;
467  }
468 
469  return TRUE;
470 }
471 
472 void
474 {
475  xmlNode *cIter = __xml_first_child(xml);
476  xml_private_t *p = xml->_private;
477 
478  if (is_set(p->flags, xpf_created)) {
479  xmlAttr *xIter = NULL;
480  char *path = xml_get_path(xml);
481 
482  /* Always allow new scaffolding (e.g. node with no attributes or only an
483  * 'id'), except in the ACLs section
484  */
485 
486  for (xIter = xml->properties; xIter != NULL; xIter = xIter->next) {
487  const char *prop_name = (const char *)xIter->name;
488 
489  if (!strcmp(prop_name, XML_ATTR_ID)
490  && !strstr(path, "/"XML_CIB_TAG_ACLS"/")) {
491  /* Delay the acl check */
492  continue;
493 
494  } else if (pcmk__check_acl(xml, NULL, xpf_acl_write)) {
495  crm_trace("Creation of %s=%s is allowed",
496  crm_element_name(xml), ID(xml));
497  break;
498 
499  } else {
500  crm_trace("Cannot add new node %s at %s",
501  crm_element_name(xml), path);
502 
503  if (xml != xmlDocGetRootElement(xml->doc)) {
504  xmlUnlinkNode(xml);
505  xmlFreeNode(xml);
506  }
507  free(path);
508  return;
509  }
510  }
511  free(path);
512  }
513 
514  while (cIter != NULL) {
515  xmlNode *child = cIter;
516  cIter = __xml_next(cIter); /* In case it is free'd */
517  pcmk__post_process_acl(child);
518  }
519 }
520 
521 bool
522 xml_acl_denied(xmlNode *xml)
523 {
524  if (xml && xml->doc && xml->doc->_private){
525  xml_private_t *p = xml->doc->_private;
526 
527  return is_set(p->flags, xpf_acl_denied);
528  }
529  return FALSE;
530 }
531 
532 void
533 xml_acl_disable(xmlNode *xml)
534 {
535  if (xml_acl_enabled(xml)) {
536  xml_private_t *p = xml->doc->_private;
537 
538  /* Catch anything that was created but shouldn't have been */
539  pcmk__apply_acl(xml);
542  }
543 }
544 
545 bool
546 xml_acl_enabled(xmlNode *xml)
547 {
548  if (xml && xml->doc && xml->doc->_private){
549  xml_private_t *p = xml->doc->_private;
550 
551  return is_set(p->flags, xpf_acl_enabled);
552  }
553  return FALSE;
554 }
555 
556 bool
557 pcmk__check_acl(xmlNode *xml, const char *name, enum xml_private_flags mode)
558 {
559  CRM_ASSERT(xml);
560  CRM_ASSERT(xml->doc);
561  CRM_ASSERT(xml->doc->_private);
562 
563 #if ENABLE_ACL
564  if (pcmk__tracking_xml_changes(xml, FALSE) && xml_acl_enabled(xml)) {
565  int offset = 0;
566  xmlNode *parent = xml;
567  char buffer[MAX_XPATH_LEN];
568  xml_private_t *docp = xml->doc->_private;
569 
570  if (docp->acls == NULL) {
571  crm_trace("Ordinary user %s cannot access the CIB without any defined ACLs",
572  docp->user);
574  return FALSE;
575  }
576 
577  offset = pcmk__element_xpath(NULL, xml, buffer, offset,
578  sizeof(buffer));
579  if (name) {
580  offset += snprintf(buffer + offset, MAX_XPATH_LEN - offset,
581  "[@%s]", name);
582  }
583  CRM_LOG_ASSERT(offset > 0);
584 
585  /* Walk the tree upwards looking for xml_acl_* flags
586  * - Creating an attribute requires write permissions for the node
587  * - Creating a child requires write permissions for the parent
588  */
589 
590  if (name) {
591  xmlAttr *attr = xmlHasProp(xml, (pcmkXmlStr) name);
592 
593  if (attr && mode == xpf_acl_create) {
594  mode = xpf_acl_write;
595  }
596  }
597 
598  while (parent && parent->_private) {
599  xml_private_t *p = parent->_private;
600  if (__xml_acl_mode_test(p->flags, mode)) {
601  return TRUE;
602 
603  } else if (is_set(p->flags, xpf_acl_deny)) {
604  crm_trace("%x access denied to %s: parent", mode, buffer);
606  return FALSE;
607  }
608  parent = parent->parent;
609  }
610 
611  crm_trace("%x access denied to %s: default", mode, buffer);
613  return FALSE;
614  }
615 #endif
616 
617  return TRUE;
618 }
619 
620 bool
621 pcmk_acl_required(const char *user)
622 {
623 #if ENABLE_ACL
624  if (user == NULL || strlen(user) == 0) {
625  crm_trace("no user set");
626  return FALSE;
627 
628  } else if (strcmp(user, CRM_DAEMON_USER) == 0) {
629  return FALSE;
630 
631  } else if (strcmp(user, "root") == 0) {
632  return FALSE;
633  }
634  crm_trace("ACLs required for %s", user);
635  return TRUE;
636 #else
637  crm_trace("ACLs not supported");
638  return FALSE;
639 #endif
640 }
641 
642 #if ENABLE_ACL
643 char *
644 uid2username(uid_t uid)
645 {
646  struct passwd *pwent = getpwuid(uid);
647 
648  if (pwent == NULL) {
649  crm_perror(LOG_INFO, "Cannot get user details for user ID %d", uid);
650  return NULL;
651  }
652  return strdup(pwent->pw_name);
653 }
654 
655 const char *
656 crm_acl_get_set_user(xmlNode *request, const char *field, const char *peer_user)
657 {
658  static const char *effective_user = NULL;
659  const char *requested_user = NULL;
660  const char *user = NULL;
661 
662  if (effective_user == NULL) {
663  effective_user = uid2username(geteuid());
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");
668  }
669  }
670 
671  requested_user = crm_element_value(request, XML_ACL_TAG_USER);
672  if (requested_user == NULL) {
673  /* @COMPAT rolling upgrades <=1.1.11
674  *
675  * field is checked for backward compatibility with older versions that
676  * did not use XML_ACL_TAG_USER.
677  */
678  requested_user = crm_element_value(request, field);
679  }
680 
681  if (is_privileged(effective_user) == FALSE) {
682  /* We're not running as a privileged user, set or overwrite any existing
683  * value for $XML_ACL_TAG_USER
684  */
685  user = effective_user;
686 
687  } else if (peer_user == NULL && requested_user == NULL) {
688  /* No user known or requested, use 'effective_user' and make sure one is
689  * set for the request
690  */
691  user = effective_user;
692 
693  } else if (peer_user == NULL) {
694  /* No user known, trusting 'requested_user' */
695  user = requested_user;
696 
697  } else if (is_privileged(peer_user) == FALSE) {
698  /* The peer is not a privileged user, set or overwrite any existing
699  * value for $XML_ACL_TAG_USER
700  */
701  user = peer_user;
702 
703  } else if (requested_user == NULL) {
704  /* Even if we're privileged, make sure there is always a value set */
705  user = peer_user;
706 
707  } else {
708  /* Legal delegation to 'requested_user' */
709  user = requested_user;
710  }
711 
712  // This requires pointer comparison, not string comparison
713  if (user != crm_element_value(request, XML_ACL_TAG_USER)) {
714  crm_xml_add(request, XML_ACL_TAG_USER, user);
715  }
716 
717  if (field != NULL && user != crm_element_value(request, field)) {
718  crm_xml_add(request, field, user);
719  }
720 
721  return requested_user;
722 }
723 #endif
#define LOG_TRACE
Definition: logging.h:26
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:156
A dumping ground.
#define XML_ACL_ATTR_REF
Definition: msg_xml.h:377
#define MAX_XPATH_LEN
Definition: acl.c:24
void pcmk__free_acls(GList *acls)
Definition: acl.c:43
G_GNUC_INTERNAL int pcmk__element_xpath(const char *prefix, xmlNode *xml, char *buffer, int offset, size_t buffer_size)
Definition: xml.c:1915
bool xml_acl_denied(xmlNode *xml)
Definition: acl.c:522
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:275
#define XML_ACL_TAG_WRITE
Definition: msg_xml.h:375
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:142
#define clear_bit(word, bit)
Definition: crm_internal.h:168
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:220
void pcmk__post_process_acl(xmlNode *xml)
Definition: acl.c:473
bool xml_acl_enabled(xmlNode *xml)
Definition: acl.c:546
xmlNode * copy_xml(xmlNode *src_node)
Definition: xml.c:2020
#define XML_ACL_ATTR_REFv1
Definition: msg_xml.h:378
#define XML_ACL_TAG_ROLE
Definition: msg_xml.h:369
#define XML_ACL_ATTR_KIND
Definition: msg_xml.h:373
bool pcmk__check_acl(xmlNode *xml, const char *name, enum xml_private_flags mode)
Definition: acl.c:557
#define crm_warn(fmt, args...)
Definition: logging.h:241
bool pcmk_acl_required(const char *user)
Definition: acl.c:621
#define crm_debug(fmt, args...)
Definition: logging.h:245
#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:423
#define XML_ACL_ATTR_XPATH
Definition: msg_xml.h:381
#define XML_ACL_TAG_PERMISSION
Definition: msg_xml.h:370
#define crm_trace(fmt, args...)
Definition: logging.h:246
#define XML_ACL_TAG_USERv1
Definition: msg_xml.h:367
Wrappers for and extensions to libxml2.
#define XML_ACL_TAG_DENY
Definition: msg_xml.h:376
G_GNUC_INTERNAL void pcmk__set_xml_flag(xmlNode *xml, enum xml_private_flags flag)
Definition: xml.c:130
#define XML_ACL_ATTR_ATTRIBUTE
Definition: msg_xml.h:382
#define CRM_DAEMON_USER
Definition: config.h:32
void xml_acl_disable(xmlNode *xml)
Definition: acl.c:533
void pcmk__unpack_acl(xmlNode *source, xmlNode *target, const char *user)
Definition: acl.c:283
void free_xml(xmlNode *child)
Definition: xml.c:2014
xml_private_flags
#define XML_CIB_TAG_ACLS
Definition: msg_xml.h:147
#define XML_ACL_ATTR_TAGv1
Definition: msg_xml.h:380
const xmlChar * pcmkXmlStr
Definition: xml.h:51
#define crm_config_warn(fmt...)
Definition: crm_internal.h:180
#define crm_perror(level, fmt, args...)
Log a system error message.
Definition: logging.h:218
#define crm_err(fmt, args...)
Definition: logging.h:240
#define CRM_ASSERT(expr)
Definition: results.h:42
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
Definition: xpath.c:145
#define XML_ACL_TAG_ROLE_REFv1
Definition: msg_xml.h:372
void pcmk__apply_acl(xmlNode *xml)
Definition: acl.c:224
xmlNode * getXpathResult(xmlXPathObjectPtr xpathObj, int index)
Definition: xpath.c:64
char * xml_get_path(xmlNode *xml)
Definition: xml.c:1937
bool xml_acl_filtered_copy(const char *user, xmlNode *acl_source, xmlNode *xml, xmlNode **result)
Definition: acl.c:395
char data[0]
Definition: internal.h:92
#define XML_ACL_TAG_READ
Definition: msg_xml.h:374
const char * crm_acl_get_set_user(xmlNode *request, const char *field, const char *peer_user)
#define XML_ACL_TAG_ROLE_REF
Definition: msg_xml.h:371
G_GNUC_INTERNAL bool pcmk__tracking_xml_changes(xmlNode *xml, bool lazy)
Definition: xml.c:64
#define ID(x)
Definition: msg_xml.h:414
#define XML_ACL_TAG_USER
Definition: msg_xml.h:366
void freeXpathObject(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:45
#define XML_ACL_ATTR_TAG
Definition: msg_xml.h:379
GList * GListPtr
Definition: crm.h:192
#define crm_info(fmt, args...)
Definition: logging.h:243
char * uid2username(uid_t uid)
struct xml_acl_s xml_acl_t
uint64_t flags
Definition: remote.c:148