Don't do polkit auth as root
This commit is contained in:
parent
bca27d9111
commit
1e65165c3a
400
libvirt-0.4.1-polkit.patch
Normal file
400
libvirt-0.4.1-polkit.patch
Normal file
@ -0,0 +1,400 @@
|
||||
diff -rup libvirt-0.4.1.orig/configure.in libvirt-0.4.1.new/configure.in
|
||||
--- libvirt-0.4.1.orig/configure.in 2008-03-03 09:14:19.000000000 -0500
|
||||
+++ libvirt-0.4.1.new/configure.in 2008-04-03 15:37:49.000000000 -0400
|
||||
@@ -450,10 +450,6 @@ if test "x$with_polkit" = "xyes" -o "x$w
|
||||
CFLAGS="$old_CFLAGS"
|
||||
LDFLAGS="$old_LDFLAGS"
|
||||
|
||||
- AC_PATH_PROG(POLKIT_GRANT, polkit-grant)
|
||||
- if test "x$POLKIT_GRANT" != "x"; then
|
||||
- AC_DEFINE_UNQUOTED([POLKIT_GRANT],["$POLKIT_GRANT"],[Location of polkit-grant program])
|
||||
- fi
|
||||
AC_PATH_PROG(POLKIT_AUTH, polkit-auth)
|
||||
if test "x$POLKIT_AUTH" != "x"; then
|
||||
AC_DEFINE_UNQUOTED([POLKIT_AUTH],["$POLKIT_AUTH"],[Location of polkit-auth program])
|
||||
diff -rup libvirt-0.4.1.orig/qemud/internal.h libvirt-0.4.1.new/qemud/internal.h
|
||||
--- libvirt-0.4.1.orig/qemud/internal.h 2008-01-24 12:07:43.000000000 -0500
|
||||
+++ libvirt-0.4.1.new/qemud/internal.h 2008-04-03 15:38:03.000000000 -0400
|
||||
@@ -179,6 +179,9 @@ void qemudLog(int priority, const char *
|
||||
void remoteDispatchClientRequest (struct qemud_server *server,
|
||||
struct qemud_client *client);
|
||||
|
||||
+#if HAVE_POLKIT
|
||||
+int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid);
|
||||
+#endif
|
||||
|
||||
#endif
|
||||
|
||||
diff -rup libvirt-0.4.1.orig/qemud/qemud.c libvirt-0.4.1.new/qemud/qemud.c
|
||||
--- libvirt-0.4.1.orig/qemud/qemud.c 2008-04-03 15:39:15.000000000 -0400
|
||||
+++ libvirt-0.4.1.new/qemud/qemud.c 2008-04-03 15:38:03.000000000 -0400
|
||||
@@ -1040,6 +1040,28 @@ remoteCheckAccess (struct qemud_client *
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#if HAVE_POLKIT
|
||||
+int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid) {
|
||||
+#ifdef SO_PEERCRED
|
||||
+ struct ucred cr;
|
||||
+ unsigned int cr_len = sizeof (cr);
|
||||
+
|
||||
+ if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) < 0) {
|
||||
+ qemudLog(QEMUD_ERR, _("Failed to verify client credentials: %s"),
|
||||
+ strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ *pid = cr.pid;
|
||||
+ *uid = cr.uid;
|
||||
+#else
|
||||
+ /* XXX Many more OS support UNIX socket credentials we could port to. See dbus ....*/
|
||||
+#error "UNIX socket credentials not supported/implemented on this platform yet..."
|
||||
+#endif
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static int qemudDispatchServer(struct qemud_server *server, struct qemud_socket *sock) {
|
||||
int fd;
|
||||
struct sockaddr_storage addr;
|
||||
@@ -1075,6 +1097,26 @@ static int qemudDispatchServer(struct qe
|
||||
memcpy (&client->addr, &addr, sizeof addr);
|
||||
client->addrlen = addrlen;
|
||||
|
||||
+#if HAVE_POLKIT
|
||||
+ /* Only do policy checks for non-root - allow root user
|
||||
+ through with no checks, as a fail-safe - root can easily
|
||||
+ change policykit policy anyway, so its pointless trying
|
||||
+ to restrict root */
|
||||
+ if (client->auth == REMOTE_AUTH_POLKIT) {
|
||||
+ uid_t uid;
|
||||
+ pid_t pid;
|
||||
+
|
||||
+ if (qemudGetSocketIdentity(client->fd, &uid, &pid) < 0)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ /* Cient is running as root, so disable auth */
|
||||
+ if (uid == 0) {
|
||||
+ qemudLog(QEMUD_INFO, _("Turn off polkit auth for privileged client %d"), pid);
|
||||
+ client->auth = REMOTE_AUTH_NONE;
|
||||
+ }
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (client->type != QEMUD_SOCK_TYPE_TLS) {
|
||||
client->mode = QEMUD_MODE_RX_HEADER;
|
||||
client->bufferLength = REMOTE_MESSAGE_HEADER_XDR_LEN;
|
||||
diff -rup libvirt-0.4.1.orig/qemud/remote.c libvirt-0.4.1.new/qemud/remote.c
|
||||
--- libvirt-0.4.1.orig/qemud/remote.c 2008-02-29 11:23:17.000000000 -0500
|
||||
+++ libvirt-0.4.1.new/qemud/remote.c 2008-04-03 15:38:03.000000000 -0400
|
||||
@@ -2564,27 +2564,6 @@ remoteDispatchAuthSaslStep (struct qemud
|
||||
|
||||
|
||||
#if HAVE_POLKIT
|
||||
-static int qemudGetSocketIdentity(int fd, uid_t *uid, pid_t *pid) {
|
||||
-#ifdef SO_PEERCRED
|
||||
- struct ucred cr;
|
||||
- unsigned int cr_len = sizeof (cr);
|
||||
-
|
||||
- if (getsockopt (fd, SOL_SOCKET, SO_PEERCRED, &cr, &cr_len) < 0) {
|
||||
- qemudLog(QEMUD_ERR, _("Failed to verify client credentials: %s"),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- *pid = cr.pid;
|
||||
- *uid = cr.uid;
|
||||
-#else
|
||||
- /* XXX Many more OS support UNIX socket credentials we could port to. See dbus ....*/
|
||||
-#error "UNIX socket credentials not supported/implemented on this platform yet..."
|
||||
-#endif
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-
|
||||
static int
|
||||
remoteDispatchAuthPolkit (struct qemud_server *server ATTRIBUTE_UNUSED,
|
||||
struct qemud_client *client,
|
||||
@@ -2594,6 +2573,15 @@ remoteDispatchAuthPolkit (struct qemud_s
|
||||
{
|
||||
pid_t callerPid;
|
||||
uid_t callerUid;
|
||||
+ PolKitCaller *pkcaller = NULL;
|
||||
+ PolKitAction *pkaction = NULL;
|
||||
+ PolKitContext *pkcontext = NULL;
|
||||
+ PolKitError *pkerr = NULL;
|
||||
+ PolKitResult pkresult;
|
||||
+ DBusError err;
|
||||
+ const char *action = client->readonly ?
|
||||
+ "org.libvirt.unix.monitor" :
|
||||
+ "org.libvirt.unix.manage";
|
||||
|
||||
REMOTE_DEBUG("Start PolicyKit auth %d", client->fd);
|
||||
if (client->auth != REMOTE_AUTH_POLKIT) {
|
||||
@@ -2609,98 +2597,78 @@ remoteDispatchAuthPolkit (struct qemud_s
|
||||
return -2;
|
||||
}
|
||||
|
||||
- /* Only do policy checks for non-root - allow root user
|
||||
- through with no checks, as a fail-safe - root can easily
|
||||
- change policykit policy anyway, so its pointless trying
|
||||
- to restrict root */
|
||||
- if (callerUid == 0) {
|
||||
- qemudLog(QEMUD_INFO, _("Allowing PID %d running as root"), callerPid);
|
||||
- ret->complete = 1;
|
||||
- client->auth = REMOTE_AUTH_NONE;
|
||||
- } else {
|
||||
- PolKitCaller *pkcaller = NULL;
|
||||
- PolKitAction *pkaction = NULL;
|
||||
- PolKitContext *pkcontext = NULL;
|
||||
- PolKitError *pkerr = NULL;
|
||||
- PolKitResult pkresult;
|
||||
- DBusError err;
|
||||
- const char *action = client->readonly ?
|
||||
- "org.libvirt.unix.monitor" :
|
||||
- "org.libvirt.unix.manage";
|
||||
-
|
||||
- qemudLog(QEMUD_INFO, _("Checking PID %d running as %d"),
|
||||
- callerPid, callerUid);
|
||||
- dbus_error_init(&err);
|
||||
- if (!(pkcaller = polkit_caller_new_from_pid(server->sysbus,
|
||||
- callerPid, &err))) {
|
||||
- qemudLog(QEMUD_ERR, _("Failed to lookup policy kit caller: %s"),
|
||||
- err.message);
|
||||
- dbus_error_free(&err);
|
||||
- remoteDispatchFailAuth(client, req);
|
||||
- return -2;
|
||||
- }
|
||||
-
|
||||
- if (!(pkaction = polkit_action_new())) {
|
||||
- qemudLog(QEMUD_ERR, _("Failed to create polkit action %s\n"),
|
||||
- strerror(errno));
|
||||
- polkit_caller_unref(pkcaller);
|
||||
- remoteDispatchFailAuth(client, req);
|
||||
- return -2;
|
||||
- }
|
||||
- polkit_action_set_action_id(pkaction, action);
|
||||
-
|
||||
- if (!(pkcontext = polkit_context_new()) ||
|
||||
- !polkit_context_init(pkcontext, &pkerr)) {
|
||||
- qemudLog(QEMUD_ERR, _("Failed to create polkit context %s\n"),
|
||||
- (pkerr ? polkit_error_get_error_message(pkerr)
|
||||
- : strerror(errno)));
|
||||
- if (pkerr)
|
||||
- polkit_error_free(pkerr);
|
||||
- polkit_caller_unref(pkcaller);
|
||||
- polkit_action_unref(pkaction);
|
||||
- dbus_error_free(&err);
|
||||
- remoteDispatchFailAuth(client, req);
|
||||
- return -2;
|
||||
- }
|
||||
+ qemudLog(QEMUD_INFO, _("Checking PID %d running as %d"),
|
||||
+ callerPid, callerUid);
|
||||
+ dbus_error_init(&err);
|
||||
+ if (!(pkcaller = polkit_caller_new_from_pid(server->sysbus,
|
||||
+ callerPid, &err))) {
|
||||
+ qemudLog(QEMUD_ERR, _("Failed to lookup policy kit caller: %s"),
|
||||
+ err.message);
|
||||
+ dbus_error_free(&err);
|
||||
+ remoteDispatchFailAuth(client, req);
|
||||
+ return -2;
|
||||
+ }
|
||||
+
|
||||
+ if (!(pkaction = polkit_action_new())) {
|
||||
+ qemudLog(QEMUD_ERR, _("Failed to create polkit action %s\n"),
|
||||
+ strerror(errno));
|
||||
+ polkit_caller_unref(pkcaller);
|
||||
+ remoteDispatchFailAuth(client, req);
|
||||
+ return -2;
|
||||
+ }
|
||||
+ polkit_action_set_action_id(pkaction, action);
|
||||
+
|
||||
+ if (!(pkcontext = polkit_context_new()) ||
|
||||
+ !polkit_context_init(pkcontext, &pkerr)) {
|
||||
+ qemudLog(QEMUD_ERR, _("Failed to create polkit context %s\n"),
|
||||
+ (pkerr ? polkit_error_get_error_message(pkerr)
|
||||
+ : strerror(errno)));
|
||||
+ if (pkerr)
|
||||
+ polkit_error_free(pkerr);
|
||||
+ polkit_caller_unref(pkcaller);
|
||||
+ polkit_action_unref(pkaction);
|
||||
+ dbus_error_free(&err);
|
||||
+ remoteDispatchFailAuth(client, req);
|
||||
+ return -2;
|
||||
+ }
|
||||
|
||||
#if HAVE_POLKIT_CONTEXT_IS_CALLER_AUTHORIZED
|
||||
- pkresult = polkit_context_is_caller_authorized(pkcontext,
|
||||
- pkaction,
|
||||
- pkcaller,
|
||||
- 0,
|
||||
- &pkerr);
|
||||
- if (pkerr && polkit_error_is_set(pkerr)) {
|
||||
- qemudLog(QEMUD_ERR,
|
||||
- _("Policy kit failed to check authorization %d %s"),
|
||||
- polkit_error_get_error_code(pkerr),
|
||||
- polkit_error_get_error_message(pkerr));
|
||||
- remoteDispatchFailAuth(client, req);
|
||||
- return -2;
|
||||
- }
|
||||
+ pkresult = polkit_context_is_caller_authorized(pkcontext,
|
||||
+ pkaction,
|
||||
+ pkcaller,
|
||||
+ 0,
|
||||
+ &pkerr);
|
||||
+ if (pkerr && polkit_error_is_set(pkerr)) {
|
||||
+ qemudLog(QEMUD_ERR,
|
||||
+ _("Policy kit failed to check authorization %d %s"),
|
||||
+ polkit_error_get_error_code(pkerr),
|
||||
+ polkit_error_get_error_message(pkerr));
|
||||
+ remoteDispatchFailAuth(client, req);
|
||||
+ return -2;
|
||||
+ }
|
||||
#else
|
||||
- pkresult = polkit_context_can_caller_do_action(pkcontext,
|
||||
- pkaction,
|
||||
- pkcaller);
|
||||
+ pkresult = polkit_context_can_caller_do_action(pkcontext,
|
||||
+ pkaction,
|
||||
+ pkcaller);
|
||||
#endif
|
||||
- polkit_context_unref(pkcontext);
|
||||
- polkit_caller_unref(pkcaller);
|
||||
- polkit_action_unref(pkaction);
|
||||
- if (pkresult != POLKIT_RESULT_YES) {
|
||||
- qemudLog(QEMUD_ERR,
|
||||
- _("Policy kit denied action %s from pid %d, uid %d,"
|
||||
- " result: %s\n"),
|
||||
- action, callerPid, callerUid,
|
||||
- polkit_result_to_string_representation(pkresult));
|
||||
- remoteDispatchFailAuth(client, req);
|
||||
- return -2;
|
||||
- }
|
||||
- qemudLog(QEMUD_INFO,
|
||||
- _("Policy allowed action %s from pid %d, uid %d, result %s"),
|
||||
+ polkit_context_unref(pkcontext);
|
||||
+ polkit_caller_unref(pkcaller);
|
||||
+ polkit_action_unref(pkaction);
|
||||
+ if (pkresult != POLKIT_RESULT_YES) {
|
||||
+ qemudLog(QEMUD_ERR,
|
||||
+ _("Policy kit denied action %s from pid %d, uid %d,"
|
||||
+ " result: %s\n"),
|
||||
action, callerPid, callerUid,
|
||||
polkit_result_to_string_representation(pkresult));
|
||||
- ret->complete = 1;
|
||||
- client->auth = REMOTE_AUTH_NONE;
|
||||
+ remoteDispatchFailAuth(client, req);
|
||||
+ return -2;
|
||||
}
|
||||
+ qemudLog(QEMUD_INFO,
|
||||
+ _("Policy allowed action %s from pid %d, uid %d, result %s"),
|
||||
+ action, callerPid, callerUid,
|
||||
+ polkit_result_to_string_representation(pkresult));
|
||||
+ ret->complete = 1;
|
||||
+ client->auth = REMOTE_AUTH_NONE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff -rup libvirt-0.4.1.orig/src/libvirt.c libvirt-0.4.1.new/src/libvirt.c
|
||||
--- libvirt-0.4.1.orig/src/libvirt.c 2008-02-26 10:37:43.000000000 -0500
|
||||
+++ libvirt-0.4.1.new/src/libvirt.c 2008-04-03 15:38:47.000000000 -0400
|
||||
@@ -19,6 +19,9 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
+#ifdef HAVE_SYS_WAIT_H
|
||||
+#include <sys/wait.h>
|
||||
+#endif
|
||||
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/xpath.h>
|
||||
@@ -66,6 +69,39 @@ static int initialized = 0;
|
||||
int debugFlag = 0;
|
||||
#endif
|
||||
|
||||
+#if defined(POLKIT_AUTH)
|
||||
+static int virConnectAuthGainPolkit(const char *privilege) {
|
||||
+ const char *const args[] = {
|
||||
+ POLKIT_AUTH, "--obtain", privilege, NULL
|
||||
+ };
|
||||
+ int childpid, status, ret;
|
||||
+
|
||||
+ /* Root has all rights */
|
||||
+ if (getuid() == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ if ((childpid = fork()) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ if (!childpid) {
|
||||
+ execvp(args[0], (char **)args);
|
||||
+ _exit(-1);
|
||||
+ }
|
||||
+
|
||||
+ while ((ret = waitpid(childpid, &status, 0) == -1) && errno == EINTR);
|
||||
+ if (ret == -1) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ if (!WIFEXITED(status) ||
|
||||
+ (WEXITSTATUS(status) != 0 && WEXITSTATUS(status) != 1)) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
static int virConnectAuthCallbackDefault(virConnectCredentialPtr cred,
|
||||
unsigned int ncred,
|
||||
void *cbdata ATTRIBUTE_UNUSED) {
|
||||
@@ -77,28 +113,25 @@ static int virConnectAuthCallbackDefault
|
||||
size_t len;
|
||||
|
||||
switch (cred[i].type) {
|
||||
-#if defined(POLKIT_GRANT) || defined(POLKIT_AUTH)
|
||||
case VIR_CRED_EXTERNAL: {
|
||||
int ret;
|
||||
- const char *const args[] = {
|
||||
-#if defined(POLKIT_GRANT)
|
||||
- POLKIT_GRANT, "--gain", cred[i].prompt, NULL
|
||||
-#else
|
||||
- POLKIT_AUTH, "--obtain", cred[i].prompt, NULL
|
||||
-#endif
|
||||
- };
|
||||
-
|
||||
if (STRNEQ(cred[i].challenge, "PolicyKit"))
|
||||
return -1;
|
||||
- if (virRun(NULL, (char **) args, &ret) < 0)
|
||||
- return -1;
|
||||
|
||||
- if (!WIFEXITED(ret) ||
|
||||
- (WEXITSTATUS(ret) != 0 && WEXITSTATUS(ret) != 1))
|
||||
+#if defined(POLKIT_AUTH)
|
||||
+ if (virConnectAuthGainPolkit(cred[i].prompt) < 0)
|
||||
return -1;
|
||||
+#else
|
||||
+ /*
|
||||
+ * Ignore & carry on. Although we can't auth
|
||||
+ * directly, the user may have authenticated
|
||||
+ * themselves already outside context of libvirt
|
||||
+ */
|
||||
+#endif
|
||||
+
|
||||
break;
|
||||
}
|
||||
-#endif
|
||||
+
|
||||
case VIR_CRED_USERNAME:
|
||||
case VIR_CRED_AUTHNAME:
|
||||
case VIR_CRED_ECHOPROMPT:
|
||||
@@ -158,9 +191,7 @@ static int virConnectCredTypeDefault[] =
|
||||
VIR_CRED_REALM,
|
||||
VIR_CRED_PASSPHRASE,
|
||||
VIR_CRED_NOECHOPROMPT,
|
||||
-#if defined(POLKIT_AUTH) || defined(POLKIT_GRANT)
|
||||
VIR_CRED_EXTERNAL,
|
||||
-#endif
|
||||
};
|
||||
|
||||
static virConnectAuth virConnectAuthDefault = {
|
@ -21,7 +21,7 @@
|
||||
Summary: Library providing a simple API virtualization
|
||||
Name: libvirt
|
||||
Version: 0.4.1
|
||||
Release: 6%{?dist}%{?extra_release}
|
||||
Release: 7%{?dist}%{?extra_release}
|
||||
License: LGPL
|
||||
Group: Development/Libraries
|
||||
Source: libvirt-%{version}.tar.gz
|
||||
@ -34,6 +34,7 @@ Patch5: %{name}-%{version}-tap-ifname.patch
|
||||
Patch6: libvirt-storage-api-iscsi-sendtarget.patch
|
||||
Patch7: libvirt-iscsi-sysfs4.patch
|
||||
Patch8: libvirt-source-dir-fix.patch
|
||||
Patch9: %{name}-%{version}-polkit.patch
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||
URL: http://libvirt.org/
|
||||
BuildRequires: python python-devel
|
||||
@ -154,6 +155,7 @@ of recent versions of Linux (and other OSes).
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
%patch9 -p1
|
||||
|
||||
%build
|
||||
# Xen is available only on i386 x86_64 ia64
|
||||
@ -297,6 +299,10 @@ fi
|
||||
%doc docs/examples/python
|
||||
|
||||
%changelog
|
||||
* Thu Apr 4 2008 Daniel P. Berrange <berrange@redhat.com> - 0.4.1-7.fc9
|
||||
- Don't run polkit-auth as root
|
||||
- Don't request polkit auth if client is root
|
||||
|
||||
* Fri Mar 28 2008 Chris Lalancette <clalance@redhat.com> - 0.4.1-6.fc9
|
||||
- When dumping XML for a storage pool, make the <source> directory tag
|
||||
match the <dir> tag used for specifying the pool in the first place
|
||||
|
Loading…
Reference in New Issue
Block a user