If a uid and/or gid is specified for a command, it will be set just
after the user-supplied post-fork "hook" function is called.
The intent is that this can replace user hook functions that set
uid/gid. This moves the setting of uid/gid and dropping of
capabilities closer to each other, which is important since the two
should really be done at the same time (libcapng provides a single
function that does both, which we will be unable to use, but want to
mimic as closely as possible).
---
src/libvirt_private.syms | 2 ++
src/util/vircommand.c | 26 ++++++++++++++++++++++++++
src/util/vircommand.h | 6 +++++-
3 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 57e3eb4..83d83ad 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -159,12 +159,14 @@ virCommandRun;
virCommandRunAsync;
virCommandSetErrorBuffer;
virCommandSetErrorFD;
+virCommandSetGID;
virCommandSetInputBuffer;
virCommandSetInputFD;
virCommandSetOutputBuffer;
virCommandSetOutputFD;
virCommandSetPidFile;
virCommandSetPreExecHook;
+virCommandSetUID;
virCommandSetWorkingDirectory;
virCommandToString;
virCommandTransferFD;
diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index ba81c14..65838d1 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -101,6 +101,8 @@ struct _virCommand {
char *pidfile;
bool reap;
+ uid_t uid;
+ gid_t gid;
unsigned long long capabilities;
};
@@ -605,6 +607,12 @@ virExec(virCommandPtr cmd)
goto fork_error;
}
+ if (cmd->uid > 0 || cmd->gid > 0) {
+ VIR_DEBUG("Setting child uid:gid to %u:%u", cmd->uid, cmd->gid);
+ if (virSetUIDGID(cmd->uid, cmd->gid) < 0)
+ goto fork_error;
+ }
+
if (cmd->pwd) {
VIR_DEBUG("Running child in %s", cmd->pwd);
if (chdir(cmd->pwd) < 0) {
@@ -905,6 +913,24 @@ virCommandSetPidFile(virCommandPtr cmd, const char *pidfile)
}
+void
+virCommandSetGID(virCommandPtr cmd, gid_t gid)
+{
+ if (!cmd || cmd->has_error)
+ return;
+
+ cmd->gid = gid;
+}
+
+void
+virCommandSetUID(virCommandPtr cmd, uid_t uid)
+{
+ if (!cmd || cmd->has_error)
+ return;
+
+ cmd->uid = uid;
+}
+
/**
* virCommandClearCaps:
* @cmd: the command to modify
diff --git a/src/util/vircommand.h b/src/util/vircommand.h
index c1a2e24..ac940f0 100644
--- a/src/util/vircommand.h
+++ b/src/util/vircommand.h
@@ -1,7 +1,7 @@
/*
* vircommand.h: Child command execution
*
- * Copyright (C) 2010-2011 Red Hat, Inc.
+ * Copyright (C) 2010-2011, 2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -61,6 +61,10 @@ void virCommandTransferFD(virCommandPtr cmd,
void virCommandSetPidFile(virCommandPtr cmd,
const char *pidfile) ATTRIBUTE_NONNULL(2);
+void virCommandSetGID(virCommandPtr cmd, gid_t gid);
+
+void virCommandSetUID(virCommandPtr cmd, uid_t uid);
+
void virCommandClearCaps(virCommandPtr cmd);
void virCommandAllowCap(virCommandPtr cmd,
--
1.8.1