On Thu, Oct 14, 2010 at 04:24:45PM +0530, Harsh Prateek Bora wrote: > This patch introduces new attribute to filesystem element > to support customizable access mode for mount type. > Valid accessmode are: passthrough, mapped and squash. > > Usage: > <filesystem type='mount' accessmode='passthrough'> > <source dir='/export/to/guest'/> > <target dir='mount_tag'/> > </filesystem> > > Here is the detailed explanation on these access modes: > > Access mode: mapped > -------------------- > > Fileserver intercepts and maps all the file object create requests. > Files on the fileserver will be created with Fileserver's user credentials > and the > client-user's credentials are stored in extended attributes. > During getattr() server extracts the client-user's credentials from extended > attributes and sends to the client. > > This adds a great deal of security in the cloud environments where the > guest's(client) user space is kept completely isolated from host's user > space. > > > Access mode : passthrough > -------------------------- > > In this security model, Fileserver passes down all requests to the > underlying filesystem. File system objects on the fileserver will be created > with client-user's credentials. This is done by setting setuid()/setgid() > during creation or chmod/chown after file creation. At the end of create > protocol > request, files on the fileserver will be owned by cleint-user's uid/gid. > This model mimic's current NFSv3 level of security. > > Access mode: squash > -------------------- > > In 'squash' mode, the (filesystem) server attempts to preserve user/group > ownership from guest, however: > - If the server is running as root this mode is equivalent to passthrough. > - If the server is running as non-root, all files just have uid/gid matching > the server process. > > > Note: This patch is based on Daniel's patch to support 9pfs. > It shall be applied after applying Daniel's patch to support 9pfs. > > Signed-off-by: Harsh Prateek Bora <harsh@xxxxxxxxxxxxxxxxxx> > --- > docs/schemas/domain.rng | 7 +++++++ > src/conf/domain_conf.c | 30 ++++++++++++++++++++++++++++-- > src/conf/domain_conf.h | 11 +++++++++++ > src/qemu/qemu_conf.c | 10 ++++++++-- > 4 files changed, 54 insertions(+), 4 deletions(-) > > diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng > index ccb8cf3..c0e5149 100644 > --- a/docs/schemas/domain.rng > +++ b/docs/schemas/domain.rng > @@ -761,6 +761,13 @@ > </choice> > <optional> > <ref name="address"/> > + <attribute name="accessmode"> > + <choice> > + <value>passthrough</value> > + <value>mapped</value> > + <value>squash</value> > + </choice> > + </attribute> > </optional> > </element> > </define> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index e05d5d7..68c8441 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -161,6 +161,12 @@ VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST, > "file", > "template") > > +VIR_ENUM_IMPL(virDomainFSAccessMode, VIR_DOMAIN_FS_SECURITY_LAST, > + "passthrough", > + "mapped", > + "squash") > + > + > VIR_ENUM_IMPL(virDomainNet, VIR_DOMAIN_NET_TYPE_LAST, > "user", > "ethernet", > @@ -1847,6 +1853,7 @@ virDomainFSDefParseXML(xmlNodePtr node, > char *type = NULL; > char *source = NULL; > char *target = NULL; > + char *accessmode = NULL; > > if (VIR_ALLOC(def) < 0) { > virReportOOMError(); > @@ -1864,6 +1871,17 @@ virDomainFSDefParseXML(xmlNodePtr node, > def->type = VIR_DOMAIN_FS_TYPE_MOUNT; > } > > + accessmode = virXMLPropString(node, "accessmode"); > + if (accessmode) { > + if ((def->accessmode = virDomainFSAccessModeTypeFromString(accessmode)) < 0) { > + virDomainReportError(VIR_ERR_INTERNAL_ERROR, > + _("unknown accessmode '%s'"), accessmode); > + goto error; > + } > + } else { > + def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH; > + } > + > cur = node->children; > while (cur != NULL) { > if (cur->type == XML_ELEMENT_NODE) { > @@ -5602,6 +5620,7 @@ virDomainFSDefFormat(virBufferPtr buf, > int flags) > { > const char *type = virDomainFSTypeToString(def->type); > + const char *accessmode = virDomainFSAccessModeTypeToString(def->accessmode); > > if (!type) { > virDomainReportError(VIR_ERR_INTERNAL_ERROR, > @@ -5609,9 +5628,16 @@ virDomainFSDefFormat(virBufferPtr buf, > return -1; > } > > + if (!accessmode) { > + virDomainReportError(VIR_ERR_INTERNAL_ERROR, > + _("unexpected accessmode %d"), def->accessmode); > + return -1; > + } > + > + > virBufferVSprintf(buf, > - " <filesystem type='%s'>\n", > - type); > + " <filesystem type='%s' accessmode='%s'>\n", > + type, accessmode); > > if (def->src) { > switch (def->type) { > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > index 7195c04..0668ce5 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -236,10 +236,20 @@ enum virDomainFSType { > VIR_DOMAIN_FS_TYPE_LAST > }; > > +/* Filesystem mount access mode */ > +enum virDomainFSAccessMode { > + VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH, > + VIR_DOMAIN_FS_ACCESSMODE_MAPPED, > + VIR_DOMAIN_FS_ACCESSMODE_SQUASH, > + > + VIR_DOMAIN_FS_ACCESSMODE_LAST > +}; > + > typedef struct _virDomainFSDef virDomainFSDef; > typedef virDomainFSDef *virDomainFSDefPtr; > struct _virDomainFSDef { > int type; > + int accessmode; > char *src; > char *dst; > unsigned int readonly : 1; > @@ -1167,6 +1177,7 @@ VIR_ENUM_DECL(virDomainDiskErrorPolicy) > VIR_ENUM_DECL(virDomainController) > VIR_ENUM_DECL(virDomainControllerModel) > VIR_ENUM_DECL(virDomainFS) > +VIR_ENUM_DECL(virDomainFSAccessMode) > VIR_ENUM_DECL(virDomainNet) > VIR_ENUM_DECL(virDomainChrDevice) > VIR_ENUM_DECL(virDomainChrChannelTarget) > diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c > index 18a302a..0961d8a 100644 > --- a/src/qemu/qemu_conf.c > +++ b/src/qemu/qemu_conf.c > @@ -2783,11 +2783,17 @@ char *qemuBuildFSStr(virDomainFSDefPtr fs, > > if (fs->type != VIR_DOMAIN_FS_TYPE_MOUNT) { > qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > - _("can only passthrough directories")); > + _("only supports mount filesystem type")); > goto error; > } > > - virBufferAddLit(&opt, "local,security_model=passthrough"); > + virBufferAddLit(&opt, "local"); > + if (fs->accessmode == VIR_DOMAIN_FS_ACCESSMODE_SQUASH) { > + virBufferAddLit(&opt, ",security_model=none"); > + } else { > + virBufferAddLit(&opt, ",security_model=%s", > + virDomainFSAccessModeTypeToString(fs->accessmode)); > + } > virBufferVSprintf(&opt, ",id=%s%s", QEMU_FSDEV_HOST_PREFIX, fs->info.alias); > virBufferVSprintf(&opt, ",path=%s", fs->src); ACK, this gets my vote now. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list