From f59a32cbe47fad5b9e34426131241b080eb65ca0 Mon Sep 17 00:00:00 2001 From: "Andrew G. Morgan" Date: Mon, 21 Jan 2008 05:03:48 -0800 Subject: 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 --- doc/Makefile | 5 ++-- doc/cap_clear.3 | 2 +- doc/cap_from_name.3 | 1 + doc/cap_from_text.3 | 55 ++++++++++++++++++++++++++++++++--------- doc/cap_to_name.3 | 1 + libcap/cap_flag.c | 2 +- libcap/cap_text.c | 32 ++++++++++++++++++++++++ libcap/include/sys/capability.h | 48 ++++++++++++++++------------------- 8 files changed, 102 insertions(+), 44 deletions(-) create mode 100644 doc/cap_from_name.3 create mode 100644 doc/cap_to_name.3 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 .\" -.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 .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 #include +#include /* Maximum output text length (16 per cap) */ #define CAP_TEXT_SIZE (16*__CAP_BITS) @@ -228,6 +229,37 @@ bad: return res; } +/* + * 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 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 @@ * * * Copyright (C) 1997 Aleph One - * Copyright (C) 1997-8 Andrew G. Morgan + * Copyright (C) 1997-8,2008 Andrew G. Morgan * * defunct POSIX.1e Standard: 25.2 Capabilities */ @@ -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 -- cgit 1.2.3-korg