From: "Daniel P. Berrange" <berra...@redhat.com> --- po/POTFILES.in | 1 + src/Makefile.am | 12 ++- src/access/org.libvirt.domain.policy | 37 ++++++++ src/access/viraccessdriverpolkit.c | 163 ++++++++++++++++++++++++++++++++++ src/access/viraccessdriverpolkit.h | 28 ++++++ src/access/viraccessmanager.c | 2 + 6 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 src/access/org.libvirt.domain.policy create mode 100644 src/access/viraccessdriverpolkit.c create mode 100644 src/access/viraccessdriverpolkit.h
diff --git a/po/POTFILES.in b/po/POTFILES.in index 0a5443f..0548479 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -4,6 +4,7 @@ daemon/remote.c daemon/remote_dispatch.h daemon/stream.c gnulib/lib/gai_strerror.c +src/access/viraccessdriverpolkit.c src/access/viraccessmanager.c src/conf/cpu_conf.c src/conf/domain_conf.c diff --git a/src/Makefile.am b/src/Makefile.am index 0baa17d..ebc8301 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -523,7 +523,12 @@ ACCESS_DRIVER_SOURCES = \ access/viraccessmanager.h access/viraccessmanager.c \ access/viraccessdriver.h \ access/viraccessdrivernop.h access/viraccessdrivernop.c \ - access/viraccessdriverstack.h access/viraccessdriverstack.c + access/viraccessdriverstack.h access/viraccessdriverstack.c \ + access/viraccessdriverpolkit.h access/viraccessdriverpolkit.c + +ACCESS_DRIVER_POLKIT_POLICY = \ + access/org.libvirt.domain.policy + NODE_DEVICE_DRIVER_SOURCES = \ node_device/node_device_driver.c \ @@ -1116,6 +1121,8 @@ libvirt_driver_access_la_CFLAGS = \ libvirt_driver_access_la_LDFLAGS = $(AM_LDFLAGS) libvirt_driver_access_la_LIBADD = +polkitactiondir = $(datadir)/polkit-1/actions +polkitaction_DATA = $(ACCESS_DRIVER_POLKIT_POLICY) # Add all conditional sources just in case... EXTRA_DIST += \ @@ -1152,7 +1159,8 @@ EXTRA_DIST += \ $(SECRET_DRIVER_SOURCES) \ $(VBOX_DRIVER_EXTRA_DIST) \ $(VMWARE_DRIVER_SOURCES) \ - $(XENXS_SOURCES) + $(XENXS_SOURCES) \ + $(ACCESS_DRIVER_POLKIT_POLICY) check-local: augeas-check diff --git a/src/access/org.libvirt.domain.policy b/src/access/org.libvirt.domain.policy new file mode 100644 index 0000000..a8ebd84 --- /dev/null +++ b/src/access/org.libvirt.domain.policy @@ -0,0 +1,37 @@ +<!DOCTYPE policyconfig PUBLIC + "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN" + "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd"> + +<!-- +Policy definitions for libvirt daemon + +Copyright (c) 2007 Daniel P. Berrange <berrange redhat com> + +libvirt is licensed to you under the GNU Lesser General Public License +version 2. See COPYING for details. + +NOTE: If you make changes to this file, make sure to validate the file +using the polkit-policy-file-validate(1) tool. Changes made to this +file are instantly applied. +--> + +<policyconfig> + <action id="org.libvirt.domain.getattr"> + <description>Get virtual domain attributes</description> + <message>System policy prevents getattr on guest domains</message> + <defaults> + <allow_any>yes</allow_any> + <allow_inactive>yes</allow_inactive> + <allow_active>yes</allow_active> + </defaults> + </action> + <action id="org.libvirt.domain.read"> + <description>Get virtual domain attributes</description> + <message>System policy prevents getattr on guest domains</message> + <defaults> + <allow_any>yes</allow_any> + <allow_inactive>yes</allow_inactive> + <allow_active>yes</allow_active> + </defaults> + </action> +</policyconfig> diff --git a/src/access/viraccessdriverpolkit.c b/src/access/viraccessdriverpolkit.c new file mode 100644 index 0000000..d330653 --- /dev/null +++ b/src/access/viraccessdriverpolkit.c @@ -0,0 +1,163 @@ +/* + * viraccessdriverpolkit.c: polkited access control driver + * + * Copyright (C) 2012 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <config.h> + +#include "access/viraccessdriverpolkit.h" +#include "memory.h" +#include "command.h" +#include "logging.h" +#include "virterror_internal.h" + +#define VIR_FROM_THIS VIR_FROM_ACCESS +#define virAccessError(code, ...) \ + virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \ + __FUNCTION__, __LINE__, __VA_ARGS__) + +#define VIR_ACCESS_DRIVER_POLKIT_ACTION_PREFIX "org.libvirt" + +typedef struct _virAccessDriverPolkitPrivate virAccessDriverPolkitPrivate; +typedef virAccessDriverPolkitPrivate *virAccessDriverPolkitPrivatePtr; + +struct _virAccessDriverPolkitPrivate { + bool ignore; +}; + + +static void virAccessDriverPolkitCleanup(virAccessManagerPtr manager ATTRIBUTE_UNUSED) +{ +} + + +static char * +virAccessDriverPolkitFormatAction(const char *typename, + const char *avname) +{ + char *actionid = NULL; + + if (virAsprintf(&actionid, "%s.%s.%s", + VIR_ACCESS_DRIVER_POLKIT_ACTION_PREFIX, + typename, avname) < 0) { + virReportOOMError(); + return NULL; + } + + return actionid; +} + + +static char * +virAccessDriverPolkitFormatProcess(void) +{ + virIdentityPtr identity = virAccessManagerGetEffectiveIdentity(); + const char *process = NULL; + char *ret = NULL; + + if (!identity) { + virAccessError(VIR_ERR_INTERNAL_ERROR, "%s", + _("No identity available")); + return NULL; + } + if (virIdentityGetAttr(identity, VIR_IDENTITY_ATTR_UNIX_PROCESS_ID, &process) < 0) + goto cleanup; + + if (!process) { + virAccessError(VIR_ERR_INTERNAL_ERROR, "%s", + _("No UNIX process ID available")); + goto cleanup; + } + + if (!(ret = strdup(process))) { + virReportOOMError(); + goto cleanup; + } +cleanup: + virIdentityFree(identity); + return ret; +} + + +static bool +virAccessDriverPolkitCheck(virAccessManagerPtr manager ATTRIBUTE_UNUSED, + const char *typename, + const char *avname) +{ + char *actionid = virAccessDriverPolkitFormatAction(typename, avname); + char *process = virAccessDriverPolkitFormatProcess(); + virCommandPtr cmd; + int status; + int ret = false; + + if (!actionid || !process) + goto cleanup; + + cmd = virCommandNewArgList(PKCHECK_PATH, + "--action-id", actionid, + "--process", process, + NULL); + + if (virCommandRun(cmd, &status) < 0) + goto cleanup; + + if (status != 0) { + char *tmp = virCommandTranslateStatus(status); + virAccessError(VIR_ERR_ACCESS_DENIED, + _("Policy kit denied action %s from %s: %s"), + actionid, process, NULLSTR(tmp)); + VIR_FREE(tmp); + goto cleanup; + } + + ret = true; + +cleanup: + VIR_FREE(actionid); + VIR_FREE(process); + return ret; +} + + +static bool +virAccessDriverPolkitCheckConnect(virAccessManagerPtr manager, + virAccessVectorConnect av) +{ + return virAccessDriverPolkitCheck(manager, + "connect", + virAccessVectorConnectTypeToString(av)); +} + + +static bool +virAccessDriverPolkitCheckDomain(virAccessManagerPtr manager, + virDomainDefPtr def ATTRIBUTE_UNUSED, + virAccessVectorDomain av) +{ + return virAccessDriverPolkitCheck(manager, + "domain", + virAccessVectorDomainTypeToString(av)); +} + + +virAccessDriver accessDriverPolkit = { + .name = "polkit", + .cleanup = virAccessDriverPolkitCleanup, + .checkConnect = virAccessDriverPolkitCheckConnect, + .checkDomain = virAccessDriverPolkitCheckDomain, +}; diff --git a/src/access/viraccessdriverpolkit.h b/src/access/viraccessdriverpolkit.h new file mode 100644 index 0000000..ac71fa5 --- /dev/null +++ b/src/access/viraccessdriverpolkit.h @@ -0,0 +1,28 @@ +/* + * viraccessdriverpolkit.h: polkited access control driver + * + * Copyright (C) 2012 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 + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __VIR_ACCESS_DRIVER_POLKIT_H__ +# define __VIR_ACCESS_DRIVER_POLKIT_H__ + +# include "access/viraccessdriver.h" + +extern virAccessDriver accessDriverPolkit; + +#endif /* __VIR_ACCESS_DRIVER_POLKIT_H__ */ diff --git a/src/access/viraccessmanager.c b/src/access/viraccessmanager.c index 5bb4404..4698a4f 100644 --- a/src/access/viraccessmanager.c +++ b/src/access/viraccessmanager.c @@ -29,6 +29,7 @@ #endif #include "access/viraccessdrivernop.h" #include "access/viraccessdriverstack.h" +#include "access/viraccessdriverpolkit.h" #include "logging.h" #define VIR_FROM_THIS VIR_FROM_ACCESS @@ -206,6 +207,7 @@ static virAccessManagerPtr virAccessManagerNewDriver(virAccessDriverPtr drv) static virAccessDriverPtr accessDrivers[] = { &accessDriverNop, + &accessDriverPolkit, }; -- 1.7.7.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list