diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2012-11-22 14:49:54 +0000 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2012-11-22 16:45:32 +0000 |
commit | fae8d7cafb66e0da697cde71f7e9444165c76ff7 (patch) | |
tree | 9ef86b17795fab79a3e4d56ececd6de0817168c7 /daemon/cap.c | |
parent | 218b39acae324955b089dcfc191b0270b6bafb62 (diff) | |
download | libguestfs-fae8d7cafb66e0da697cde71f7e9444165c76ff7.tar.gz libguestfs-fae8d7cafb66e0da697cde71f7e9444165c76ff7.tar.xz libguestfs-fae8d7cafb66e0da697cde71f7e9444165c76ff7.zip |
New APIs: Implement Linux filesystem capabilities.
This adds the following new APIs:
- cap_get_file
- cap_set_file
Diffstat (limited to 'daemon/cap.c')
-rw-r--r-- | daemon/cap.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/daemon/cap.c b/daemon/cap.c new file mode 100644 index 00000000..3572704c --- /dev/null +++ b/daemon/cap.c @@ -0,0 +1,131 @@ +/* libguestfs - the guestfsd daemon + * Copyright (C) 2012 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <config.h> + +#include <stdio.h> +#include <limits.h> +#include <unistd.h> + +#include "guestfs_protocol.h" +#include "daemon.h" +#include "actions.h" +#include "optgroups.h" + +#if defined(HAVE_CAP) + +#include <sys/capability.h> + +int +optgroup_linuxcaps_available (void) +{ + return 1; +} + +char * +do_cap_get_file (const char *path) +{ + cap_t cap; + char *r, *ret; + + CHROOT_IN; + cap = cap_get_file (path); + CHROOT_OUT; + + if (cap == NULL) { + reply_with_perror ("%s", path); + return NULL; + } + + r = cap_to_text (cap, NULL); + if (r == NULL) { + reply_with_perror ("cap_to_text"); + cap_free (cap); + return NULL; + } + + cap_free (cap); + + /* 'r' is not an ordinary pointer that can be freed with free(3)! + * In the current implementation of libcap, if you try to do that it + * will segfault. We have to duplicate this into an ordinary + * buffer, then call cap_free (r). + */ + ret = strdup (r); + if (ret == NULL) { + reply_with_perror ("strdup"); + cap_free (r); + return NULL; + } + cap_free (r); + + return ret; /* caller frees */ +} + +int +do_cap_set_file (const char *path, const char *capstr) +{ + cap_t cap; + int r; + + cap = cap_from_text (capstr); + if (cap == NULL) { + reply_with_perror ("could not parse cap string: %s: cap_from_text", capstr); + return -1; + } + + CHROOT_IN; + r = cap_set_file (path, cap); + CHROOT_OUT; + + if (r == -1) { + reply_with_perror ("%s", path); + cap_free (cap); + return -1; + } + + cap_free (cap); + + return 0; +} + +#else /* no libcap */ + +/* Note that the wrapper code (daemon/stubs.c) ensures that the + * functions below are never called because + * optgroup_linuxcaps_available returns false. + */ +int +optgroup_linuxcaps_available (void) +{ + return 0; +} + +char * +do_cap_get_file (const char *path) +{ + abort (); +} + +int +do_cap_set_file (const char *path, const char *cap) +{ + abort (); +} + +#endif /* no libcap */ |