This should be applied to libvirt-0.4.0. It is a bit old one, sorry, but this patch is just hooking around. So I think I can merge it to latest libvirt with a little effort. Please note that uid is essential for access control and the uid is available only in a local machine. For this reason, our access control takes effect only in a local machine by virsh. This means that remotely connecting to libvirtd is currently out of scope.
diff -r d5dbadfb6161 -r 62d2ebb8d23b configure --- a/configure Wed Apr 02 13:13:06 2008 +0900 +++ b/configure Tue Jan 27 03:13:46 2009 +0900 @@ -35181,7 +35181,12 @@ sysconfdir='/etc' fi - +# Check whether --with-rbac was given. +if test "${with_rbac+set}" = set; then + withval=$with_rbac; +else + with_rbac=no +fi # Check whether --with-xen was given. if test "${with_xen+set}" = set; then @@ -39753,6 +39758,9 @@ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H +if test "$with_rbac" = "yes" ; then + DEFS="$DEFS -DRBAC" +fi ac_libobjs= ac_ltlibobjs= @@ -41743,6 +41751,9 @@ { echo "$as_me:$LINENO: polkit: no" >&5 echo "$as_me: polkit: no" >&6;} fi +{ echo "$as_me:$LINENO: RBAC: $with_rbac" >&5 +echo "$as_me: RBAC: $with_rbac" >&6;} + { echo "$as_me:$LINENO: " >&5 echo "$as_me: " >&6;} { echo "$as_me:$LINENO: Miscellaneous" >&5 diff -r d5dbadfb6161 -r 62d2ebb8d23b include/libvirt/libvirt.h --- a/include/libvirt/libvirt.h Wed Apr 02 13:13:06 2008 +0900 +++ b/include/libvirt/libvirt.h Tue Jan 27 03:13:46 2009 +0900 @@ -514,6 +514,11 @@ char * virDomainGetXMLDesc (virDomainPtr domain, int flags); +#ifdef RBAC +char * virDomainGetXMLDesc_XRBAC (int op_id, + virDomainPtr domain, + int flags); +#endif int virDomainBlockStats (virDomainPtr dom, const char *path, virDomainBlockStatsPtr stats, @@ -697,6 +702,11 @@ char **const names, int maxnames); +#ifdef RBAC +int virConnectListNetworks_QEMUD (virConnectPtr conn, + char **const names, + int maxnames); +#endif /* * List inactive networks */ @@ -705,6 +715,11 @@ char **const names, int maxnames); +#ifdef RBAC +int virConnectListDefinedNetworks_QEMUD (virConnectPtr conn, + char **const names, + int maxnames); +#endif /* * Lookup network by name or uuid */ @@ -721,26 +736,43 @@ virNetworkPtr virNetworkCreateXML (virConnectPtr conn, const char *xmlDesc); +#ifdef RBAC +virNetworkPtr virNetworkCreateXML_QEMUD (virConnectPtr conn, + const char *xmlDesc); +#endif /* * Define inactive persistent network */ virNetworkPtr virNetworkDefineXML (virConnectPtr conn, const char *xmlDesc); +#ifdef RBAC +virNetworkPtr virNetworkDefineXML_QEMUD (virConnectPtr conn, + const char *xml); +#endif /* * Delete persistent network */ int virNetworkUndefine (virNetworkPtr network); +#ifdef RBAC +int virNetworkUndefine_QEMUD (virNetworkPtr network); +#endif /* * Activate persistent network */ int virNetworkCreate (virNetworkPtr network); +#ifdef RBAC +int virNetworkCreate_QEMUD (virNetworkPtr network); +#endif /* * Network destroy/free */ int virNetworkDestroy (virNetworkPtr network); +#ifdef RBAC +int virNetworkDestroy_QEMUD (virNetworkPtr network); +#endif int virNetworkFree (virNetworkPtr network); /* @@ -753,12 +785,20 @@ char *buf); char * virNetworkGetXMLDesc (virNetworkPtr network, int flags); +#ifdef RBAC +char * virNetworkGetXMLDesc_QEMUD (virNetworkPtr network, + int flags); +#endif char * virNetworkGetBridgeName (virNetworkPtr network); int virNetworkGetAutostart (virNetworkPtr network, int *autostart); int virNetworkSetAutostart (virNetworkPtr network, int autostart); +#ifdef RBAC +int virNetworkSetAutostart_QEMUD (virNetworkPtr network, + int autostart); +#endif #ifdef __cplusplus } diff -r d5dbadfb6161 -r 62d2ebb8d23b include/libvirt/libvirt.h.in --- a/include/libvirt/libvirt.h.in Wed Apr 02 13:13:06 2008 +0900 +++ b/include/libvirt/libvirt.h.in Tue Jan 27 03:13:46 2009 +0900 @@ -514,6 +514,11 @@ char * virDomainGetXMLDesc (virDomainPtr domain, int flags); +#ifdef RBAC +char * virDomainGetXMLDesc_XRBAC (int op_id, + virDomainPtr domain, + int flags); +#endif int virDomainBlockStats (virDomainPtr dom, const char *path, virDomainBlockStatsPtr stats, @@ -697,6 +702,11 @@ char **const names, int maxnames); +#ifdef RBAC +int virConnectListNetworks_QEMUD (virConnectPtr conn, + char **const names, + int maxnames); +#endif /* * List inactive networks */ @@ -705,6 +715,11 @@ char **const names, int maxnames); +#ifdef RBAC +int virConnectListDefinedNetworks_QEMUD (virConnectPtr conn, + char **const names, + int maxnames); +#endif /* * Lookup network by name or uuid */ @@ -721,26 +736,43 @@ virNetworkPtr virNetworkCreateXML (virConnectPtr conn, const char *xmlDesc); +#ifdef RBAC +virNetworkPtr virNetworkCreateXML_QEMUD (virConnectPtr conn, + const char *xmlDesc); +#endif /* * Define inactive persistent network */ virNetworkPtr virNetworkDefineXML (virConnectPtr conn, const char *xmlDesc); +#ifdef RBAC +virNetworkPtr virNetworkDefineXML_QEMUD (virConnectPtr conn, + const char *xml); +#endif /* * Delete persistent network */ int virNetworkUndefine (virNetworkPtr network); +#ifdef RBAC +int virNetworkUndefine_QEMUD (virNetworkPtr network); +#endif /* * Activate persistent network */ int virNetworkCreate (virNetworkPtr network); +#ifdef RBAC +int virNetworkCreate_QEMUD (virNetworkPtr network); +#endif /* * Network destroy/free */ int virNetworkDestroy (virNetworkPtr network); +#ifdef RBAC +int virNetworkDestroy_QEMUD (virNetworkPtr network); +#endif int virNetworkFree (virNetworkPtr network); /* @@ -753,12 +785,20 @@ char *buf); char * virNetworkGetXMLDesc (virNetworkPtr network, int flags); +#ifdef RBAC +char * virNetworkGetXMLDesc_QEMUD (virNetworkPtr network, + int flags); +#endif char * virNetworkGetBridgeName (virNetworkPtr network); int virNetworkGetAutostart (virNetworkPtr network, int *autostart); int virNetworkSetAutostart (virNetworkPtr network, int autostart); +#ifdef RBAC +int virNetworkSetAutostart_QEMUD (virNetworkPtr network, + int autostart); +#endif #ifdef __cplusplus } diff -r d5dbadfb6161 -r 62d2ebb8d23b include/libvirt/virterror.h --- a/include/libvirt/virterror.h Wed Apr 02 13:13:06 2008 +0900 +++ b/include/libvirt/virterror.h Tue Jan 27 03:13:46 2009 +0900 @@ -54,6 +54,9 @@ VIR_FROM_OPENVZ, /* Error from OpenVZ driver */ VIR_FROM_XENXM, /* Error at Xen XM layer */ VIR_FROM_STATS_LINUX, /* Error in the Linux Stats code */ +#ifdef RBAC + VIR_FROM_XENRBAC, /* Error form Xen RBAC */ +#endif } virErrorDomain; @@ -132,6 +135,9 @@ VIR_ERR_NO_NETWORK, /* network not found */ VIR_ERR_INVALID_MAC, /* invalid MAC adress */ VIR_ERR_AUTH_FAILED, /* authentication failed */ +#ifdef RBAC + VIR_ERR_PERMISSION, /* operation not permitted */ +#endif } virErrorNumber; /** diff -r d5dbadfb6161 -r 62d2ebb8d23b libvirt.pc --- a/libvirt.pc Wed Apr 02 13:13:06 2008 +0900 +++ b/libvirt.pc Tue Jan 27 03:13:46 2009 +0900 @@ -1,4 +1,4 @@ -prefix=/usr +prefix=/usr/local exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include diff -r d5dbadfb6161 -r 62d2ebb8d23b libvirt.spec --- a/libvirt.spec Wed Apr 02 13:13:06 2008 +0900 +++ b/libvirt.spec Tue Jan 27 03:13:46 2009 +0900 @@ -1,17 +1,14 @@ # -*- rpm-spec -*- -%if "%{fedora}" >= "8" -%define with_polkit 1 -%define with_proxy no -%else +# For Xen RBAC 20080910 %define with_polkit 0 %define with_proxy yes -%endif +%define with_rbac yes Summary: Library providing a simple API virtualization Name: libvirt Version: 0.4.0 -Release: 1 +Release: 1%{?dist} License: LGPL Group: Development/Libraries Source: libvirt-%{version}.tar.gz @@ -35,6 +32,7 @@ Requires: PolicyKit >= 0.6 %endif BuildRequires: xen-devel +BuildRequires: libxenrbac >= 2.0.0 BuildRequires: libxml2-devel BuildRequires: readline-devel BuildRequires: ncurses-devel @@ -85,7 +83,8 @@ %configure --with-init-script=redhat \ --with-qemud-pid-file=%{_localstatedir}/run/libvirt_qemud.pid \ --with-remote-file=%{_localstatedir}/run/libvirtd.pid \ - --with-xen-proxy=%{with_proxy} + --with-xen-proxy=%{with_proxy} \ + --with-rbac=%{with_rbac} make %install diff -r d5dbadfb6161 -r 62d2ebb8d23b libvirt.spec.in --- a/libvirt.spec.in Wed Apr 02 13:13:06 2008 +0900 +++ b/libvirt.spec.in Tue Jan 27 03:13:46 2009 +0900 @@ -1,17 +1,14 @@ # -*- rpm-spec -*- -%if "%{fedora}" >= "8" -%define with_polkit 1 -%define with_proxy no -%else +# For Xen RBAC 20080910 %define with_polkit 0 %define with_proxy yes -%endif +%define with_rbac yes Summary: Library providing a simple API virtualization Name: libvirt Version: @VERSION@ -Release: 1 +Release: 1%{?dist} License: LGPL Group: Development/Libraries Source: libvirt-%{version}.tar.gz @@ -35,6 +32,7 @@ Requires: PolicyKit >= 0.6 %endif BuildRequires: xen-devel +BuildRequires: libxenrbac >= 2.0.0 BuildRequires: libxml2-devel BuildRequires: readline-devel BuildRequires: ncurses-devel @@ -85,7 +83,8 @@ %configure --with-init-script=redhat \ --with-qemud-pid-file=%{_localstatedir}/run/libvirt_qemud.pid \ --with-remote-file=%{_localstatedir}/run/libvirtd.pid \ - --with-xen-proxy=%{with_proxy} + --with-xen-proxy=%{with_proxy} \ + --with-rbac=%{with_rbac} make %install diff -r d5dbadfb6161 -r 62d2ebb8d23b proxy/libvirt_proxy.c --- a/proxy/libvirt_proxy.c Wed Apr 02 13:13:06 2008 +0900 +++ b/proxy/libvirt_proxy.c Tue Jan 27 03:13:46 2009 +0900 @@ -363,6 +363,9 @@ virProxyPacketPtr req = (virProxyPacketPtr) &request; int ret; char *xml, *ostype; +#ifdef RBAC + char *sched_type; +#endif /* RBAC */ retry: ret = read(pollInfos[nr].fd, req, sizeof(virProxyPacket)); @@ -662,6 +665,28 @@ free(ostype); } break; +#ifdef RBAC + case VIR_PROXY_GET_SCHEDTYPE: + if (req->len != sizeof(virProxyPacket)) + goto comm_error; + sched_type = xenHypervisorGetSchedType(conn, &request.extra.arg[0]); + if (!sched_type) { + req->data.arg = -1; + req->len = sizeof (virProxyPacket); + } else { + int type_len = strlen(sched_type); + if (type_len > (int) sizeof (request.extra.str)) { + req->data.arg = -2; + req->len = sizeof (virProxyPacket); + } else { + req->data.arg = 0; + memmove (&request.extra.str[4], sched_type, type_len); + req->len = sizeof (virProxyPacket) + sizeof(int) + type_len; + } + free (sched_type); + } + break; +#endif /* RBAC */ default: goto comm_error; } diff -r d5dbadfb6161 -r 62d2ebb8d23b qemud/qemud.c --- a/qemud/qemud.c Wed Apr 02 13:13:06 2008 +0900 +++ b/qemud/qemud.c Tue Jan 27 03:13:46 2009 +0900 @@ -73,7 +73,11 @@ static char *tcp_port = (char *) LIBVIRTD_TCP_PORT; static gid_t unix_sock_gid = 0; /* Only root by default */ +#ifdef RBAC +static int unix_sock_rw_mask = 0777; /* Allow world */ +#else static int unix_sock_rw_mask = 0700; /* Allow user only */ +#endif static int unix_sock_ro_mask = 0777; /* Allow world */ #if HAVE_POLKIT diff -r d5dbadfb6161 -r 62d2ebb8d23b qemud/remote.c --- a/qemud/remote.c Wed Apr 02 13:13:06 2008 +0900 +++ b/qemud/remote.c Tue Jan 27 03:13:46 2009 +0900 @@ -1705,9 +1705,15 @@ /* Allocate return buffer. */ ret->names.names_val = calloc (args->maxnames, sizeof (*(ret->names.names_val))); +#ifdef RBAC + ret->names.names_len = + virConnectListDefinedNetworks_QEMUD (client->conn, + ret->names.names_val, args->maxnames); +#else ret->names.names_len = virConnectListDefinedNetworks (client->conn, ret->names.names_val, args->maxnames); +#endif if (ret->names.names_len == -1) return -1; return 0; @@ -1756,9 +1762,15 @@ /* Allocate return buffer. */ ret->names.names_val = calloc (args->maxnames, sizeof (*(ret->names.names_val))); +#ifdef RBAC + ret->names.names_len = + virConnectListNetworks_QEMUD (client->conn, + ret->names.names_val, args->maxnames); +#else ret->names.names_len = virConnectListNetworks (client->conn, ret->names.names_val, args->maxnames); +#endif if (ret->names.names_len == -1) return -1; return 0; @@ -1780,10 +1792,17 @@ return -2; } +#ifdef RBAC + if (virNetworkCreate_QEMUD (net) == -1) { + virNetworkFree(net); + return -1; + } +#else if (virNetworkCreate (net) == -1) { virNetworkFree(net); return -1; } +#endif virNetworkFree(net); return 0; } @@ -1798,7 +1817,11 @@ virNetworkPtr net; CHECK_CONN(client); +#ifdef RBAC + net = virNetworkCreateXML_QEMUD (client->conn, args->xml); +#else net = virNetworkCreateXML (client->conn, args->xml); +#endif if (net == NULL) return -1; make_nonnull_network (&ret->net, net); @@ -1816,7 +1839,11 @@ virNetworkPtr net; CHECK_CONN(client); +#ifdef RBAC + net = virNetworkDefineXML_QEMUD (client->conn, args->xml); +#else net = virNetworkDefineXML (client->conn, args->xml); +#endif if (net == NULL) return -1; make_nonnull_network (&ret->net, net); @@ -1840,10 +1867,17 @@ return -2; } +#ifdef RBAC + if (virNetworkDestroy_QEMUD (net) == -1) { + virNetworkFree(net); + return -1; + } +#else if (virNetworkDestroy (net) == -1) { virNetworkFree(net); return -1; } +#endif virNetworkFree(net); return 0; } @@ -1865,7 +1899,11 @@ } /* remoteDispatchClientRequest will free this. */ +#ifdef RBAC + ret->xml = virNetworkGetXMLDesc_QEMUD (net, args->flags); +#else ret->xml = virNetworkGetXMLDesc (net, args->flags); +#endif if (!ret->xml) { virNetworkFree(net); return -1; @@ -1976,10 +2014,17 @@ return -2; } +#ifdef RBAC + if (virNetworkSetAutostart_QEMUD (net, args->autostart) == -1) { + virNetworkFree(net); + return -1; + } +#else if (virNetworkSetAutostart (net, args->autostart) == -1) { virNetworkFree(net); return -1; } +#endif virNetworkFree(net); return 0; } @@ -2000,10 +2045,17 @@ return -2; } +#ifdef RBAC + if (virNetworkUndefine_QEMUD (net) == -1) { + virNetworkFree(net); + return -1; + } +#else if (virNetworkUndefine (net) == -1) { virNetworkFree(net); return -1; } +#endif virNetworkFree(net); return 0; } diff -r d5dbadfb6161 -r 62d2ebb8d23b src/Makefile.in --- a/src/Makefile.in Wed Apr 02 13:13:06 2008 +0900 +++ b/src/Makefile.in Tue Jan 27 03:13:46 2009 +0900 @@ -122,7 +122,8 @@ libvirt_la-iptables.lo libvirt_la-uuid.lo \ libvirt_la-qemu_driver.lo libvirt_la-qemu_conf.lo \ libvirt_la-openvz_conf.lo libvirt_la-openvz_driver.lo \ - libvirt_la-nodeinfo.lo libvirt_la-util.lo + libvirt_la-nodeinfo.lo libvirt_la-util.lo \ + libvirt_la-xenrbac_libvirt.lo am__objects_2 = libvirt_la-remote_protocol.lo am_libvirt_la_OBJECTS = $(am__objects_1) $(am__objects_2) libvirt_la_OBJECTS = $(am_libvirt_la_OBJECTS) @@ -359,6 +360,7 @@ LIBVIRT_VERSION_NUMBER = @LIBVIRT_VERSION_NUMBER@ LIBXML_CFLAGS = @LIBXML_CFLAGS@ LIBXML_LIBS = @LIBXML_LIBS@ +LIBXENRBAC = -lxenrbac LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ @@ -569,7 +571,8 @@ openvz_conf.c openvz_conf.h \ openvz_driver.c openvz_driver.h \ nodeinfo.h nodeinfo.c \ - util.c util.h + util.c util.h \ + xenrbac_libvirt.c xenrbac_libvirt.h SERVER_SOURCES = \ ../qemud/remote_protocol.c ../qemud/remote_protocol.h @@ -652,7 +655,7 @@ rm -f "$${dir}/so_locations"; \ done libvirt.la: $(libvirt_la_OBJECTS) $(libvirt_la_DEPENDENCIES) - $(libvirt_la_LINK) -rpath $(libdir) $(libvirt_la_OBJECTS) $(libvirt_la_LIBADD) $(LIBS) + $(libvirt_la_LINK) -rpath $(libdir) $(libvirt_la_OBJECTS) $(libvirt_la_LIBADD) $(LIBS) $(LIBXENRBAC) install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @@ -683,7 +686,7 @@ done virsh$(EXEEXT): $(virsh_OBJECTS) $(virsh_DEPENDENCIES) @rm -f virsh$(EXEEXT) - $(virsh_LINK) $(virsh_OBJECTS) $(virsh_LDADD) $(LIBS) + $(virsh_LINK) $(virsh_OBJECTS) $(virsh_LDADD) $(LIBS) $(LIBXENRBAC) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -719,6 +722,8 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_la-xm_internal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_la-xml.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_la-xs_internal.Plo@am__quote@ +#RBAC +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libvirt_la-xenrbac_libvirt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virsh-console.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/virsh-virsh.Po@am__quote@ @@ -813,6 +818,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_la_CFLAGS) $(CFLAGS) -c -o libvirt_la-xs_internal.lo `test -f 'xs_internal.c' || echo '$(srcdir)/'`xs_internal.c +libvirt_la-xenrbac_libvirt.lo: xenrbac_libvirt.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_la_CFLAGS) $(CFLAGS) -MT libvirt_la-xenrbac_libvirt.lo -MD -MP -MF $(DEPDIR)/libvirt_la-xenrbac_libvirt.Tpo -c -o libvirt_la-xenrbac_libvirt.lo `test -f 'xenrbac_libvirt.c' || echo '$(srcdir)/'`xenrbac_libvirt.c +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libvirt_la-xenrbac_libvirt.Tpo $(DEPDIR)/libvirt_la-xenrbac_libvirt.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='xenrbac_libvirt.c' object='libvirt_la-xenrbac_libvirt.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_la_CFLAGS) $(CFLAGS) -c -o libvirt_la-xenrbac_libvirt.lo `test -f 'xenrbac_libvirt.c' || echo '$(srcdir)/'`xenrbac_libvirt.c + libvirt_la-xend_internal.lo: xend_internal.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libvirt_la_CFLAGS) $(CFLAGS) -MT libvirt_la-xend_internal.lo -MD -MP -MF $(DEPDIR)/libvirt_la-xend_internal.Tpo -c -o libvirt_la-xend_internal.lo `test -f 'xend_internal.c' || echo '$(srcdir)/'`xend_internal.c @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libvirt_la-xend_internal.Tpo $(DEPDIR)/libvirt_la-xend_internal.Plo @@ -1181,7 +1193,7 @@ # target to ease building test programs # tst: tst.c - $(CC) $(CFLAGS) $(INCLUDES) -I../include -o tst tst.c .libs/libvirt.a $(LIBXML_LIBS) $(VIRSH_LIBS) $(GNUTLS_LIBS) $(LIBS) + $(CC) $(CFLAGS) $(INCLUDES) -I../include -o tst tst.c .libs/libvirt.a $(LIBXML_LIBS) $(VIRSH_LIBS) $(GNUTLS_LIBS) $(LIBS) $(LIBXENRBAC) cov: clean-cov $(COVERAGE_FILES) diff -r d5dbadfb6161 -r 62d2ebb8d23b src/libvirt.c --- a/src/libvirt.c Wed Apr 02 13:13:06 2008 +0900 +++ b/src/libvirt.c Tue Jan 27 03:13:46 2009 +0900 @@ -40,6 +40,9 @@ #ifdef WITH_OPENVZ #include "openvz_driver.h" #endif +#ifdef RBAC +#include "xenrbac_libvirt.h" +#endif /* * TODO: @@ -481,6 +484,11 @@ if (libVer == NULL) return (-1); + +#ifdef RBAC + if(xenRBACdomain( XR_VERSION, NULL, NULL) == -1) + return (-1); +#endif *libVer = LIBVIR_VERSION_NUMBER; if (typeVer != NULL) { @@ -815,6 +823,10 @@ return NULL; } +#ifdef RBAC + if(xenRBACdomain( XR_HOSTNAME, NULL, conn) == -1) + return NULL; +#endif if (conn->driver->getHostname) return conn->driver->getHostname (conn); @@ -849,6 +861,10 @@ return NULL; } +#ifdef RBAC + if(xenRBACdomain( XR_HYPERVISER_URI, NULL, conn) == -1) + return NULL; +#endif /* Drivers may override getURI, but if they don't then * we provide a default implementation. */ @@ -917,6 +933,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_LIST_VM, NULL, conn) == -1) + return (-1); +#endif if (conn->driver->listDomains) return conn->driver->listDomains (conn, ids, maxids); @@ -1006,6 +1026,10 @@ return (NULL); } +#ifdef RBAC + if(xenRBACxml(XR_CREATE_VM, xmlDesc, conn) == -1) + return (NULL); +#endif if (conn->driver->domainCreateLinux) return conn->driver->domainCreateLinux (conn, xmlDesc, flags); @@ -1189,6 +1213,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_DESTROY_VM, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainDestroy) return conn->driver->domainDestroy (domain); @@ -1248,6 +1276,10 @@ conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_PAUSE_VM, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainSuspend) return conn->driver->domainSuspend (domain); @@ -1282,6 +1314,10 @@ conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_PAUSE_VM, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainResume) return conn->driver->domainResume (domain); @@ -1322,6 +1358,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_SAVE_VM, NULL, conn) == -1) + return (-1); +#endif /* * We must absolutize the file path as the save is done out of process * TODO: check for URI when libxml2 is linked in. @@ -1377,6 +1417,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_SAVE_VM, NULL, conn) == -1) + return (-1); +#endif /* * We must absolutize the file path as the restore is done out of process * TODO: check for URI when libxml2 is linked in. @@ -1436,6 +1480,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_DUMP_VM, domain->name, conn) == -1) + return (-1); +#endif /* * We must absolutize the file path as the save is done out of process * TODO: check for URI when libxml2 is linked in. @@ -1493,6 +1541,10 @@ conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_SHUTDOWN_VM, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainShutdown) return conn->driver->domainShutdown (domain); @@ -1528,6 +1580,10 @@ conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_REBOOT_VM, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainReboot) return conn->driver->domainReboot (domain, flags); @@ -1661,6 +1717,10 @@ conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_LIST_VM, domain->name, conn) == -1) + return (NULL); +#endif if (conn->driver->domainGetOSType) return conn->driver->domainGetOSType (domain); @@ -1734,6 +1794,10 @@ } conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_SET_MEM, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainSetMaxMemory) return conn->driver->domainSetMaxMemory (domain, memory); @@ -1778,6 +1842,10 @@ conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_SET_MEM, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainSetMemory) return conn->driver->domainSetMemory (domain, memory); @@ -1926,6 +1994,11 @@ return NULL; } conn = domain->conn; /* Source connection. */ + +#ifdef RBAC + if(xenRBACdomain( XR_MIGRATE_VM, domain->name, conn) == -1) + return NULL; +#endif if (!VIR_IS_CONNECT (dconn)) { virLibConnError (conn, VIR_ERR_INVALID_CONN, __FUNCTION__); return NULL; @@ -2150,6 +2223,10 @@ return 0; } +#ifdef RBAC + if(xenRBACdomain( XR_AVAILABLE_MEM, NULL, conn) == -1) + return 0; +#endif if (conn->driver->getFreeMemory) return conn->driver->getFreeMemory (conn); @@ -2179,6 +2256,10 @@ } conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_GET_SCHEDULER, domain->name, conn) == -1) + return NULL; +#endif if (conn->driver->domainGetSchedulerType){ schedtype = conn->driver->domainGetSchedulerType (domain, nparams); return schedtype; @@ -2216,6 +2297,10 @@ } conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_GET_SCHEDULER, domain->name, conn) == -1) + return -1; +#endif if (conn->driver->domainGetSchedulerParameters) return conn->driver->domainGetSchedulerParameters (domain, params, nparams); @@ -2248,6 +2333,10 @@ } conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_SET_SCHEDULER, domain->name, conn) == -1) + return -1; +#endif if (conn->driver->domainSetSchedulerParameters) return conn->driver->domainSetSchedulerParameters (domain, params, nparams); @@ -2297,6 +2386,10 @@ } conn = dom->conn; +#ifdef RBAC + if(xenRBACdomain( XR_LOAD_VM, dom->name, conn) == -1) + return -1; +#endif if (conn->driver->domainBlockStats) { if (conn->driver->domainBlockStats (dom, path, &stats2) == -1) return -1; @@ -2349,6 +2442,10 @@ } conn = dom->conn; +#ifdef RBAC + if(xenRBACdomain( XR_LOAD_VM, dom->name, conn) == -1) + return -1; +#endif if (conn->driver->domainInterfaceStats) { if (conn->driver->domainInterfaceStats (dom, path, &stats2) == -1) return -1; @@ -2396,6 +2493,10 @@ return (NULL); } +#ifdef RBAC + if(xenRBACxml(XR_DEFINE_VM, xml, conn) == -1) + return (NULL); +#endif if (conn->driver->domainDefineXML) return conn->driver->domainDefineXML (conn, xml); @@ -2426,6 +2527,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_UNDEFINE_VM, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainUndefine) return conn->driver->domainUndefine (domain); @@ -2483,6 +2588,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_LIST_VM, NULL, conn) == -1) + return (-1); +#endif if (conn->driver->listDefinedDomains) return conn->driver->listDefinedDomains (conn, names, maxnames); @@ -2518,6 +2627,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_START_VM, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainCreate) return conn->driver->domainCreate (domain); @@ -2585,6 +2698,10 @@ conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_AUTOSTART_VM, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainSetAutostart) return conn->driver->domainSetAutostart (domain, autostart); @@ -2630,6 +2747,10 @@ } conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_SET_VCPU, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainSetVcpus) return conn->driver->domainSetVcpus (domain, nvcpus); @@ -2682,6 +2803,10 @@ conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_SET_VCPU, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainPinVcpu) return conn->driver->domainPinVcpu (domain, vcpu, cpumap, maplen); @@ -2736,6 +2861,10 @@ conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_GET_VCPU, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainGetVcpus) return conn->driver->domainGetVcpus (domain, info, maxinfo, cpumaps, maplen); @@ -2802,6 +2931,10 @@ } conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_ATTACH_DEVICE, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainAttachDevice) return conn->driver->domainAttachDevice (domain, xml); @@ -2834,6 +2967,10 @@ } conn = domain->conn; +#ifdef RBAC + if(xenRBACdomain( XR_DETACH_DEVICE, domain->name, conn) == -1) + return (-1); +#endif if (conn->driver->domainDetachDevice) return conn->driver->domainDetachDevice (domain, xml); @@ -2876,6 +3013,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_AVAILABLE_MEM, NULL, conn) == -1) + return (-1); +#endif if (conn->driver->nodeGetCellsFreeMemory) return conn->driver->nodeGetCellsFreeMemory (conn, freeMems, startCell, maxCells); @@ -2959,6 +3100,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_LIST_VNET, NULL, conn) == -1) + return (-1); +#endif if (conn->networkDriver && conn->networkDriver->listNetworks) return conn->networkDriver->listNetworks (conn, names, maxnames); @@ -3017,6 +3162,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_LIST_VNET, NULL, conn) == -1) + return (-1); +#endif if (conn->networkDriver && conn->networkDriver->listDefinedNetworks) return conn->networkDriver->listDefinedNetworks (conn, names, maxnames); @@ -3166,6 +3315,10 @@ return (NULL); } +#ifdef RBAC + if(xenRBACdomain( XR_CREATE_VNET, NULL, conn) == -1) + return (NULL); +#endif if (conn->networkDriver && conn->networkDriver->networkCreateXML) return conn->networkDriver->networkCreateXML (conn, xmlDesc); @@ -3200,6 +3353,10 @@ return (NULL); } +#ifdef RBAC + if(xenRBACdomain( XR_DEFINE_VNET, NULL, conn) == -1) + return (NULL); +#endif if (conn->networkDriver && conn->networkDriver->networkDefineXML) return conn->networkDriver->networkDefineXML (conn, xml); @@ -3230,6 +3387,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_DEFINE_VNET, NULL, conn) == -1) + return (-1); +#endif if (conn->networkDriver && conn->networkDriver->networkUndefine) return conn->networkDriver->networkUndefine (network); @@ -3266,6 +3427,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_CREATE_VNET, NULL, conn) == -1) + return (-1); +#endif if (conn->networkDriver && conn->networkDriver->networkCreate) return conn->networkDriver->networkCreate (network); @@ -3302,6 +3467,10 @@ return (-1); } +#ifdef RBAC + if(xenRBACdomain( XR_DESTROY_VNET, NULL, conn) == -1) + return (-1); +#endif if (conn->networkDriver && conn->networkDriver->networkDestroy) return conn->networkDriver->networkDestroy (network); @@ -3441,6 +3610,10 @@ conn = network->conn; +#ifdef RBAC + if(xenRBACdomain( XR_DETAIL_VNET, NULL, conn) == -1) + return (NULL); +#endif if (conn->networkDriver && conn->networkDriver->networkDumpXML) return conn->networkDriver->networkDumpXML (network, flags); @@ -3538,6 +3711,10 @@ conn = network->conn; +#ifdef RBAC + if(xenRBACdomain( XR_AUTOSTART_VNET, NULL, conn) == -1) + return (-1); +#endif if (conn->networkDriver && conn->networkDriver->networkSetAutostart) return conn->networkDriver->networkSetAutostart (network, autostart); @@ -3545,6 +3722,340 @@ return -1; } +#ifdef RBAC +/** + * virDomainGetXMLDesc_XRBAC: + * @op_id: a access ID + * @domain: a domain object + * @flags: an OR'ed set of virDomainXMLFlags + * + * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error. + * the caller must free() the returned value. + */ +char * +virDomainGetXMLDesc_XRBAC(int op_id, virDomainPtr domain, int flags) +{ + /* parameter Check */ + if( domain == NULL ) { + virLibConnError( domain->conn, VIR_ERR_INTERNAL_ERROR, "domain name"); + return NULL; + } + if( (domain->name == NULL) || (strlen(domain->name) == 0) ){ + virLibConnError( domain->conn, VIR_ERR_INTERNAL_ERROR, "domain name"); + return NULL; + } + + if(xenRBACdomain( op_id, domain->name, domain->conn) == -1) + return NULL; + + return virDomainGetXMLDesc(domain, flags); +} + +/** + * virConnectListNetworks_QEMUD: + * @conn: pointer to the hypervisor connection + * @names: array to collect the list of names of active networks + * @maxnames: size of @names + * + * Collect the list of active networks, and store their names in @names + * + * Returns the number of networks found or -1 in case of error + */ +int +virConnectListNetworks_QEMUD(virConnectPtr conn, char **const names, int maxnames) +{ + DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return (-1); + } + + if ((names == NULL) || (maxnames < 0)) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + return (-1); + } + + if (conn->networkDriver && conn->networkDriver->listNetworks) + return conn->networkDriver->listNetworks (conn, names, maxnames); + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + return -1; +} + +/** + * virConnectListDefinedNetworks_QEMUD: + * @conn: pointer to the hypervisor connection + * @names: pointer to an array to store the names + * @maxnames: size of the array + * + * list the inactive networks, stores the pointers to the names in @names + * + * Returns the number of names provided in the array or -1 in case of error + */ +int +virConnectListDefinedNetworks_QEMUD(virConnectPtr conn, char **const names, + int maxnames) +{ + DEBUG("conn=%p, names=%p, maxnames=%d", conn, names, maxnames); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return (-1); + } + + if ((names == NULL) || (maxnames < 0)) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + return (-1); + } + + if (conn->networkDriver && conn->networkDriver->listDefinedNetworks) + return conn->networkDriver->listDefinedNetworks (conn, + names, maxnames); + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + return -1; +} + +/** + * virNetworkCreateXML_QEMUD: + * @conn: pointer to the hypervisor connection + * @xmlDesc: an XML description of the network + * + * Create and start a new virtual network, based on an XML description + * similar to the one returned by virNetworkGetXMLDesc() + * + * Returns a new network object or NULL in case of failure + */ +virNetworkPtr +virNetworkCreateXML_QEMUD(virConnectPtr conn, const char *xmlDesc) +{ + DEBUG("conn=%p, xmlDesc=%s", conn, xmlDesc); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return (NULL); + } + if (xmlDesc == NULL) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + return (NULL); + } + if (conn->flags & VIR_CONNECT_RO) { + virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + return (NULL); + } + + if (conn->networkDriver && conn->networkDriver->networkCreateXML) + return conn->networkDriver->networkCreateXML (conn, xmlDesc); + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + return NULL; +} + +/** + * virNetworkDefineXML_QEMUD: + * @conn: pointer to the hypervisor connection + * @xml: the XML description for the network, preferably in UTF-8 + * + * Define a network, but does not create it + * + * Returns NULL in case of error, a pointer to the network otherwise + */ +virNetworkPtr +virNetworkDefineXML_QEMUD(virConnectPtr conn, const char *xml) +{ + DEBUG("conn=%p, xml=%s", conn, xml); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return (NULL); + } + if (conn->flags & VIR_CONNECT_RO) { + virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + return (NULL); + } + if (xml == NULL) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + return (NULL); + } + + if (conn->networkDriver && conn->networkDriver->networkDefineXML) + return conn->networkDriver->networkDefineXML (conn, xml); + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + return NULL; +} + +/** + * virNetworkUndefine_QEMUD: + * @network: pointer to a defined network + * + * Undefine a network but does not stop it if it is running + * + * Returns 0 in case of success, -1 in case of error + */ +int +virNetworkUndefine_QEMUD(virNetworkPtr network) { + virConnectPtr conn; + DEBUG("network=%p", network); + + if (!VIR_IS_CONNECTED_NETWORK(network)) { + virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__); + return (-1); + } + conn = network->conn; + if (conn->flags & VIR_CONNECT_RO) { + virLibNetworkError(network, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + return (-1); + } + + if (conn->networkDriver && conn->networkDriver->networkUndefine) + return conn->networkDriver->networkUndefine (network); + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + return -1; +} + +/** + * virNetworkCreate_QEMUD: + * @network: pointer to a defined network + * + * Create and start a defined network. If the call succeed the network + * moves from the defined to the running networks pools. + * + * Returns 0 in case of success, -1 in case of error + */ +int +virNetworkCreate_QEMUD(virNetworkPtr network) +{ + virConnectPtr conn; + DEBUG("network=%p", network); + + if (network == NULL) { + TODO + return (-1); + } + if (!VIR_IS_CONNECTED_NETWORK(network)) { + virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__); + return (-1); + } + conn = network->conn; + if (conn->flags & VIR_CONNECT_RO) { + virLibNetworkError(network, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + return (-1); + } + + if (conn->networkDriver && conn->networkDriver->networkCreate) + return conn->networkDriver->networkCreate (network); + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + return -1; +} + +/** + * virNetworkDestroy_QEMUD: + * @network: a network object + * + * Destroy the network object. The running instance is shutdown if not down + * already and all resources used by it are given back to the hypervisor. + * The data structure is freed and should not be used thereafter if the + * call does not return an error. + * This function may requires priviledged access + * + * Returns 0 in case of success and -1 in case of failure. + */ +int +virNetworkDestroy_QEMUD(virNetworkPtr network) +{ + virConnectPtr conn; + DEBUG("network=%p", network); + + if (!VIR_IS_CONNECTED_NETWORK(network)) { + virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__); + return (-1); + } + + conn = network->conn; + if (conn->flags & VIR_CONNECT_RO) { + virLibNetworkError(network, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + return (-1); + } + + if (conn->networkDriver && conn->networkDriver->networkDestroy) + return conn->networkDriver->networkDestroy (network); + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + return -1; +} + +/** + * virNetworkGetXMLDesc_QEMUD: + * @network: a network object + * @flags: and OR'ed set of extraction flags, not used yet + * + * Provide an XML description of the network. The description may be reused + * later to relaunch the network with virNetworkCreateXML(). + * + * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of error. + * the caller must free() the returned value. + */ +char * +virNetworkGetXMLDesc_QEMUD(virNetworkPtr network, int flags) +{ + virConnectPtr conn; + DEBUG("network=%p, flags=%d", network, flags); + + if (!VIR_IS_NETWORK(network)) { + virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__); + return (NULL); + } + if (flags != 0) { + virLibNetworkError(network, VIR_ERR_INVALID_ARG, __FUNCTION__); + return (NULL); + } + + conn = network->conn; + + if (conn->networkDriver && conn->networkDriver->networkDumpXML) + return conn->networkDriver->networkDumpXML (network, flags); + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + return NULL; +} + +/** + * virNetworkSetAutostart_QEMUD: + * @network: a network object + * @autostart: whether the network should be automatically started 0 or 1 + * + * Configure the network to be automatically started + * when the host machine boots. + * + * Returns -1 in case of error, 0 in case of success + */ +int +virNetworkSetAutostart_QEMUD(virNetworkPtr network, + int autostart) +{ + virConnectPtr conn; + DEBUG("network=%p, autostart=%d", network, autostart); + + if (!VIR_IS_NETWORK(network)) { + virLibNetworkError(NULL, VIR_ERR_INVALID_NETWORK, __FUNCTION__); + return (-1); + } + + conn = network->conn; + + if (conn->networkDriver && conn->networkDriver->networkSetAutostart) + return conn->networkDriver->networkSetAutostart (network, autostart); + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + return -1; +} +#endif + + /* * vim: set tabstop=4: * vim: set shiftwidth=4: diff -r d5dbadfb6161 -r 62d2ebb8d23b src/libvirt_sym.version --- a/src/libvirt_sym.version Wed Apr 02 13:13:06 2008 +0900 +++ b/src/libvirt_sym.version Tue Jan 27 03:13:46 2009 +0900 @@ -28,6 +28,7 @@ virDomainGetName; virDomainGetOSType; virDomainGetXMLDesc; + virDomainGetXMLDesc_XRBAC; virDomainLookupByID; virDomainLookupByName; virDomainLookupByUUID; @@ -99,6 +100,15 @@ virNetworkGetBridgeName; virNetworkGetAutostart; virNetworkSetAutostart; + virConnectListNetworks_QEMUD; + virConnectListDefinedNetworks_QEMUD; + virNetworkCreateXML_QEMUD; + virNetworkDefineXML_QEMUD; + virNetworkUndefine_QEMUD; + virNetworkCreate_QEMUD; + virNetworkDestroy_QEMUD; + virNetworkGetXMLDesc_QEMUD; + virNetworkSetAutostart_QEMUD; /* Symbols with __ are private only for use by the libvirtd daemon. diff -r d5dbadfb6161 -r 62d2ebb8d23b src/proxy_internal.c --- a/src/proxy_internal.c Wed Apr 02 13:13:06 2008 +0900 +++ b/src/proxy_internal.c Tue Jan 27 03:13:46 2009 +0900 @@ -42,6 +42,9 @@ static unsigned long xenProxyDomainGetMaxMemory(virDomainPtr domain); static int xenProxyDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info); static char *xenProxyDomainGetOSType(virDomainPtr domain); +#ifdef RBAC +static char *xenProxyGetSchedulerType(virDomainPtr domain, int *nparams); +#endif struct xenUnifiedDriver xenProxyDriver = { xenProxyOpen, /* open */ @@ -80,7 +83,11 @@ NULL, /* domainDetachDevice */ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ +#ifdef RBAC + xenProxyGetSchedulerType, /* domainGetInfo */ +#else NULL, /* domainGetSchedulerType */ +#endif NULL, /* domainGetSchedulerParameters */ NULL, /* domainSetSchedulerParameters */ }; @@ -533,9 +540,11 @@ int ret; int fd; xenUnifiedPrivatePtr priv; - + +#ifndef RBAC if (!(flags & VIR_CONNECT_RO)) return(-1); +#endif priv = (xenUnifiedPrivatePtr) conn->privateData; priv->proxy = -1; @@ -1113,6 +1122,54 @@ return(ostype); } +#ifdef RBAC +static char * +xenProxyGetSchedulerType(virDomainPtr domain, int *nparams) +{ + virProxyPacket req; + virProxyFullPacket ans; + int ret, type_len; + char *sched_type; + + if (!VIR_IS_CONNECTED_DOMAIN(domain)) { + if (domain == NULL) + virProxyError(NULL, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + else + virProxyError(domain->conn, VIR_ERR_INVALID_DOMAIN, __FUNCTION__); + return NULL; + } + if (domain->id < 0) + return NULL; + + memset(&req, 0, sizeof(req)); + req.command = VIR_PROXY_GET_SCHEDTYPE; + req.len = sizeof(req); + ret = xenProxyCommand(domain->conn, &req, &ans, 0); + if (ret < 0) { + xenProxyClose(domain->conn); + return NULL; + } + if (ans.data.arg == -1) + return NULL; + if (ans.len <= sizeof(virProxyPacket)) { + virProxyError(domain->conn, VIR_ERR_OPERATION_FAILED, __FUNCTION__); + return NULL; + } + + type_len = ans.len - sizeof (virProxyPacket) - sizeof(int); + sched_type = malloc (type_len + 1); + if (!sched_type) { + virProxyError (domain->conn, VIR_ERR_NO_MEMORY, __FUNCTION__); + return NULL; + } + + *nparams = ans.extra.arg[0]; + memmove (sched_type, &ans.extra.str[4], type_len); + sched_type[type_len] = '\0'; + + return sched_type; +} +#endif #endif /* WITH_XEN */ /* diff -r d5dbadfb6161 -r 62d2ebb8d23b src/proxy_internal.h --- a/src/proxy_internal.h Wed Apr 02 13:13:06 2008 +0900 +++ b/src/proxy_internal.h Tue Jan 27 03:13:46 2009 +0900 @@ -37,7 +37,12 @@ VIR_PROXY_DOMAIN_INFO = 9, VIR_PROXY_DOMAIN_XML = 10, VIR_PROXY_DOMAIN_OSTYPE = 11, +#ifdef RBAC + VIR_PROXY_GET_CAPABILITIES = 12, + VIR_PROXY_GET_SCHEDTYPE = 13 +#else VIR_PROXY_GET_CAPABILITIES = 12 +#endif } virProxyCommand; /* diff -r d5dbadfb6161 -r 62d2ebb8d23b src/remote_internal.c --- a/src/remote_internal.c Wed Apr 02 13:13:06 2008 +0900 +++ b/src/remote_internal.c Tue Jan 27 03:13:46 2009 +0900 @@ -677,7 +677,7 @@ cmd_argv[j++] = strdup (sockname ? sockname : LIBVIRTD_PRIV_UNIX_SOCKET); cmd_argv[j++] = 0; assert (j == nr_args); - for (j = 0; j < nr_args; j++) + for (j = 0; j < (nr_args-1); j++) if (cmd_argv[j] == NULL) { error (conn, VIR_ERR_SYSTEM_ERROR, strerror (ENOMEM)); goto failed; diff -r d5dbadfb6161 -r 62d2ebb8d23b src/virsh.c --- a/src/virsh.c Wed Apr 02 13:13:06 2008 +0900 +++ b/src/virsh.c Tue Jan 27 03:13:46 2009 +0900 @@ -49,6 +49,10 @@ #include "internal.h" #include "console.h" +#ifdef RBAC +#include "xenrbac_libvirt.h" +#endif + static char *progname; #ifndef TRUE @@ -1066,12 +1070,13 @@ if (!(dom = vshCommandOptDomainBy(ctl, cmd, "name", NULL, VSH_BYNAME))) return FALSE; +#ifndef RBAC if (virDomainGetID(dom) != (unsigned int)-1) { vshError(ctl, FALSE, _("Domain is already active")); virDomainFree(dom); return FALSE; } - +#endif if (virDomainCreate(dom) == 0) { vshPrint(ctl, _("Domain %s started\n"), virDomainGetName(dom)); @@ -1549,6 +1554,25 @@ if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL))) return FALSE; +#ifdef RBAC + if ((str = virDomainGetOSType(dom))) { + id = virDomainGetID(dom); + if (id == ((unsigned int)-1)) + vshPrint(ctl, "%-15s %s\n", _("Id:"), "-"); + else + vshPrint(ctl, "%-15s %d\n", _("Id:"), id); + vshPrint(ctl, "%-15s %s\n", _("Name:"), virDomainGetName(dom)); + + if (virDomainGetUUIDString(dom, &uuid[0])==0) + vshPrint(ctl, "%-15s %s\n", _("UUID:"), uuid); + + vshPrint(ctl, "%-15s %s\n", _("OS Type:"), str); + free(str); + } else { + virDomainFree(dom); + return FALSE; + } +#else id = virDomainGetID(dom); if (id == ((unsigned int)-1)) vshPrint(ctl, "%-15s %s\n", _("Id:"), "-"); @@ -1563,6 +1587,7 @@ vshPrint(ctl, "%-15s %s\n", _("OS Type:"), str); free(str); } +#endif if (virDomainGetInfo(dom, &info) == 0) { vshPrint(ctl, "%-15s %s\n", _("State:"), @@ -2116,7 +2141,11 @@ if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL))) return FALSE; +#ifdef RBAC + dump = virDomainGetXMLDesc_XRBAC(XR_DETAIL_VM, dom, 0); +#else dump = virDomainGetXMLDesc(dom, 0); +#endif if (dump != NULL) { printf("%s", dump); free(dump); @@ -2555,7 +2584,6 @@ } if (maxactive) { activeNames = vshMalloc(ctl, sizeof(char *) * maxactive); - if ((maxactive = virConnectListNetworks(ctl->conn, activeNames, maxactive)) < 0) { vshError(ctl, FALSE, _("Failed to list active networks")); @@ -2576,7 +2604,6 @@ } if (maxinactive) { inactiveNames = vshMalloc(ctl, sizeof(char *) * maxinactive); - if ((maxinactive = virConnectListDefinedNetworks(ctl->conn, inactiveNames, maxinactive)) < 0) { vshError(ctl, FALSE, _("Failed to list inactive networks")); if (activeNames) @@ -2824,6 +2851,13 @@ return FALSE; } +#ifdef RBAC + ret = virGetVersion(&libVersion, hvType, &apiVersion); + if (ret < 0) { + vshError(ctl, FALSE, _("failed to get the library version")); + return FALSE; + } + includeVersion = LIBVIR_VERSION_NUMBER; major = includeVersion / 1000000; includeVersion %= 1000000; @@ -2831,12 +2865,22 @@ rel = includeVersion % 1000; vshPrint(ctl, _("Compiled against library: libvir %d.%d.%d\n"), major, minor, rel); +#else + includeVersion = LIBVIR_VERSION_NUMBER; + major = includeVersion / 1000000; + includeVersion %= 1000000; + minor = includeVersion / 1000; + rel = includeVersion % 1000; + vshPrint(ctl, _("Compiled against library: libvir %d.%d.%d\n"), + major, minor, rel); ret = virGetVersion(&libVersion, hvType, &apiVersion); if (ret < 0) { vshError(ctl, FALSE, _("failed to get the library version")); return FALSE; } +#endif + major = libVersion / 1000000; libVersion %= 1000000; minor = libVersion / 1000; @@ -2961,7 +3005,11 @@ if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL))) return FALSE; +#ifdef RBAC + doc = virDomainGetXMLDesc_XRBAC(XR_DETAIL_VM, dom, 0); +#else doc = virDomainGetXMLDesc(dom, 0); +#endif if (!doc) goto cleanup; @@ -3038,7 +3086,11 @@ if (!(dom = vshCommandOptDomain(ctl, cmd, "domain", NULL))) return FALSE; +#ifdef RBAC + doc = virDomainGetXMLDesc_XRBAC(XR_DETAIL_VM, dom, 0); +#else doc = virDomainGetXMLDesc(dom, 0); +#endif if (!doc) goto cleanup; @@ -4532,12 +4584,15 @@ /* set up the library error handler */ virSetErrorFunc(NULL, virshErrorHandler); +#ifdef RBAC +#else #ifndef __MINGW32__ /* Force a non-root, Xen connection to readonly */ if ((ctl->name == NULL || !strcasecmp(ctl->name, "xen")) && ctl->uid != 0) ctl->readonly = 1; #endif +#endif /* RBAC */ ctl->conn = virConnectOpenAuth(ctl->name, virConnectAuthPtrDefault, diff -r d5dbadfb6161 -r 62d2ebb8d23b src/virterror.c --- a/src/virterror.c Wed Apr 02 13:13:06 2008 +0900 +++ b/src/virterror.c Tue Jan 27 03:13:46 2009 +0900 @@ -300,6 +300,11 @@ case VIR_FROM_STATS_LINUX: dom = "Linux Stats "; break; +#ifdef RBAC + case VIR_FROM_XENRBAC: + dom = "Xen RBAC "; + break; +#endif } if ((err->dom != NULL) && (err->code != VIR_ERR_INVALID_DOMAIN)) { @@ -679,6 +684,14 @@ else errmsg = _("authentication failed: %s"); break; +#ifdef RBAC + case VIR_ERR_PERMISSION: + if (info == NULL) + errmsg = _("operation not permitted"); + else + errmsg = _("operation not permitted: %s"); + break; +#endif } return (errmsg); } diff -r d5dbadfb6161 -r 62d2ebb8d23b src/xen_internal.c --- a/src/xen_internal.c Wed Apr 02 13:13:06 2008 +0900 +++ b/src/xen_internal.c Tue Jan 27 03:13:46 2009 +0900 @@ -741,7 +741,6 @@ errmsg, info, NULL, value, 0, errmsg, info, value); } -#ifndef PROXY /** * virXenErrorFunc: @@ -779,7 +778,6 @@ } } -#endif /* PROXY */ /** * virXenPerror: @@ -1069,7 +1067,6 @@ } -#ifndef PROXY /** * xenHypervisorGetSchedulerType: * @domain: pointer to the Xen Hypervisor block @@ -1082,19 +1079,35 @@ char * xenHypervisorGetSchedulerType(virDomainPtr domain, int *nparams) { + if ((domain == NULL) || (domain->conn == NULL)) { + virXenErrorFunc(NULL, VIR_ERR_INTERNAL_ERROR, __FUNCTION__, + "domain is NULL", 0); + return NULL; + } + if (domain->id < 0) { + virXenErrorFunc(domain->conn, VIR_ERR_INTERNAL_ERROR, __FUNCTION__, + "domain->id invalid", 0); + return NULL; + } + return(xenHypervisorGetSchedType(domain->conn, nparams)); +} + +char * +xenHypervisorGetSchedType(virConnectPtr conn, int *nparams) +{ char *schedulertype = NULL; xenUnifiedPrivatePtr priv; - if ((domain == NULL) || (domain->conn == NULL)) { + if (conn == NULL) { virXenErrorFunc(NULL, VIR_ERR_INTERNAL_ERROR, __FUNCTION__, - "domain or conn is NULL", 0); + "conn is NULL", 0); return NULL; } - priv = (xenUnifiedPrivatePtr) domain->conn->privateData; - if (priv->handle < 0 || domain->id < 0) { - virXenErrorFunc(domain->conn, VIR_ERR_INTERNAL_ERROR, __FUNCTION__, - "priv->handle or domain->id invalid", 0); + priv = (xenUnifiedPrivatePtr) conn->privateData; + if (priv->handle < 0) { + virXenErrorFunc(conn, VIR_ERR_INTERNAL_ERROR, __FUNCTION__, + "priv->handle invalid", 0); return NULL; } @@ -1104,8 +1117,8 @@ * TODO: check on Xen 3.0.3 */ if (dom_interface_version < 5) { - virXenErrorFunc(domain->conn, VIR_ERR_NO_XEN, __FUNCTION__, - "unsupported in dom interface < 5", 0); + virXenErrorFunc(conn, VIR_ERR_NO_XEN, __FUNCTION__, + "unsupported in dom interface < 5", 0); return NULL; } @@ -1138,6 +1151,7 @@ return schedulertype; } +#ifndef PROXY static const char *str_weight = "weight"; static const char *str_cap = "cap"; diff -r d5dbadfb6161 -r 62d2ebb8d23b src/xen_internal.h --- a/src/xen_internal.h Wed Apr 02 13:13:06 2008 +0900 +++ b/src/xen_internal.h Tue Jan 27 03:13:46 2009 +0900 @@ -76,8 +76,10 @@ int maplen); int xenHypervisorGetVcpuMax (virDomainPtr domain); -char * xenHypervisorGetSchedulerType (virDomainPtr domain, - int *nparams); +char * xenHypervisorGetSchedulerType (virDomainPtr domain, + int *nparams); +char * xenHypervisorGetSchedType (virConnectPtr conn, + int *nparams); int xenHypervisorGetSchedulerParameters (virDomainPtr domain, virSchedParameterPtr params, diff -r d5dbadfb6161 -r 62d2ebb8d23b src/xen_unified.c --- a/src/xen_unified.c Wed Apr 02 13:13:06 2008 +0900 +++ b/src/xen_unified.c Tue Jan 27 03:13:46 2009 +0900 @@ -40,6 +40,9 @@ #include "xm_internal.h" #include "xml.h" +#ifdef RBAC +#include <xen/xen.h> +#endif static int xenUnifiedNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info); static int @@ -266,6 +269,11 @@ priv->xendConfigVersion > 2) continue; +#ifdef RBAC + /* Ignore proxy for non-root */ + if (i == XEN_UNIFIED_HYPERVISOR_OFFSET && getuid() != 0) + continue; +#endif /* Ignore proxy for root */ if (i == XEN_UNIFIED_PROXY_OFFSET && getuid() == 0) continue; @@ -282,10 +290,15 @@ #endif } +#ifdef RBAC + if (!priv->opened[i] && + (!(conn->flags & VIR_CONNECT_RO) || getuid() == 0 || i == XEN_UNIFIED_PROXY_OFFSET)) { +#else /* If as root, then all drivers must succeed. If non-root, then only proxy must succeed */ if (!priv->opened[i] && (getuid() == 0 || i == XEN_UNIFIED_PROXY_OFFSET)) { +#endif for (j = 0; j < i; ++j) if (priv->opened[j]) drivers[j]->close (conn); free (priv); @@ -381,6 +394,9 @@ static int xenUnifiedGetMaxVcpus (virConnectPtr conn, const char *type) { +#ifdef RBAC + return MAX_VIRT_CPUS; +#else GET_PRIVATE(conn); if (type && STRCASENEQ (type, "Xen")) { @@ -394,6 +410,7 @@ xenUnifiedError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); return -1; } +#endif } static int @@ -889,6 +906,9 @@ static int xenUnifiedDomainGetMaxVcpus (virDomainPtr dom) { +#ifdef RBAC + return MAX_VIRT_CPUS; +#else GET_PRIVATE(dom->conn); int i, ret; @@ -899,6 +919,7 @@ } return -1; +#endif } static char * diff -r d5dbadfb6161 -r 62d2ebb8d23b src/xend_internal.c --- a/src/xend_internal.c Wed Apr 02 13:13:06 2008 +0900 +++ b/src/xend_internal.c Tue Jan 27 03:13:46 2009 +0900 @@ -62,6 +62,12 @@ static int xenDaemonDomainCoreDump(virDomainPtr domain, const char *filename, int flags); #endif /* PROXY */ +#ifdef RBAC +static int xenDaemonGetSchedulerParameters(virDomainPtr domain, + virSchedParameterPtr params, int *nparams); +static int xenDaemonSetSchedulerParameters(virDomainPtr domain, + virSchedParameterPtr params, int nparams); +#endif /* RBAC */ #ifndef PROXY struct xenUnifiedDriver xenDaemonDriver = { @@ -102,8 +108,13 @@ NULL, /* domainGetAutostart */ NULL, /* domainSetAutostart */ NULL, /* domainGetSchedulerType */ +#ifdef RBAC + xenDaemonGetSchedulerParameters, /* domainGetSchedulerParameters */ + xenDaemonSetSchedulerParameters, /* domainSetSchedulerParameters */ +#else NULL, /* domainGetSchedulerParameters */ NULL, /* domainSetSchedulerParameters */ +#endif }; /** @@ -235,7 +246,11 @@ * is rather normal, this should fallback to the proxy (or * remote) mechanism. */ +#ifdef RBAC + if (getuid() == 0) { +#else if ((getuid() == 0) || (xend->flags & VIR_CONNECT_RO)) { +#endif virXendError(xend, VIR_ERR_INTERNAL_ERROR, "failed to connect to xend"); } @@ -3591,6 +3606,109 @@ return(ret); } + +#ifdef RBAC +static const char *str_weight = "weight"; +static const char *str_cap = "cap"; + +static int +xenDaemonGetSchedulerParameters(virDomainPtr domain, + virSchedParameterPtr params, int *nparams) +{ + xenUnifiedPrivatePtr priv; + struct sexpr *root; + int weight, cap; + + if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) { + virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, + __FUNCTION__); + return (-1); + } + + priv = (xenUnifiedPrivatePtr) domain->conn->privateData; + if (domain->id < 0 && priv->xendConfigVersion < 3) + return (-1); + + root = sexpr_get(domain->conn, "/xend/domain/%d?detail=1", domain->id); + if (root == NULL) + return (-1); + + weight = sexpr_int(root, "domain/cpu_weight"); + cap = sexpr_int(root, "domain/cpu_cap"); + + strncpy (params[0].field, str_weight, VIR_DOMAIN_SCHED_FIELD_LENGTH); + params[0].type = VIR_DOMAIN_SCHED_FIELD_INT; + params[0].value.i = weight; + + strncpy (params[1].field, str_cap, VIR_DOMAIN_SCHED_FIELD_LENGTH); + params[1].type = VIR_DOMAIN_SCHED_FIELD_INT; + params[1].value.i = cap; + + return (0); +} + +static int +xenDaemonSetSchedulerParameters(virDomainPtr domain, + virSchedParameterPtr params, int nparams) +{ + int i; + int weight_set = 0; + int cap_set = 0; + char buf_weight[VIR_UUID_BUFLEN]; + char buf_cap[VIR_UUID_BUFLEN]; + xenUnifiedPrivatePtr priv; + int weight, cap; + struct sexpr *root; + + if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) + || (nparams == 0) || (params == NULL)) { + virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG, + __FUNCTION__); + return (-1); + } + + priv = (xenUnifiedPrivatePtr) domain->conn->privateData; + + if (domain->id < 0 && priv->xendConfigVersion < 3) + return(-1); + + /* search specified parameter */ + memset(&buf_weight, 0, VIR_UUID_BUFLEN); + memset(&buf_cap, 0, VIR_UUID_BUFLEN); + for (i = 0; i < nparams; i++) { + if (STREQ (params[i].field, str_weight) && + params[i].type == VIR_DOMAIN_SCHED_FIELD_UINT) { + snprintf(buf_weight, sizeof(buf_weight), "%d", params[i].value.ui); + weight_set = 1; + } else if (STREQ (params[i].field, str_cap) && + params[i].type == VIR_DOMAIN_SCHED_FIELD_UINT) { + snprintf(buf_cap, sizeof(buf_cap), "%d", params[i].value.ui); + cap_set = 1; + } else { + virXendError((domain ? domain->conn : NULL), + VIR_ERR_INVALID_ARG, __FUNCTION__); + return(-1); + } + } + + /* get the current setting from xend */ + root = sexpr_get(domain->conn, "/xend/domain/%d?detail=1", domain->id); + weight = sexpr_int(root, "domain/cpu_weight"); + cap = sexpr_int(root, "domain/cpu_cap"); + + + /* if not specified parameter, set the current value */ + if (weight_set != 1) + snprintf(buf_weight, sizeof(buf_weight), "%d", weight); + if (cap_set != 1) + snprintf(buf_cap, sizeof(buf_weight), "%d", cap); + + /* xend operation */ + return(xend_op(domain->conn, domain->name, "op", "domain_sched_credit_set", + "weight", buf_weight, "cap", buf_cap, NULL)); +} +#endif /* RBAC */ + #endif /* ! PROXY */ #endif /* WITH_XEN */ diff -r d5dbadfb6161 -r 62d2ebb8d23b src/xenrbac.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/xenrbac.h Tue Jan 27 03:13:46 2009 +0900 @@ -0,0 +1,39 @@ +/* + Copyright (C) 2008 Fujitsu Limited. + + 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. +*/ + +#ifndef __XENRBAC_H__ +#define __XENRBAC_H__ + +#include <errno.h> + +int xr_judge(char *username, int opeid, char *domainname, int flag_all); + +#define XR_ANY 0 +#define XR_ALL 1 + +#define XR_ACCEPT 0 +#define XR_DENY EPERM + +#endif /*__XENRBAC_H__*/ +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * End: + */ diff -r d5dbadfb6161 -r 62d2ebb8d23b src/xenrbac_libvirt.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/xenrbac_libvirt.c Tue Jan 27 03:13:46 2009 +0900 @@ -0,0 +1,162 @@ +/* + * xr_internal.c: access to Xen RBAC + * + * Copyright (C) 2008 FUJITSU Limited. + * + * See COPYING.LIB for the License of this software + * + */ + +#include "libvirt/libvirt.h" +#include "libvirt/virterror.h" +#include "internal.h" + +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <pwd.h> +#include <unistd.h> + +#include <libxml/parser.h> +#include <libxml/xpath.h> +#include <libxml/uri.h> + +#include "xenrbac_libvirt.h" +#include "xenrbac.h" + + +/** + * xenRBACError: + * @error: the error number + * @info: extra information string + * + * Handle an error at the connection level + */ +static void +xenRBACError(virConnectPtr conn, virErrorNumber error, const char *info) +{ + const char *errmsg; + + if (error == VIR_ERR_OK) + return; + + errmsg = __virErrorMsg(error, info); + __virRaiseError(conn, NULL, NULL, VIR_FROM_XENRBAC, error, VIR_ERR_ERROR, + errmsg, info, NULL, 0, 0, errmsg, info); +} + +int +xenRBACdomain(int op_id, char *domname, virConnectPtr conn) +{ + struct passwd *pw = NULL; + int ret=0; + char msg_buff[256]; + + memset((char *)msg_buff, (char)NULL, 256); + + /* parameter Check */ + if( op_id <= 0 ) { + snprintf(msg_buff, 256, "unknown access ID ID = %d", op_id); + xenRBACError( conn, VIR_ERR_INTERNAL_ERROR, msg_buff); + return -1; + } + + if( (domname != NULL) && (strlen(domname) == 0) ){ + xenRBACError( conn, VIR_ERR_INTERNAL_ERROR, "domain name"); + return -1; + } + /* Get username */ + if( !(pw = getpwuid( getuid())) ){ + if(errno == 0) + xenRBACError( conn, VIR_ERR_SYSTEM_ERROR, NULL); + else + xenRBACError( conn, VIR_ERR_SYSTEM_ERROR, strerror(errno)); + return -1; + } + + ret = xr_judge( pw->pw_name, op_id, domname, XR_ANY); + if ( ret != 0 ){ + switch(ret) { + case EPERM: + xenRBACError( conn, VIR_ERR_PERMISSION, NULL); + return -1; + + case EINVAL: + xenRBACError( conn, VIR_ERR_INTERNAL_ERROR, NULL); + return -1; + + case ENOMEM: + xenRBACError( conn, VIR_ERR_NO_MEMORY, NULL); + return -1; + + case ENOENT: + case EACCES: + xenRBACError( conn, VIR_ERR_OPEN_FAILED, NULL); + return -1; + + default: + xenRBACError( conn, VIR_ERR_INTERNAL_ERROR, NULL); + return -1; + + } //switch_end + } + + return 0; +} + +int +xenRBACxml( int op_id, const char *xmlDesc, virConnectPtr conn) +{ + + xmlDocPtr xml = NULL; + xmlXPathObjectPtr obj = NULL; + xmlXPathContextPtr ctxt = NULL; + int ret = 0; + + /* parameter Check */ + if( xmlDesc == NULL ){ + xenRBACError( conn, VIR_ERR_INTERNAL_ERROR, "xmlDesc"); + return -1; + } + + xml = xmlReadDoc((const xmlChar *) xmlDesc, "domain.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (!xml) { + xenRBACError( conn, VIR_ERR_XML_ERROR, NULL); + ret = -1; + goto cleanup; + } + + ctxt = xmlXPathNewContext(xml); + if (!ctxt) { + xenRBACError( conn, VIR_ERR_XML_ERROR, NULL); + ret = -1; + goto cleanup; + } + + obj = xmlXPathEval(BAD_CAST "string(/domain/name)" , ctxt); + if (!obj) { + xenRBACError( conn, VIR_ERR_XML_ERROR, NULL); + ret = -1; + goto cleanup; + } + if ( (obj->type == XPATH_STRING) && (obj->stringval != NULL) && (obj->stringval[0] != 0) ) { + ret = xenRBACdomain( op_id, (char *)obj->stringval, conn); + } else { + xenRBACError( conn, VIR_ERR_XML_ERROR, NULL); + ret = -1; + goto cleanup; + } + + cleanup: + if (obj) + xmlXPathFreeObject(obj); + if (ctxt) + xmlXPathFreeContext(ctxt); + if (xml) + xmlFreeDoc(xml); + + return ret; +} + diff -r d5dbadfb6161 -r 62d2ebb8d23b src/xenrbac_libvirt.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/xenrbac_libvirt.h Tue Jan 27 03:13:46 2009 +0900 @@ -0,0 +1,68 @@ +/* + * xenrbac_libvirt.h: internal API for access to Xen RBAC + * + * Copyright (C) 2008 FUJITSU Limited. + * + * See COPYING.LIB for the License of this software + * + */ + + +#ifndef __VIR_XR_JUDGE_H__ +#define __VIR_XR_JUDGE_H__ + +int xenRBACdomain(int op_id, char *domainname, virConnectPtr conn); +int xenRBACxml(int op_id, const char *xmlDesc, virConnectPtr conn); + +#ifdef RBAC +/* ACCESS LIST */ +#define XR_CREATE_VM 1 +#define XR_START_VM 2 +#define XR_DESTROY_VM 3 +#define XR_SHUTDOWN_VM 4 +#define XR_PAUSE_VM 5 +#define XR_SUSPEND_VM 6 +#define XR_SAVE_VM 7 +#define XR_DEFINE_VM 8 +#define XR_MIGRATE_VM 9 +#define XR_REBOOT_VM 10 +#define XR_DUMP_VM 11 +#define XR_RENAME_VM 12 +#define XR_SYSREQ_VM 13 +#define XR_AUTOSTART_VM 14 +#define XR_UNDEFINE_VM 15 /* Step2 2008.8.13 */ +#define XR_LIST_VM 16 +#define XR_DETAIL_VM 17 +#define XR_LOAD_VM 18 +#define XR_UPTIME_VM 19 +#define XR_XEND_LOG 20 +#define XR_XEND_MSG 21 +#define XR_HOSTNAME 22 +#define XR_AVAILABLE_MEM 23 + +#define XR_SET_VCPU 30 +#define XR_GET_VCPU 31 +#define XR_SET_SCHEDULER 32 +#define XR_GET_SCHEDULER 33 +#define XR_SET_MEM 34 +#define XR_ATTACH_DEVICE 35 /* Step2 2008.8.13 */ +#define XR_LIST_VBD 36 +#define XR_LIST_VNIF 37 +#define XR_LIST_VTPM 38 +#define XR_CREATE_VNET 40 +#define XR_LIST_VNET 41 +#define XR_DETAIL_VNET 42 +#define XR_AUTOSTART_VNET 43 +#define XR_DEFINE_VNET 44 +#define XR_DETACH_DEVICE 45 /* Step2 2008.8.13 */ +#define XR_CHANGE_DEVICE 46 /* Step2 2008.8.13 */ +#define XR_DESTROY_VNET 47 /* Step2 2008.8.13 */ + +#define XR_HYPERVISER_URI 61 +#define XR_VERSION 62 +#define XR_SEND_TRIGGER 63 +#define XR_SEND_DEBUG_KEY 64 +#endif + +#endif /* __VIR_XR_JUDGE_H__ */ + diff -r d5dbadfb6161 -r 62d2ebb8d23b src/xs_internal.c --- a/src/xs_internal.c Wed Apr 02 13:13:06 2008 +0900 +++ b/src/xs_internal.c Tue Jan 27 03:13:46 2009 +0900 @@ -336,7 +336,11 @@ #ifdef PROXY priv->xshandle = xs_daemon_open_readonly(); #else +#ifdef RBAC + if ((getuid != 0) || (flags & VIR_CONNECT_RO)) +#else if (flags & VIR_CONNECT_RO) +#endif priv->xshandle = xs_daemon_open_readonly(); else priv->xshandle = xs_daemon_open(); @@ -348,7 +352,11 @@ * is rather normal, this should fallback to the proxy (or * remote) mechanism. */ +#ifdef RBAC + if (!(flags & VIR_CONNECT_RO)) { +#else if (getuid() == 0) { +#endif virXenStoreError(NULL, VIR_ERR_NO_XEN, _("failed to connect to Xen Store")); } diff -r d5dbadfb6161 -r 62d2ebb8d23b tests/Makefile.in --- a/tests/Makefile.in Wed Apr 02 13:13:06 2008 +0900 +++ b/tests/Makefile.in Tue Jan 27 03:13:46 2009 +0900 @@ -387,6 +387,7 @@ LIBXML_CFLAGS = @LIBXML_CFLAGS@ LIBXML_LIBS = @LIBXML_LIBS@ LN_S = @LN_S@ +LIBXENRBAC = -lxenrbac LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ LTLIBOBJS = @LTLIBOBJS@ @@ -693,37 +694,37 @@ done conftest$(EXEEXT): $(conftest_OBJECTS) $(conftest_DEPENDENCIES) @rm -f conftest$(EXEEXT) - $(LINK) $(conftest_OBJECTS) $(conftest_LDADD) $(LIBS) + $(LINK) $(conftest_OBJECTS) $(conftest_LDADD) $(LIBS) $(LIBXENRBAC) nodeinfotest$(EXEEXT): $(nodeinfotest_OBJECTS) $(nodeinfotest_DEPENDENCIES) @rm -f nodeinfotest$(EXEEXT) - $(LINK) $(nodeinfotest_OBJECTS) $(nodeinfotest_LDADD) $(LIBS) + $(LINK) $(nodeinfotest_OBJECTS) $(nodeinfotest_LDADD) $(LIBS) $(LIBXENRBAC) qemuxml2argvtest$(EXEEXT): $(qemuxml2argvtest_OBJECTS) $(qemuxml2argvtest_DEPENDENCIES) @rm -f qemuxml2argvtest$(EXEEXT) - $(LINK) $(qemuxml2argvtest_OBJECTS) $(qemuxml2argvtest_LDADD) $(LIBS) + $(LINK) $(qemuxml2argvtest_OBJECTS) $(qemuxml2argvtest_LDADD) $(LIBS) $(LIBXENRBAC) qemuxml2xmltest$(EXEEXT): $(qemuxml2xmltest_OBJECTS) $(qemuxml2xmltest_DEPENDENCIES) @rm -f qemuxml2xmltest$(EXEEXT) - $(LINK) $(qemuxml2xmltest_OBJECTS) $(qemuxml2xmltest_LDADD) $(LIBS) + $(LINK) $(qemuxml2xmltest_OBJECTS) $(qemuxml2xmltest_LDADD) $(LIBS) $(LIBXENRBAC) reconnect$(EXEEXT): $(reconnect_OBJECTS) $(reconnect_DEPENDENCIES) @rm -f reconnect$(EXEEXT) - $(LINK) $(reconnect_OBJECTS) $(reconnect_LDADD) $(LIBS) + $(LINK) $(reconnect_OBJECTS) $(reconnect_LDADD) $(LIBS) $(LIBXENRBAC) sexpr2xmltest$(EXEEXT): $(sexpr2xmltest_OBJECTS) $(sexpr2xmltest_DEPENDENCIES) @rm -f sexpr2xmltest$(EXEEXT) - $(LINK) $(sexpr2xmltest_OBJECTS) $(sexpr2xmltest_LDADD) $(LIBS) + $(LINK) $(sexpr2xmltest_OBJECTS) $(sexpr2xmltest_LDADD) $(LIBS) $(LIBXENRBAC) virshtest$(EXEEXT): $(virshtest_OBJECTS) $(virshtest_DEPENDENCIES) @rm -f virshtest$(EXEEXT) - $(LINK) $(virshtest_OBJECTS) $(virshtest_LDADD) $(LIBS) + $(LINK) $(virshtest_OBJECTS) $(virshtest_LDADD) $(LIBS) $(LIBXENRBAC) xencapstest$(EXEEXT): $(xencapstest_OBJECTS) $(xencapstest_DEPENDENCIES) @rm -f xencapstest$(EXEEXT) - $(LINK) $(xencapstest_OBJECTS) $(xencapstest_LDADD) $(LIBS) + $(LINK) $(xencapstest_OBJECTS) $(xencapstest_LDADD) $(LIBS) $(LIBXENRBAC) xmconfigtest$(EXEEXT): $(xmconfigtest_OBJECTS) $(xmconfigtest_DEPENDENCIES) @rm -f xmconfigtest$(EXEEXT) - $(LINK) $(xmconfigtest_OBJECTS) $(xmconfigtest_LDADD) $(LIBS) + $(LINK) $(xmconfigtest_OBJECTS) $(xmconfigtest_LDADD) $(LIBS) $(LIBXENRBAC) xml2sexprtest$(EXEEXT): $(xml2sexprtest_OBJECTS) $(xml2sexprtest_DEPENDENCIES) @rm -f xml2sexprtest$(EXEEXT) - $(LINK) $(xml2sexprtest_OBJECTS) $(xml2sexprtest_LDADD) $(LIBS) + $(LINK) $(xml2sexprtest_OBJECTS) $(xml2sexprtest_LDADD) $(LIBS) $(LIBXENRBAC) xmlrpctest$(EXEEXT): $(xmlrpctest_OBJECTS) $(xmlrpctest_DEPENDENCIES) @rm -f xmlrpctest$(EXEEXT) - $(LINK) $(xmlrpctest_OBJECTS) $(xmlrpctest_LDADD) $(LIBS) + $(LINK) $(xmlrpctest_OBJECTS) $(xmlrpctest_LDADD) $(LIBS) $(LIBXENRBAC) mostlyclean-compile: -rm -f *.$(OBJEXT)
-- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list