2
0

acl.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*
  2. * QEMU access control list management
  3. *
  4. * Copyright (C) 2009 Red Hat, Inc
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "qemu-common.h"
  25. #include "acl.h"
  26. #ifdef CONFIG_FNMATCH
  27. #include <fnmatch.h>
  28. #endif
  29. static unsigned int nacls = 0;
  30. static qemu_acl **acls = NULL;
  31. qemu_acl *qemu_acl_find(const char *aclname)
  32. {
  33. int i;
  34. for (i = 0 ; i < nacls ; i++) {
  35. if (strcmp(acls[i]->aclname, aclname) == 0)
  36. return acls[i];
  37. }
  38. return NULL;
  39. }
  40. qemu_acl *qemu_acl_init(const char *aclname)
  41. {
  42. qemu_acl *acl;
  43. acl = qemu_acl_find(aclname);
  44. if (acl)
  45. return acl;
  46. acl = qemu_malloc(sizeof(*acl));
  47. acl->aclname = qemu_strdup(aclname);
  48. /* Deny by default, so there is no window of "open
  49. * access" between QEMU starting, and the user setting
  50. * up ACLs in the monitor */
  51. acl->defaultDeny = 1;
  52. acl->nentries = 0;
  53. QTAILQ_INIT(&acl->entries);
  54. acls = qemu_realloc(acls, sizeof(*acls) * (nacls +1));
  55. acls[nacls] = acl;
  56. nacls++;
  57. return acl;
  58. }
  59. int qemu_acl_party_is_allowed(qemu_acl *acl,
  60. const char *party)
  61. {
  62. qemu_acl_entry *entry;
  63. QTAILQ_FOREACH(entry, &acl->entries, next) {
  64. #ifdef CONFIG_FNMATCH
  65. if (fnmatch(entry->match, party, 0) == 0)
  66. return entry->deny ? 0 : 1;
  67. #else
  68. /* No fnmatch, so fallback to exact string matching
  69. * instead of allowing wildcards */
  70. if (strcmp(entry->match, party) == 0)
  71. return entry->deny ? 0 : 1;
  72. #endif
  73. }
  74. return acl->defaultDeny ? 0 : 1;
  75. }
  76. void qemu_acl_reset(qemu_acl *acl)
  77. {
  78. qemu_acl_entry *entry;
  79. /* Put back to deny by default, so there is no window
  80. * of "open access" while the user re-initializes the
  81. * access control list */
  82. acl->defaultDeny = 1;
  83. QTAILQ_FOREACH(entry, &acl->entries, next) {
  84. QTAILQ_REMOVE(&acl->entries, entry, next);
  85. free(entry->match);
  86. free(entry);
  87. }
  88. acl->nentries = 0;
  89. }
  90. int qemu_acl_append(qemu_acl *acl,
  91. int deny,
  92. const char *match)
  93. {
  94. qemu_acl_entry *entry;
  95. entry = qemu_malloc(sizeof(*entry));
  96. entry->match = qemu_strdup(match);
  97. entry->deny = deny;
  98. QTAILQ_INSERT_TAIL(&acl->entries, entry, next);
  99. acl->nentries++;
  100. return acl->nentries;
  101. }
  102. int qemu_acl_insert(qemu_acl *acl,
  103. int deny,
  104. const char *match,
  105. int index)
  106. {
  107. qemu_acl_entry *entry;
  108. qemu_acl_entry *tmp;
  109. int i = 0;
  110. if (index <= 0)
  111. return -1;
  112. if (index >= acl->nentries)
  113. return qemu_acl_append(acl, deny, match);
  114. entry = qemu_malloc(sizeof(*entry));
  115. entry->match = qemu_strdup(match);
  116. entry->deny = deny;
  117. QTAILQ_FOREACH(tmp, &acl->entries, next) {
  118. i++;
  119. if (i == index) {
  120. QTAILQ_INSERT_BEFORE(tmp, entry, next);
  121. acl->nentries++;
  122. break;
  123. }
  124. }
  125. return i;
  126. }
  127. int qemu_acl_remove(qemu_acl *acl,
  128. const char *match)
  129. {
  130. qemu_acl_entry *entry;
  131. int i = 0;
  132. QTAILQ_FOREACH(entry, &acl->entries, next) {
  133. i++;
  134. if (strcmp(entry->match, match) == 0) {
  135. QTAILQ_REMOVE(&acl->entries, entry, next);
  136. return i;
  137. }
  138. }
  139. return -1;
  140. }
  141. /*
  142. * Local variables:
  143. * c-indent-level: 4
  144. * c-basic-offset: 4
  145. * tab-width: 8
  146. * End:
  147. */