1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
/*
* $Id: cap_flag.c,v 1.1.1.1.4.1 2000/07/11 05:29:14 agmorgan Exp $
*
* Copyright (c) 1997-8 Andrew G. Morgan <morgan@linux.kernel.org>
*
* This file deals with flipping of capabilities on internal
* capability sets as specified by POSIX.1e (formerlly, POSIX 6).
*/
#include "libcap.h"
/*
* Return the state of a specified capability flag. The state is
* returned as the contents of *raised. The capability is from one of
* the sets stored in cap_d as specified by set and value
*/
int cap_get_flag(cap_t cap_d, cap_value_t value, cap_flag_t set,
cap_flag_value_t *raised)
{
/*
* Do we have a set and a place to store its value?
* Is it a known capability?
*/
if (raised && good_cap_t(cap_d) && value >= 0 && value < __CAP_BITS
&& set >= 0 && set < NUMBER_OF_CAP_SETS) {
__cap_s *cap_p = (__cap_s *) (set*CAP_SET_SIZE
+ (__u8 *) &cap_d->set);
*raised = isset_cap(cap_p,value) ? CAP_SET:CAP_CLEAR;
return 0;
} else {
_cap_debug("invalid arguments");
errno = EINVAL;
return -1;
}
}
/*
* raise/lower a selection of capabilities
*/
int cap_set_flag(cap_t cap_d, cap_flag_t set,
int no_values, cap_value_t *array_values,
cap_flag_value_t raise)
{
/*
* Do we have a set and a place to store its value?
* Is it a known capability?
*/
if (good_cap_t(cap_d) && no_values > 0 && no_values <= __CAP_BITS
&& (set >= 0) && (set < NUMBER_OF_CAP_SETS)
&& (raise == CAP_SET || raise == CAP_CLEAR) ) {
int i;
for (i=0; i<no_values; ++i) {
if (array_values[i] < 0 || array_values[i] >= __CAP_BITS) {
_cap_debug("weird capability (%d) - skipped", array_values[i]);
} else {
int value = array_values[i];
__cap_s *cap_p = (__cap_s *) (set*CAP_SET_SIZE
+ (__u8 *) &cap_d->set);
if (raise == CAP_SET) {
cap_p->raise_cap(value);
} else {
cap_p->lower_cap(value);
}
}
}
return 0;
} else {
_cap_debug("invalid arguments");
errno = EINVAL;
return -1;
}
}
/*
* Reset the capability to be empty (nothing raised)
*/
int cap_clear(cap_t cap_d)
{
if (good_cap_t(cap_d)) {
memset(&(cap_d->set), 0, sizeof(cap_d->set));
return 0;
} else {
_cap_debug("invalid pointer");
errno = EINVAL;
return -1;
}
}
|