int cap_set_file(const char *filename, cap_t cap_d) { if (!good_cap_t(cap_d)) { errno = EINVAL; return -1; } _cap_debug("setting filename capabilities"); return _setfilecap(filename, sizeof(struct __cap_s), &cap_d->set[CAP_INHERITABLE], &cap_d->set[CAP_PERMITTED], &cap_d->set[CAP_EFFECTIVE] ); }
int cap_set_proc(cap_t cap_d) { int retval; if (!good_cap_t(cap_d)) { errno = EINVAL; return -1; } _cap_debug("setting process capabilities"); retval = capset(&cap_d->head, &cap_d->set); cap_d->head.version = _LINUX_CAPABILITY_VERSION; return retval; }
int capsetp(pid_t pid, cap_t cap_d) { int error; if (!good_cap_t(cap_d)) { errno = EINVAL; return -1; } _cap_debug("setting process capabilities for proc %d", pid); cap_d->head.pid = pid; error = capset(&cap_d->head, &cap_d->set); cap_d->head.version = _LINUX_CAPABILITY_VERSION; cap_d->head.pid = 0; return error; }
cap_t cap_dup(cap_t cap_d) { cap_t result; if (!good_cap_t(cap_d)) { _cap_debug("bad argument"); errno = EINVAL; return NULL; } result = cap_init(); if (result == NULL) { _cap_debug("out of memory"); return NULL; } memcpy(result, cap_d, sizeof(*cap_d)); return result; }
int cap_free(void *data_p) { if ( good_cap_t(data_p) ) { data_p = -1 + (__u32 *) data_p; memset(data_p, 0, sizeof(__u32) + sizeof(struct _cap_struct)); free(data_p); data_p = NULL; return 0; } if ( good_cap_string(data_p) ) { int length = strlen(data_p) + sizeof(__u32); data_p = -1 + (__u32 *) data_p; memset(data_p, 0, length); free(data_p); data_p = NULL; return 0; } _cap_debug("don't recognize what we're supposed to liberate"); errno = EINVAL; return -1; }
static int _fcaps_save(struct vfs_cap_data *rawvfscap, cap_t cap_d, int *bytes_p) { __u32 eff_not_zero, magic; unsigned tocopy, i; if (!good_cap_t(cap_d)) { errno = EINVAL; return -1; } switch (cap_d->head.version) { #ifdef _LINUX_CAPABILITY_VERSION_1 case _LINUX_CAPABILITY_VERSION_1: magic = VFS_CAP_REVISION_1; tocopy = VFS_CAP_U32_1; *bytes_p = XATTR_CAPS_SZ_1; break; #endif #ifdef _LINUX_CAPABILITY_VERSION_2 case _LINUX_CAPABILITY_VERSION_2: magic = VFS_CAP_REVISION_2; tocopy = VFS_CAP_U32_2; *bytes_p = XATTR_CAPS_SZ_2; break; #endif #ifdef _LINUX_CAPABILITY_VERSION_3 case _LINUX_CAPABILITY_VERSION_3: magic = VFS_CAP_REVISION_2; tocopy = VFS_CAP_U32_2; *bytes_p = XATTR_CAPS_SZ_2; break; #endif default: errno = EINVAL; return -1; } _cap_debug("setting named file capabilities"); for (eff_not_zero = 0, i = 0; i < tocopy; i++) { eff_not_zero |= cap_d->u[i].flat[CAP_EFFECTIVE]; } while (i < __CAP_BLKS) { if ((cap_d->u[i].flat[CAP_EFFECTIVE] || cap_d->u[i].flat[CAP_INHERITABLE] || cap_d->u[i].flat[CAP_PERMITTED])) { /* * System does not support these capabilities */ errno = EINVAL; return -1; } i++; } for (i=0; i < tocopy; i++) { rawvfscap->data[i].permitted = FIXUP_32BITS(cap_d->u[i].flat[CAP_PERMITTED]); rawvfscap->data[i].inheritable = FIXUP_32BITS(cap_d->u[i].flat[CAP_INHERITABLE]); if (eff_not_zero && ((~(cap_d->u[i].flat[CAP_EFFECTIVE])) & (cap_d->u[i].flat[CAP_PERMITTED] | cap_d->u[i].flat[CAP_INHERITABLE]))) { errno = EINVAL; return -1; } } if (eff_not_zero == 0) { rawvfscap->magic_etc = FIXUP_32BITS(magic); } else { rawvfscap->magic_etc = FIXUP_32BITS(magic|VFS_CAP_FLAGS_EFFECTIVE); } return 0; /* success */ }
char *cap_to_text(cap_t caps, ssize_t *length_p) { static char buf[CAP_TEXT_SIZE+CAP_TEXT_BUFFER_ZONE]; char *p; int histo[8] = {0}; int m, n, t; /* Check arguments */ if (!good_cap_t(caps)) { errno = EINVAL; return NULL; } _cap_debugcap("e = ", &caps->set.effective); _cap_debugcap("i = ", &caps->set.inheritable); _cap_debugcap("p = ", &caps->set.permitted); for (n = __CAP_BITS; n--; ) histo[getstateflags(caps, n)]++; for (m=t=7; t--; ) if (histo[t] > histo[m]) m = t; /* blank is not a valid capability set */ p = sprintf(buf, "=%s%s%s", (m & LIBCAP_EFF) ? "e" : "", (m & LIBCAP_INH) ? "i" : "", (m & LIBCAP_PER) ? "p" : "" ) + buf; for (t = 8; t--; ) if (t != m && histo[t]) { *p++ = ' '; for (n = 0; n != __CAP_BITS; n++) if (getstateflags(caps, n) == t) { if (_cap_names[n]) p += sprintf(p, "%s,", _cap_names[n]); else p += sprintf(p, "%d,", n); if (p - buf > CAP_TEXT_SIZE) { errno = ERANGE; return NULL; } } p--; n = t & ~m; if (n) p += sprintf(p, "+%s%s%s", (n & LIBCAP_EFF) ? "e" : "", (n & LIBCAP_INH) ? "i" : "", (n & LIBCAP_PER) ? "p" : ""); n = ~t & m; if (n) p += sprintf(p, "-%s%s%s", (n & LIBCAP_EFF) ? "e" : "", (n & LIBCAP_INH) ? "i" : "", (n & LIBCAP_PER) ? "p" : ""); if (p - buf > CAP_TEXT_SIZE) { errno = ERANGE; return NULL; } } _cap_debug("%s", buf); if (length_p) { *length_p = p - buf; } return (_libcap_strdup(buf)); }