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