-Thu Jun 12 13:06:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
+Fri Jun 12 14:16:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
+
+ Remove use of getuid()==0 for privilege checks
+ * qemud/qemud.c, qemud/qemud.h, src/driver.h, src/libvirt.c,
+ src/libvirt_internal.h, src/lxc_driver.c, src/network_driver.c,
+ src/node_device_devkit.c, src/node_device_hal.c,
+ src/qemu_conf.h, src/qemu_driver.c, src/remote_internal.c,
+ src/storage_driver.c, src/uml_conf.h, src/uml_driver.c,
+ src/xen_internal.c, src/xen_unified.c: Remove all use of
+ getuid()/geteuid() to determine if privileged. Replace with
+ 'privileged' flag provided by libvirtd, or direct access
+ checks.
+
+Fri Jun 12 13:36:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
Include OS driver name (if any) in device XML
* src/node_device.c: Refresh OS driver when generating XML,
* src/node_device_hal.c: Record sysfs path to be used for
driver name fetching later.
-Thu Jun 12 13:06:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
+Fri Jun 12 13:06:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
Improve error reporting for virConnectOpen URIs
* src/lxc_driver.c, src/openvz_driver.c, src/qemu_driver.c,
* src/virterror.c: Improve error message text for
VIR_ERR_NO_CONNECT code
-Thu Jun 12 12:26:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
+Fri Jun 12 12:26:42 BST 2009 Daniel P. Berrange <berrange@redhat.com>
Fix re-detection of transient VMs after libvirtd restart
* src/domain_conf.c, src/domain_conf.h, src/libvirt_private.syms:
#else
-#define SYSTEM_UID 0
-
static gid_t unix_sock_gid = 0; /* Only root by default */
static int unix_sock_rw_mask = 0700; /* Allow user only */
static int unix_sock_ro_mask = 0777; /* Allow world */
oldgrp = getgid();
oldmask = umask(readonly ? ~unix_sock_ro_mask : ~unix_sock_rw_mask);
- if (getuid() == 0)
+ if (server->privileged)
setgid(unix_sock_gid);
if (bind(sock->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
goto cleanup;
}
umask(oldmask);
- if (getuid() == 0)
+ if (server->privileged)
setgid(oldgrp);
if (listen(sock->fd, 30) < 0) {
char *roSockname,
int maxlen)
{
- uid_t uid = geteuid();
char *sock_dir;
char *dir_prefix = NULL;
int ret = -1;
sock_dir = unix_sock_dir;
else {
sock_dir = sockname;
- if (uid == SYSTEM_UID) {
+ if (server->privileged) {
dir_prefix = strdup (LOCAL_STATE_DIR);
if (dir_prefix == NULL) {
virReportOOMError(NULL);
dir_prefix) >= maxlen)
goto snprintf_error;
} else {
+ uid_t uid = geteuid();
dir_prefix = virGetUserDirectory(NULL, uid);
if (dir_prefix == NULL) {
/* Do not diagnose here; virGetUserDirectory does that. */
goto cleanup;
}
- if (uid == SYSTEM_UID) {
+ if (server->privileged) {
if (snprintf (sockname, maxlen, "%s/libvirt-sock",
sock_dir_prefix) >= maxlen
|| (snprintf (roSockname, maxlen, "%s/libvirt-sock-ro",
goto snprintf_error;
}
- if (uid == SYSTEM_UID)
- server->logDir = strdup (LOCAL_STATE_DIR "/log/libvirt");
+ if (server->privileged)
+ server->logDir = strdup (LOCAL_STATE_DIR "/log/libvirt");
else
- virAsprintf(&server->logDir, "%s/.libvirt/log", dir_prefix);
+ virAsprintf(&server->logDir, "%s/.libvirt/log", dir_prefix);
if (server->logDir == NULL)
virReportOOMError(NULL);
VIR_FREE(server);
}
+ server->privileged = geteuid() == 0 ? 1 : 0;
server->sigread = sigread;
if (virEventInit() < 0) {
virEventUpdateTimeoutImpl,
virEventRemoveTimeoutImpl);
- virStateInitialize();
+ virStateInitialize(server->privileged);
return server;
}
}
#ifdef HAVE_AVAHI
- if (getuid() == 0 && mdns_adv) {
+ if (server->privileged && mdns_adv) {
struct libvirtd_mdns_group *group;
int port = 0;
#if HAVE_POLKIT
/* Change the default back to no auth for non-root */
- if (getuid() != 0 && auth_unix_rw == REMOTE_AUTH_POLKIT)
+ if (!server->privileged && auth_unix_rw == REMOTE_AUTH_POLKIT)
auth_unix_rw = REMOTE_AUTH_NONE;
- if (getuid() != 0 && auth_unix_ro == REMOTE_AUTH_POLKIT)
+ if (!server->privileged && auth_unix_ro == REMOTE_AUTH_POLKIT)
auth_unix_ro = REMOTE_AUTH_NONE;
#endif
GET_CONF_STR (conf, filename, unix_sock_group);
if (unix_sock_group) {
- if (getuid() != 0) {
+ if (!server->privileged) {
VIR_WARN0(_("Cannot set group when not running as root"));
} else {
int ret;
/* If running as root and no PID file is set, use the default */
if (pid_file == NULL &&
- getuid() == 0 &&
+ geteuid() == 0 &&
REMOTE_PID_FILE[0] != '\0')
pid_file = REMOTE_PID_FILE;
sigaction(SIGPIPE, &sig_action, NULL);
/* Ensure the rundir exists (on tmpfs on some systems) */
- if (geteuid () == 0) {
+ if (geteuid() == 0) {
const char *rundir = LOCAL_STATE_DIR "/run/libvirt";
if (mkdir (rundir, 0755)) {
}
}
+ /* Beyond this point, nothing should rely on using
+ * getuid/geteuid() == 0, for privilege level checks.
+ * It must all use the flag 'server->privileged'
+ * which is also passed into all libvirt stateful
+ * drivers
+ */
if (qemudSetupPrivs() < 0)
goto error2;
goto error2;
/* Change the group ownership of /var/run/libvirt to unix_sock_gid */
- if (unix_sock_dir && geteuid() == 0) {
+ if (unix_sock_dir && server->privileged) {
if (chown(unix_sock_dir, -1, unix_sock_gid) < 0)
VIR_ERROR(_("Failed to change group ownership of %s"),
unix_sock_dir);
virMutex lock;
virCond job;
+ int privileged;
+
int nworkers;
int nactiveworkers;
struct qemud_worker *workers;
};
#ifdef WITH_LIBVIRTD
-typedef int (*virDrvStateInitialize) (void);
+typedef int (*virDrvStateInitialize) (int privileged);
typedef int (*virDrvStateCleanup) (void);
typedef int (*virDrvStateReload) (void);
typedef int (*virDrvStateActive) (void);
*
* Return 0 if all succeed, -1 upon any failure.
*/
-int virStateInitialize(void) {
+int virStateInitialize(int privileged) {
int i, ret = 0;
if (virInitialize() < 0)
for (i = 0 ; i < virStateDriverTabCount ; i++) {
if (virStateDriverTab[i]->initialize &&
- virStateDriverTab[i]->initialize() < 0)
+ virStateDriverTab[i]->initialize(privileged) < 0)
ret = -1;
}
return ret;
#ifdef WITH_LIBVIRTD
-int virStateInitialize(void);
+int virStateInitialize(int privileged);
int virStateCleanup(void);
int virStateReload(void);
int virStateActive(void);
#define VIR_FROM_THIS VIR_FROM_LXC
-static int lxcStartup(void);
+static int lxcStartup(int privileged);
static int lxcShutdown(void);
static lxc_driver_t *lxc_driver = NULL;
return 1;
}
-static int lxcStartup(void)
+static int lxcStartup(int privileged)
{
- uid_t uid = getuid();
unsigned int i;
char *ld;
return -1;
/* Check that the user is root */
- if (0 != uid) {
+ if (!privileged) {
return -1;
}
* Initialization function for the QEmu daemon
*/
static int
-networkStartup(void) {
+networkStartup(int privileged) {
uid_t uid = geteuid();
char *base = NULL;
int err;
}
networkDriverLock(driverState);
- if (!uid) {
+ if (privileged) {
if (virAsprintf(&driverState->logDir,
"%s/log/libvirt/qemu", LOCAL_STATE_DIR) == -1)
goto out_of_memory;
}
-static int devkitDeviceMonitorStartup(void)
+static int devkitDeviceMonitorStartup(int privileged ATTRIBUTE_UNUSED)
{
size_t caps_tbl_len = sizeof(caps_tbl) / sizeof(caps_tbl[0]);
DevkitClient *devkit_client = NULL;
}
-static int halDeviceMonitorStartup(void)
+static int halDeviceMonitorStartup(int privileged ATTRIBUTE_UNUSED)
{
LibHalContext *hal_ctx = NULL;
DBusConnection *dbus_conn = NULL;
struct qemud_driver {
virMutex lock;
+ int privileged;
+
unsigned int qemuVersion;
int nextvmid;
static int
-qemudLogFD(virConnectPtr conn, const char* logDir, const char* name)
+qemudLogFD(virConnectPtr conn, struct qemud_driver *driver, const char* name)
{
char logfile[PATH_MAX];
mode_t logmode;
- uid_t uid = geteuid();
int ret, fd = -1;
- if ((ret = snprintf(logfile, sizeof(logfile), "%s/%s.log", logDir, name))
+ if ((ret = snprintf(logfile, sizeof(logfile), "%s/%s.log",
+ driver->logDir, name))
< 0 || ret >= sizeof(logfile)) {
virReportOOMError(conn);
return -1;
}
logmode = O_CREAT | O_WRONLY;
- if (uid != 0)
- logmode |= O_TRUNC;
- else
+ /* Only logrotate files in /var/log, so only append if running privileged */
+ if (driver->privileged)
logmode |= O_APPEND;
+ else
+ logmode |= O_TRUNC;
+
if ((fd = open(logfile, logmode, S_IRUSR | S_IWUSR)) < 0) {
virReportSystemError(conn, errno,
_("failed to create logfile %s"),
* to lookup the bridge associated with a virtual
* network
*/
- virConnectPtr conn = virConnectOpen(getuid() ?
- "qemu:///session" :
- "qemu:///system");
+ virConnectPtr conn = virConnectOpen(driver->privileged ?
+ "qemu:///system" :
+ "qemu:///session");
/* Ignoring NULL conn which is mostly harmless here */
qemuDriverLock(driver);
* Initialization function for the QEmu daemon
*/
static int
-qemudStartup(void) {
- uid_t uid = geteuid();
+qemudStartup(int privileged) {
char *base = NULL;
char driverConf[PATH_MAX];
return -1;
}
qemuDriverLock(qemu_driver);
+ qemu_driver->privileged = privileged;
/* Don't have a dom0 so start from 1 */
qemu_driver->nextvmid = 1;
virEventAddTimeout(-1, qemuDomainEventFlush, qemu_driver, NULL)) < 0)
goto error;
- if (!uid) {
+ if (privileged) {
if (virAsprintf(&qemu_driver->logDir,
"%s/log/libvirt/qemu", LOCAL_STATE_DIR) == -1)
goto out_of_memory;
"%s/run/libvirt/qemu/", LOCAL_STATE_DIR) == -1)
goto out_of_memory;
} else {
+ uid_t uid = geteuid();
char *userdir = virGetUserDirectory(NULL, uid);
if (!userdir)
goto error;
goto cleanup;
}
- if ((logfile = qemudLogFD(conn, driver->logDir, vm->def->name)) < 0)
+ if ((logfile = qemudLogFD(conn, driver, vm->def->name)) < 0)
goto cleanup;
emulator = vm->def->emulator;
static virDrvOpenStatus qemudOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
int flags ATTRIBUTE_UNUSED) {
- uid_t uid = getuid();
-
if (conn->uri == NULL) {
if (qemu_driver == NULL)
return VIR_DRV_OPEN_DECLINED;
- conn->uri = xmlParseURI(uid == 0 ?
+ conn->uri = xmlParseURI(qemu_driver->privileged ?
"qemu:///system" :
"qemu:///session");
if (!conn->uri) {
if (conn->uri->server != NULL)
return VIR_DRV_OPEN_DECLINED;
- if (!uid) {
+ if (qemu_driver->privileged) {
if (STRNEQ (conn->uri->path, "/system") &&
STRNEQ (conn->uri->path, "/session")) {
qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
#ifdef WITH_LIBVIRTD
static int
-remoteStartup(void)
+remoteStartup(int privileged ATTRIBUTE_UNUSED)
{
/* Mark that we're inside the daemon so we can avoid
* re-entering ourselves
* Initialization function for the QEmu daemon
*/
static int
-storageDriverStartup(void) {
- uid_t uid = geteuid();
+storageDriverStartup(int privileged) {
char *base = NULL;
char driverConf[PATH_MAX];
}
storageDriverLock(driverState);
- if (!uid) {
+ if (privileged) {
if ((base = strdup (SYSCONF_DIR "/libvirt")) == NULL)
goto out_of_memory;
} else {
+ uid_t uid = geteuid();
char *userdir = virGetUserDirectory(NULL, uid);
if (!userdir)
struct uml_driver {
virMutex lock;
+ int privileged;
+
unsigned int umlVersion;
int nextvmid;
* to lookup the bridge associated with a virtual
* network
*/
- virConnectPtr conn = virConnectOpen(getuid() ?
- "uml:///session" :
- "uml:///system");
+ virConnectPtr conn = virConnectOpen(driver->privileged ?
+ "uml:///system" :
+ "uml:///session");
/* Ignoring NULL conn which is mostly harmless here */
for (i = 0 ; i < driver->domains.count ; i++) {
* Initialization function for the Uml daemon
*/
static int
-umlStartup(void) {
+umlStartup(int privileged) {
uid_t uid = geteuid();
char *base = NULL;
char driverConf[PATH_MAX];
if (VIR_ALLOC(uml_driver) < 0)
return -1;
+ uml_driver->privileged = privileged;
+
if (virMutexInit(¨_driver->lock) < 0) {
VIR_FREE(uml_driver);
return -1;
if (!userdir)
goto error;
- if (!uid) {
+ if (privileged) {
if (virAsprintf(¨_driver->logDir,
"%s/log/libvirt/uml", LOCAL_STATE_DIR) == -1)
goto out_of_memory;
static virDrvOpenStatus umlOpen(virConnectPtr conn,
virConnectAuthPtr auth ATTRIBUTE_UNUSED,
int flags ATTRIBUTE_UNUSED) {
- uid_t uid = getuid();
-
if (conn->uri == NULL) {
if (uml_driver == NULL)
return VIR_DRV_OPEN_DECLINED;
- conn->uri = xmlParseURI(uid == 0 ?
+ conn->uri = xmlParseURI(uml_driver->privileged ?
"uml:///system" :
"uml:///session");
if (!conn->uri) {
/* Check path and tell them correct path if they made a mistake */
- if (uid == 0) {
+ if (uml_driver->privileged) {
if (STRNEQ (conn->uri->path, "/system") &&
STRNEQ (conn->uri->path, "/session")) {
umlReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
#ifdef __sun
return priv_ineffect (PRIV_XVM_CONTROL);
#else
- return getuid () == 0;
+ return access(XEN_HYPERVISOR_SOCKET, R_OK) == 0;
#endif
}
#ifdef WITH_LIBVIRTD
static int
-xenInitialize (void)
+xenInitialize (int privileged ATTRIBUTE_UNUSED)
{
inside_daemon = 1;
return 0;