cap_flag.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * Copyright (c) 1997-8,2008 Andrew G. Morgan <morgan@kernel.org>
  3. *
  4. * This file deals with flipping of capabilities on internal
  5. * capability sets as specified by POSIX.1e (formerlly, POSIX 6).
  6. */
  7. #include "libcap.h"
  8. /*
  9. * Return the state of a specified capability flag. The state is
  10. * returned as the contents of *raised. The capability is from one of
  11. * the sets stored in cap_d as specified by set and value
  12. */
  13. int cap_get_flag(cap_t cap_d, cap_value_t value, cap_flag_t set,
  14. cap_flag_value_t *raised)
  15. {
  16. /*
  17. * Do we have a set and a place to store its value?
  18. * Is it a known capability?
  19. */
  20. if (raised && good_cap_t(cap_d) && value >= 0 && value < __CAP_BITS
  21. && set >= 0 && set < NUMBER_OF_CAP_SETS) {
  22. *raised = isset_cap(cap_d,value,set) ? CAP_SET:CAP_CLEAR;
  23. return 0;
  24. } else {
  25. _cap_debug("invalid arguments");
  26. errno = EINVAL;
  27. return -1;
  28. }
  29. }
  30. /*
  31. * raise/lower a selection of capabilities
  32. */
  33. int cap_set_flag(cap_t cap_d, cap_flag_t set,
  34. int no_values, const cap_value_t *array_values,
  35. cap_flag_value_t raise)
  36. {
  37. /*
  38. * Do we have a set and a place to store its value?
  39. * Is it a known capability?
  40. */
  41. if (good_cap_t(cap_d) && no_values > 0 && no_values <= __CAP_BITS
  42. && (set >= 0) && (set < NUMBER_OF_CAP_SETS)
  43. && (raise == CAP_SET || raise == CAP_CLEAR) ) {
  44. int i;
  45. for (i=0; i<no_values; ++i) {
  46. if (array_values[i] < 0 || array_values[i] >= __CAP_BITS) {
  47. _cap_debug("weird capability (%d) - skipped", array_values[i]);
  48. } else {
  49. int value = array_values[i];
  50. if (raise == CAP_SET) {
  51. cap_d->raise_cap(value,set);
  52. } else {
  53. cap_d->lower_cap(value,set);
  54. }
  55. }
  56. }
  57. return 0;
  58. } else {
  59. _cap_debug("invalid arguments");
  60. errno = EINVAL;
  61. return -1;
  62. }
  63. }
  64. /*
  65. * Reset the capability to be empty (nothing raised)
  66. */
  67. int cap_clear(cap_t cap_d)
  68. {
  69. if (good_cap_t(cap_d)) {
  70. memset(&(cap_d->u), 0, sizeof(cap_d->u));
  71. return 0;
  72. } else {
  73. _cap_debug("invalid pointer");
  74. errno = EINVAL;
  75. return -1;
  76. }
  77. }
  78. /*
  79. * Reset the all of the capability bits for one of the flag sets
  80. */
  81. int cap_clear_flag(cap_t cap_d, cap_flag_t flag)
  82. {
  83. switch (flag) {
  84. case CAP_EFFECTIVE:
  85. case CAP_PERMITTED:
  86. case CAP_INHERITABLE:
  87. if (good_cap_t(cap_d)) {
  88. unsigned i;
  89. for (i=0; i<_LIBCAP_CAPABILITY_U32S; i++) {
  90. cap_d->u[i].flat[flag] = 0;
  91. }
  92. return 0;
  93. }
  94. /*
  95. * fall through
  96. */
  97. default:
  98. _cap_debug("invalid pointer");
  99. errno = EINVAL;
  100. return -1;
  101. }
  102. }
  103. /*
  104. * Compare two capability sets
  105. */
  106. int cap_compare(cap_t a, cap_t b)
  107. {
  108. unsigned i;
  109. int result;
  110. if (!(good_cap_t(a) && good_cap_t(b))) {
  111. _cap_debug("invalid arguments");
  112. errno = EINVAL;
  113. return -1;
  114. }
  115. for (i=0, result=0; i<_LIBCAP_CAPABILITY_U32S; i++) {
  116. result |=
  117. ((a->u[i].flat[CAP_EFFECTIVE] != b->u[i].flat[CAP_EFFECTIVE])
  118. ? LIBCAP_EFF : 0)
  119. | ((a->u[i].flat[CAP_INHERITABLE] != b->u[i].flat[CAP_INHERITABLE])
  120. ? LIBCAP_INH : 0)
  121. | ((a->u[i].flat[CAP_PERMITTED] != b->u[i].flat[CAP_PERMITTED])
  122. ? LIBCAP_PER : 0);
  123. }
  124. return result;
  125. }