aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2008-03-29 21:40:06 -0700
committerAndrew G. Morgan <morgan@kernel.org>2008-03-29 21:40:06 -0700
commitcd5e81117523b5788cc94ad88ae3bb442891b3e3 (patch)
tree175406429f0223468fc59fbdf3a40a6f9ad318b8
parent0d418f0b03f1571c204b535173862d226ecc56b0 (diff)
downloadlibcap-cd5e81117523b5788cc94ad88ae3bb442891b3e3.tar.gz
Add cap_clear_flag() function to clear one of the EIP capability flag vectors
This function makes modifying only one of E I and P sets easier. cap_clear() = cap_clear_flag(,E) + cap_clear_flag(,I) + cap_clear_flag(,P) Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r--doc/cap_clear.319
-rw-r--r--libcap/cap_flag.c29
-rw-r--r--libcap/include/sys/capability.h1
-rw-r--r--progs/capsh.c6
4 files changed, 48 insertions, 7 deletions
diff --git a/doc/cap_clear.3 b/doc/cap_clear.3
index 92a66a9..68dd521 100644
--- a/doc/cap_clear.3
+++ b/doc/cap_clear.3
@@ -1,7 +1,4 @@
-.\"
-.\" $Id: cap_clear.3,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $
-.\"
-.TH CAP_CLEAR 3 "26th May 1997" "" "Linux Programmer's Manual"
+.TH CAP_CLEAR 3 "29th March 2008" "" "Linux Programmer's Manual"
.SH NAME
cap_clear, cap_get_flag, cap_set_flag \- capability data object manipulation
.SH SYNOPSIS
@@ -9,6 +6,8 @@ cap_clear, cap_get_flag, cap_set_flag \- capability data object manipulation
.sp
.BI "int cap_clear(cap_t " cap_p );
.sp
+.BI "int cap_clear_flag(cap_t " cap_p ", cap_flag_t " flag ");"
+.sp
.BI "int cap_get_flag(cap_t " cap_p ", cap_value_t " cap ", cap_flag_t " flag ", cap_flag_value_t *" value_p ");"
.sp
.BI "int cap_set_flag(cap_t " cap_p ", cap_flag_t " flag ", int " ncap ", const cap_value_t *" caps ", cap_flag_value_t " value ");"
@@ -20,6 +19,12 @@ initializes the capability state in working storage identified by
.I cap_p
in such a way that all capability flags are cleared.
.PP
+.B cap_clear_flag
+resets, to
+.BR CAP_CLEAR ,
+all of the capabilities of the specific capability flag,
+.IR flag .
+.PP
.B cap_get_flag
obtains the current value of the capability flag,
.IR flag ,
@@ -64,6 +69,7 @@ can be
(1).
.SH "RETURN VALUE"
.BR cap_clear ,
+.BR cap_clear_flag ,
.B cap_get_flag
and
.B cap_set_flag
@@ -74,9 +80,10 @@ On failure,
is set to
.BR EINVAL ,
indicating that one of the arguments is invalid.
-
.SH "CONFORMING TO"
-These functions are specified by POSIX.1e.
+These functions are as per the defunct POSIX.1e. spec.
+.B cap_clear_flag
+is an extension.
.SH "SEE ALSO"
.IR cap_copy_ext (3),
.IR cap_from_text (3),
diff --git a/libcap/cap_flag.c b/libcap/cap_flag.c
index c48cf94..536f655 100644
--- a/libcap/cap_flag.c
+++ b/libcap/cap_flag.c
@@ -93,3 +93,32 @@ int cap_clear(cap_t cap_d)
}
}
+/*
+ * Reset the all of the capability bits for one of the flag sets
+ */
+
+int cap_clear_flag(cap_t cap_d, cap_flag_t flag)
+{
+ switch (flag) {
+ case CAP_EFFECTIVE:
+ case CAP_PERMITTED:
+ case CAP_INHERITABLE:
+ if (good_cap_t(cap_d)) {
+ unsigned i;
+
+ for (i=0; i<_LINUX_CAPABILITY_U32S; i++) {
+ cap_d->u[i].flat[flag] = 0;
+ }
+ return 0;
+ }
+ /*
+ * fall through
+ */
+
+ default:
+ _cap_debug("invalid pointer");
+ errno = EINVAL;
+ return -1;
+ }
+}
+
diff --git a/libcap/include/sys/capability.h b/libcap/include/sys/capability.h
index 72964e4..ea19359 100644
--- a/libcap/include/sys/capability.h
+++ b/libcap/include/sys/capability.h
@@ -85,6 +85,7 @@ extern int cap_get_flag(cap_t, cap_value_t, cap_flag_t, cap_flag_value_t *);
extern int cap_set_flag(cap_t, cap_flag_t, int, const cap_value_t *,
cap_flag_value_t);
extern int cap_clear(cap_t);
+extern int cap_clear_flag(cap_t, cap_flag_t);
/* libcap/cap_file.c */
extern cap_t cap_get_fd(int);
diff --git a/progs/capsh.c b/progs/capsh.c
index c357d99..20ec453 100644
--- a/progs/capsh.c
+++ b/progs/capsh.c
@@ -101,6 +101,10 @@ int main(int argc, char *argv[], char *envp[])
perror("Capabilities not available");
exit(1);
}
+ if (cap_clear_flag(all, CAP_INHERITABLE) != 0) {
+ perror("libcap:cap_clear_flag() internal error");
+ exit(1);
+ }
raised_for_setpcap = cap_dup(all);
if ((raised_for_setpcap != NULL)
@@ -121,7 +125,7 @@ int main(int argc, char *argv[], char *envp[])
perror("Out of memory for inh set");
exit(1);
}
- sprintf(ptr, "%s all-i %s+i", text, argv[i]+6);
+ sprintf(ptr, "%s %s+i", text, argv[i]+6);
all = cap_from_text(ptr);
if (all == NULL) {