On Thursday, 14 July 2016 09:49:56 CEST Richard W.M. Jones wrote:
---
appliance/packagelist.in | 1 +
daemon/Makefile.am | 1 +
daemon/setfiles.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++
generator/actions.ml | 22 ++++++++++++
gobject/Makefile.inc | 2 ++
src/MAX_PROC_NR | 2 +-
6 files changed, 120 insertions(+), 1 deletion(-)
create mode 100644 daemon/setfiles.c
diff --git a/appliance/packagelist.in b/appliance/packagelist.in
index 5f04c1c..3a4790b 100644
--- a/appliance/packagelist.in
+++ b/appliance/packagelist.in
@@ -43,6 +43,7 @@ ifelse(REDHAT,1,
ntfs-3g
openssh-clients
pcre
+ policycoreutils
reiserfs-utils
libselinux
syslinux-extlinux
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index b77d1e7..9bd495f 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -168,6 +168,7 @@ guestfsd_SOURCES = \
rsync.c \
scrub.c \
selinux.c \
+ setfiles.c \
Why not directly in selinux.c? IMHO would be more logic (all the
SELinux stuff in the daemon grouped there).
sfdisk.c \
sh.c \
sleep.c \
diff --git a/daemon/setfiles.c b/daemon/setfiles.c
new file mode 100644
index 0000000..3f249c3
--- /dev/null
+++ b/daemon/setfiles.c
@@ -0,0 +1,93 @@
+/* libguestfs - the guestfsd daemon
+ * Copyright (C) 2016 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 <stdlib.h>
+#include <string.h>
+
+#include "guestfs_protocol.h"
+#include "daemon.h"
+#include "actions.h"
+
+GUESTFSD_EXT_CMD(str_setfiles, setfiles);
+
+#define MAX_ARGS 64
+
+/* Takes optional arguments, consult optargs_bitmask. */
+int
+do_setfiles (const char *specfile, const char *path,
+ int force)
+{
+ const char *argv[MAX_ARGS];
+ CLEANUP_FREE char *s_dev = NULL, *s_proc = NULL, *s_selinux = NULL,
+ *s_sys = NULL, *s_specfile = NULL, *s_path = NULL;
+ CLEANUP_FREE char *err = NULL;
+ size_t i = 0;
+
+ s_dev = sysroot_path ("/dev");
+ if (!s_dev) {
+ malloc_error:
+ reply_with_perror ("malloc");
+ return -1;
+ }
+ s_proc = sysroot_path ("/proc"); if (!s_proc) goto malloc_error;
+ s_selinux = sysroot_path ("/selinux"); if (!s_selinux) goto malloc_error;
+ s_sys = sysroot_path ("/sys"); if (!s_sys) goto malloc_error;
+ s_specfile = sysroot_path (specfile); if (!s_specfile) goto malloc_error;
+ s_path = sysroot_path (path); if (!s_path) goto malloc_error;
I'd simpy do all the sysroot_path calls one after each other, and then
check all the results at once:
if (!s_dev || !s_proc ...)
All these buffers are CLEANUP_FREE anyway, and this could IMHO simplify
the reading/organization of the code.
+ /* Default settings if not selected. */
+ if (!(optargs_bitmask & GUESTFS_SETFILES_FORCE_BITMASK))
+ force = 0;
+
+ ADD_ARG (argv, i, str_setfiles);
+ if (force)
+ ADD_ARG (argv, i, "-F");
+
+ /* Exclude some directories that should never be relabelled in
+ * ordinary Linux guests. These won't be mounted anyway. We have
+ * to prefix all these with the sysroot path.
+ */
+ ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_dev);
+ ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_proc);
+ ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_selinux);
+ ADD_ARG (argv, i, "-e"); ADD_ARG (argv, i, s_sys);
+
+ /* Relabelling in a chroot. */
+ if (STRNEQ (sysroot, "/")) {
+ ADD_ARG (argv, i, "-r");
+ ADD_ARG (argv, i, sysroot);
+ }
+
+ /* Suppress non-error output. */
+ ADD_ARG (argv, i, "-q");
+
+ /* Add parameters. */
+ ADD_ARG (argv, i, s_specfile);
+ ADD_ARG (argv, i, s_path);
+ ADD_ARG (argv, i, NULL);
+
+ if (commandv (NULL, &err, argv) == -1) {
+ reply_with_perror ("%s", err);
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/generator/actions.ml b/generator/actions.ml
index 25108a2..49c360c 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -13149,6 +13149,28 @@ fails and the C<errno> is set to C<ENODEV>."
};
shortdesc = "walk through the filesystem content";
longdesc = "Internal function for filesystem_walk." };
+ { defaults with
+ name = "setfiles"; added = (1, 33, 43);
+ style = RErr, [String "specfile"; Pathname "path"], [OBool
"force"];
+ proc_nr = Some 467;
This needs to be feature-dependent IMHO, so it will fail gracefully on
non-SELinux hosts.
Thanks,
--
Pino Toscano