aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2008-01-21 05:03:48 -0800
committerAndrew G. Morgan <morgan@kernel.org>2008-01-21 05:03:48 -0800
commitf59a32cbe47fad5b9e34426131241b080eb65ca0 (patch)
tree0c0e44efdeb09bc33934a2583eca8bfe2e674729
parente64aa18f6da831ec1b787a57822080fd3b8cc378 (diff)
downloadlibcap-f59a32cbe47fad5b9e34426131241b080eb65ca0.tar.gz
Introduce two new capability <-> text helper functions.
_cap_names was a really clumsy interface. With this commit, we add cap_to_name() and cap_from_name() with manual documentation too. Signed-off-by: Andrew G. Morgan <morgan@kernel.org>
-rw-r--r--doc/Makefile5
-rw-r--r--doc/cap_clear.32
-rw-r--r--doc/cap_from_name.31
-rw-r--r--doc/cap_from_text.355
-rw-r--r--doc/cap_to_name.31
-rw-r--r--libcap/cap_flag.c2
-rw-r--r--libcap/cap_text.c32
-rw-r--r--libcap/include/sys/capability.h48
8 files changed, 102 insertions, 44 deletions
diff --git a/doc/Makefile b/doc/Makefile
index aa6c055..2c1898a 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -1,6 +1,4 @@
#
-# $Id: Makefile,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $
-#
# Makefile for libcap documentation
#
@@ -13,7 +11,8 @@ MAN3S = cap_init.3 cap_free.3 cap_dup.3 \
cap_get_proc.3 cap_set_proc.3 \
cap_get_file.3 cap_get_fd.3 cap_set_file.3 cap_set_fd.3 \
cap_copy_ext.3 cap_size.3 cap_copy_int.3 \
- cap_from_text.3 cap_to_text.3 _cap_names.3 \
+ cap_from_text.3 cap_to_text.3 cap_from_name.3 cap_to_name.3 \
+ _cap_names.3 \
capsetp.3 capgetp.3
MAN8S = getcap.8 setcap.8
diff --git a/doc/cap_clear.3 b/doc/cap_clear.3
index c3560ff..92a66a9 100644
--- a/doc/cap_clear.3
+++ b/doc/cap_clear.3
@@ -11,7 +11,7 @@ cap_clear, cap_get_flag, cap_set_flag \- capability data object manipulation
.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 ", cap_value_t *" caps ", cap_flag_value_t " value ");"
+.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 ");"
.SH USAGE
.B cc ... -lcap
.SH DESCRIPTION
diff --git a/doc/cap_from_name.3 b/doc/cap_from_name.3
new file mode 100644
index 0000000..83ec8b5
--- /dev/null
+++ b/doc/cap_from_name.3
@@ -0,0 +1 @@
+.so man3/cap_from_text.3
diff --git a/doc/cap_from_text.3 b/doc/cap_from_text.3
index 2780a82..cb33db5 100644
--- a/doc/cap_from_text.3
+++ b/doc/cap_from_text.3
@@ -1,10 +1,9 @@
.\"
-.\" $Id: cap_from_text.3,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $
.\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
.\"
-.TH CAP_FROM_TEXT 3 "26th May 1997" "" "Linux Programmer's Manual"
+.TH CAP_FROM_TEXT 3 "21th Jan 2008" "" "Linux Programmer's Manual"
.SH NAME
-cap_from_text, cap_to_text, _cap_names \- capability state textual representation translation
+cap_from_text, cap_to_text, cap_to_name, cap_from_name, _cap_names \- capability state textual representation translation
.SH SYNOPSIS
.B #include <sys/capability.h>
.sp
@@ -12,6 +11,10 @@ cap_from_text, cap_to_text, _cap_names \- capability state textual representatio
.sp
.BI "char *cap_to_text(cap_t " caps ", ssize_t *" length_p );
.sp
+.BI "int cap_from_text(const char *" name ", cap_value_t *" cap_p );
+.sp
+.BI "char *cap_to_text(cap_value_t " cap );
+.sp
.B extern char const *_cap_names[];
.SH USAGE
.br
@@ -44,9 +47,9 @@ is both set and cleared within a single clause.
.B cap_to_text
converts the capability state in working storage identified by
.I cap_p
-into a null terminated human-readable string. This function allocates any
-memory necessary to contain the string, and returns a pointer to the string. If
-the pointer
+into a null terminated human-readable string. This function allocates
+any memory necessary to contain the string, and returns a pointer to
+the string. If the pointer
.I len_p
is not
.BR NULL ,
@@ -63,6 +66,26 @@ with
.B cap_p
as an argument.
.PP
+.B cap_from_name
+converts a text representation of a capability, such as "cap_chown",
+to its numerical representation (
+.B CAP_CHOWN=0
+). Writing the decoded value into
+.B *cap_p.
+If
+.B cap_p
+is
+.B NULL
+no result is written, but the return code of the function indicates
+whether or not the specified capability can be represented by the
+library.
+.PP
+.B cap_to_text
+converts a capability index value,
+.B cap ,
+to a libcap allocated textual string. This string should be deallocated with
+.B "cap_free" .
+.PP
.B _cap_names
is an array of textual names for capability numbers. Unnamed capabilities
have a NULL entry. (This array is not defined by POSIX.1e.)
@@ -95,8 +118,10 @@ special name
specifies all capabilities; it is equivalent to a list naming every
capability individually.
.PP
-Although not defined by POSIX, unnamed capabilities can be specified
-by number.
+Unnamed capabilities can also be specified by number. This feature
+ensures that libcap can support capabilities that were not allocated
+at the time libcap was compiled. However, generally upgrading libcap
+will add names for recently allocated capabilities.
.PP
The
.RB ` = '
@@ -127,10 +152,13 @@ will raise the override-file-ownership capability in the Permitted
capability set and lower this Inheritable capability;
"cap_fowner+pe-i" and "cap_fowner=+pe" are equivalent.
.SH "RETURN VALUE"
-.B cap_from_text
+.B "cap_from_text" ,
+.B cap_to_text
and
.B cap_to_text
return a non-NULL value on success, and NULL on failure.
+.B cap_from_text
+returns 0 for success, and -1 on failure (unknown capability).
.PP
On failure,
.BR errno (3)
@@ -142,9 +170,12 @@ or
.B cap_from_text
and
.B cap_to_text
-are specified by POSIX.1e.
-.B _cap_names
-is a Linux extension.
+are specified by the withdrawn POSIX.1e draft.
+.B cap_from_name ,
+.B cap_to_name
+and
+.B "_cap_names"
+are a Linux extension.
.SH "SEE ALSO"
.IR cap_clear (3),
.IR cap_copy_ext (3),
diff --git a/doc/cap_to_name.3 b/doc/cap_to_name.3
new file mode 100644
index 0000000..83ec8b5
--- /dev/null
+++ b/doc/cap_to_name.3
@@ -0,0 +1 @@
+.so man3/cap_from_text.3
diff --git a/libcap/cap_flag.c b/libcap/cap_flag.c
index e521fcd..c48cf94 100644
--- a/libcap/cap_flag.c
+++ b/libcap/cap_flag.c
@@ -37,7 +37,7 @@ int cap_get_flag(cap_t cap_d, cap_value_t value, cap_flag_t set,
*/
int cap_set_flag(cap_t cap_d, cap_flag_t set,
- int no_values, cap_value_t *array_values,
+ int no_values, const cap_value_t *array_values,
cap_flag_value_t raise)
{
/*
diff --git a/libcap/cap_text.c b/libcap/cap_text.c
index 06f61d9..ee22b39 100644
--- a/libcap/cap_text.c
+++ b/libcap/cap_text.c
@@ -11,6 +11,7 @@
#include <ctype.h>
#include <stdio.h>
+#include <limits.h>
/* Maximum output text length (16 per cap) */
#define CAP_TEXT_SIZE (16*__CAP_BITS)
@@ -229,6 +230,37 @@ bad:
}
/*
+ * lookup a capability name and return its numerical value
+ */
+int cap_from_name(const char *name, cap_value_t *value_p)
+{
+ int n;
+
+ if (((n = lookupname(&name)) < 0) && (value_p != NULL)) {
+ *value_p = (unsigned) n;
+ }
+ return -(n < 0);
+}
+
+/*
+ * Convert a single capability index number into a string representation
+ */
+char *cap_to_name(cap_value_t cap)
+{
+ if ((cap < 0) || (cap >= __CAP_BITS)) {
+#if UINT_MAX != 4294967295U
+# error Recompile with correctly sized numeric array
+#endif
+ char numeric[11];
+
+ sprintf(numeric, "%u", cap);
+ return _libcap_strdup(numeric);
+ } else {
+ return _libcap_strdup(_cap_names[cap]);
+ }
+}
+
+/*
* Convert an internal representation to a textual one. The textual
* representation is stored in static memory. It will be overwritten
* on the next occasion that this function is called.
diff --git a/libcap/include/sys/capability.h b/libcap/include/sys/capability.h
index 6dbe656..0e4ba37 100644
--- a/libcap/include/sys/capability.h
+++ b/libcap/include/sys/capability.h
@@ -2,7 +2,7 @@
* <sys/capability.h>
*
* Copyright (C) 1997 Aleph One
- * Copyright (C) 1997-8 Andrew G. Morgan <morgan@kernel.org>
+ * Copyright (C) 1997-8,2008 Andrew G. Morgan <morgan@kernel.org>
*
* defunct POSIX.1e Standard: 25.2 Capabilities <sys/capability.h>
*/
@@ -76,40 +76,36 @@ typedef enum {
*/
/* libcap/cap_alloc.c */
-cap_t cap_dup(cap_t);
-int cap_free(void *);
-cap_t cap_init(void);
+extern cap_t cap_dup(cap_t);
+extern int cap_free(void *);
+extern cap_t cap_init(void);
/* libcap/cap_flag.c */
-int cap_get_flag(cap_t, cap_value_t, cap_flag_t, cap_flag_value_t *);
-int cap_set_flag(cap_t, cap_flag_t, int, cap_value_t *, cap_flag_value_t);
-int cap_clear(cap_t);
+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);
/* libcap/cap_file.c */
-cap_t cap_get_fd(int);
-cap_t cap_get_file(const char *);
-int cap_set_fd(int, cap_t);
-int cap_set_file(const char *, cap_t);
+extern cap_t cap_get_fd(int);
+extern cap_t cap_get_file(const char *);
+extern int cap_set_fd(int, cap_t);
+extern int cap_set_file(const char *, cap_t);
/* libcap/cap_proc.c */
-cap_t cap_get_proc(void);
-int cap_set_proc(cap_t);
+extern cap_t cap_get_proc(void);
+extern int cap_set_proc(cap_t);
/* libcap/cap_extint.c */
-ssize_t cap_size(cap_t);
-ssize_t cap_copy_ext(void *, cap_t, ssize_t);
-cap_t cap_copy_int(const void *);
+extern ssize_t cap_size(cap_t);
+extern ssize_t cap_copy_ext(void *, cap_t, ssize_t);
+extern cap_t cap_copy_int(const void *);
/* libcap/cap_text.c */
-cap_t cap_from_text(const char *);
-char * cap_to_text(cap_t, ssize_t *);
-
-/*
- * Linux capability system calls: defined in libcap but only available
- * if the following _POSIX_SOURCE is _undefined_
- */
-
-#if !defined(_POSIX_SOURCE)
+extern cap_t cap_from_text(const char *);
+extern char * cap_to_text(cap_t, ssize_t *);
+extern int cap_from_name(const char *, cap_value_t *);
+extern char * cap_to_name(cap_value_t);
extern int capset(cap_user_header_t header, cap_user_data_t data);
extern int capget(cap_user_header_t header, const cap_user_data_t data);
@@ -117,8 +113,6 @@ extern int capgetp(pid_t pid, cap_t cap_d);
extern int capsetp(pid_t pid, cap_t cap_d);
extern char const *_cap_names[];
-#endif /* !defined(_POSIX_SOURCE) */
-
#ifdef __cplusplus
}
#endif