Signed-off-by: Ryota Ozaki <ozaki.ryota@xxxxxxxxx> >From c441d5f29f1ed964e3c17dcac8614c0834eaba49 Mon Sep 17 00:00:00 2001 From: Ryota Ozaki <ozaki.ryota@xxxxxxxxx> Date: Thu, 16 Apr 2009 23:17:29 +0900 Subject: [PATCH] storage: allow alphabetical names in owner/group of permissions --- docs/schemas/storagepool.rng | 10 ++++- docs/schemas/storagevol.rng | 10 ++++- src/Makefile.am | 1 + src/storage_backend.c | 8 +++- src/storage_backend_fs.c | 32 ++++++++++++++- src/storage_backend_logical.c | 33 ++++++++++++++- src/storage_conf.c | 91 +++++++++++++++++++++++++++++------------ src/storage_conf.h | 4 +- 8 files changed, 152 insertions(+), 37 deletions(-) diff --git a/docs/schemas/storagepool.rng b/docs/schemas/storagepool.rng index e152e19..ed1e597 100644 --- a/docs/schemas/storagepool.rng +++ b/docs/schemas/storagepool.rng @@ -127,10 +127,16 @@ <ref name='uint'/> </element> <element name='owner'> - <ref name='uint'/> + <choice> + <ref name='uint'/> + <ref name='name'/> + </choice> </element> <element name='group'> - <ref name='uint'/> + <choice> + <ref name='uint'/> + <ref name='name'/> + </choice> </element> <optional> <element name='label'> diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng index c7bd3a7..13e08b5 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -46,10 +46,16 @@ <ref name='uint'/> </element> <element name='owner'> - <ref name='uint'/> + <choice> + <ref name='uint'/> + <ref name='name'/> + </choice> </element> <element name='group'> - <ref name='uint'/> + <choice> + <ref name='uint'/> + <ref name='name'/> + </choice> </element> <optional> <element name='label'> diff --git a/src/Makefile.am b/src/Makefile.am index f176b46..84567aa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -333,6 +333,7 @@ endif # Needed to keep automake quiet about conditionals libvirt_driver_storage_la_SOURCES = +libvirt_driver_storage_la_LIBADD = libvirt_util.la if WITH_STORAGE_DIR if WITH_DRIVER_MODULES mod_LTLIBRARIES += libvirt_driver_storage.la diff --git a/src/storage_backend.c b/src/storage_backend.c index b154140..810c4b5 100644 --- a/src/storage_backend.c +++ b/src/storage_backend.c @@ -214,8 +214,12 @@ virStorageBackendUpdateVolTargetInfoFD(virConnectPtr conn, } target->perms.mode = sb.st_mode & S_IRWXUGO; - target->perms.uid = sb.st_uid; - target->perms.gid = sb.st_gid; + VIR_FREE(target->perms.owner); + if (virAsprintf(&target->perms.owner, "%d", sb.st_uid) == -1) + return -1; + VIR_FREE(target->perms.group); + if (virAsprintf(&target->perms.group, "%d", sb.st_gid) == -1) + return -1; VIR_FREE(target->perms.label); diff --git a/src/storage_backend_fs.c b/src/storage_backend_fs.c index 5000f43..d48c278 100644 --- a/src/storage_backend_fs.c +++ b/src/storage_backend_fs.c @@ -1189,7 +1189,37 @@ virStorageBackendFileSystemVolCreate(virConnectPtr conn, /* We can only chown/grp if root */ if (getuid() == 0) { - if (fchown(fd, vol->target.perms.uid, vol->target.perms.gid) < 0) { + int uid = 0, gid = 0; + char *owner = vol->target.perms.owner; + char *group = vol->target.perms.group; + + if (owner) { + char *end = NULL; + int id = strtol(owner, &end, 10); + if (*end || id < 0) { + id = virGetUIDByUsername(conn, owner); + if (id < 0) { + unlink(vol->target.path); + close(fd); + return -1; + } + } + uid = id; + } + if (group) { + char *end = NULL; + int id = strtol(group, &end, 10); + if (*end || id < 0) { + id = virGetUIDByUsername(conn, group); + if (id < 0) { + unlink(vol->target.path); + close(fd); + return -1; + } + } + gid = id; + } + if (fchown(fd, uid, gid) < 0) { virReportSystemError(conn, errno, _("cannot set file owner '%s'"), vol->target.path); diff --git a/src/storage_backend_logical.c b/src/storage_backend_logical.c index cbd2765..7a869f6 100644 --- a/src/storage_backend_logical.c +++ b/src/storage_backend_logical.c @@ -615,7 +615,38 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn, /* We can only chown/grp if root */ if (getuid() == 0) { - if (fchown(fd, vol->target.perms.uid, vol->target.perms.gid) < 0) { + int uid = 0, gid = 0; + char *owner = vol->target.perms.owner; + char *group = vol->target.perms.group; + + if (owner) { + char *end = NULL; + int id = strtol(owner, &end, 10); + if (*end || id < 0) { + id = virGetUIDByUsername(conn, owner); + if (id < 0) { + unlink(vol->target.path); + close(fd); + return -1; + } + } + uid = id; + } + if (group) { + char *end = NULL; + int id = strtol(group, &end, 10); + if (*end || id < 0) { + id = virGetUIDByUsername(conn, group); + if (id < 0) { + unlink(vol->target.path); + close(fd); + return -1; + } + } + gid = id; + } + + if (fchown(fd, uid, gid) < 0) { virReportSystemError(conn, errno, _("cannot set file owner '%s'"), vol->target.path); diff --git a/src/storage_conf.c b/src/storage_conf.c index 9e25ccb..fd34319 100644 --- a/src/storage_conf.c +++ b/src/storage_conf.c @@ -256,8 +256,12 @@ virStorageVolDefFree(virStorageVolDefPtr def) { VIR_FREE(def->source.extents); VIR_FREE(def->target.path); + VIR_FREE(def->target.perms.owner); + VIR_FREE(def->target.perms.group); VIR_FREE(def->target.perms.label); VIR_FREE(def->backingStore.path); + VIR_FREE(def->backingStore.perms.owner); + VIR_FREE(def->backingStore.perms.group); VIR_FREE(def->backingStore.perms.label); VIR_FREE(def); } @@ -295,6 +299,8 @@ virStoragePoolDefFree(virStoragePoolDefPtr def) { virStoragePoolSourceFree(&def->source); VIR_FREE(def->target.path); + VIR_FREE(def->target.perms.owner); + VIR_FREE(def->target.perms.group); VIR_FREE(def->target.perms.label); VIR_FREE(def); } @@ -391,15 +397,14 @@ virStorageDefParsePerms(virConnectPtr conn, xmlNodePtr relnode; xmlNodePtr node; + perms->mode = defaultmode; + perms->owner = NULL; + perms->group = NULL; + perms->label = NULL; + node = virXPathNode(conn, permxpath, ctxt); - if (node == NULL) { - /* Set default values if there is not <permissions> element */ - perms->mode = defaultmode; - perms->uid = getuid(); - perms->gid = getgid(); - perms->label = NULL; + if (node == NULL) return 0; - } relnode = ctxt->node; ctxt->node = node; @@ -420,25 +425,53 @@ virStorageDefParsePerms(virConnectPtr conn, } if (virXPathNode(conn, "./owner", ctxt) == NULL) { - perms->uid = getuid(); - } else { - if (virXPathLong(conn, "number(./owner)", ctxt, &v) < 0) { - virStorageReportError(conn, VIR_ERR_XML_ERROR, - "%s", _("malformed owner element")); + if (virAsprintf(&perms->owner, "%d", getuid()) == -1) { + ret = -ENOMEM; goto error; } - perms->uid = (int)v; + } else { + if (virXPathLong(conn, "number(./owner)", ctxt, &v) == 0) { + if (virAsprintf(&perms->owner, "%ld", v) == -1) { + ret = -ENOMEM; + goto error; + } + } else { + char *name; + + name = virXPathString(conn, "string(./owner)", ctxt); + if (!name) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, + "%s", _("malformed owner element")); + goto error; + } + + perms->owner = name; + } } if (virXPathNode(conn, "./group", ctxt) == NULL) { - perms->gid = getgid(); - } else { - if (virXPathLong(conn, "number(./group)", ctxt, &v) < 0) { - virStorageReportError(conn, VIR_ERR_XML_ERROR, - "%s", _("malformed group element")); + if (virAsprintf(&perms->owner, "%d", getgid()) == -1) { + ret = -ENOMEM; goto error; } - perms->gid = (int)v; + } else { + if (virXPathLong(conn, "number(./group)", ctxt, &v) == 0) { + if (virAsprintf(&perms->group, "%ld", v) == -1) { + ret = -ENOMEM; + goto error; + } + } else { + char *name; + + name = virXPathString(conn, "string(./group)", ctxt); + if (!name) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, + "%s", _("malformed group element")); + goto error; + } + + perms->group = name; + } } /* NB, we're ignoring missing labels here - they'll simply inherit */ @@ -815,10 +848,12 @@ virStoragePoolDefFormat(virConnectPtr conn, virBufferAddLit(&buf," <permissions>¥n"); virBufferVSprintf(&buf," <mode>0%o</mode>¥n", def->target.perms.mode); - virBufferVSprintf(&buf," <owner>%d</owner>¥n", - def->target.perms.uid); - virBufferVSprintf(&buf," <group>%d</group>¥n", - def->target.perms.gid); + if (def->target.perms.owner) + virBufferVSprintf(&buf," <owner>%s</owner>¥n", + def->target.perms.owner); + if (def->target.perms.group) + virBufferVSprintf(&buf," <group>%s</group>¥n", + def->target.perms.group); if (def->target.perms.label) virBufferVSprintf(&buf," <label>%s</label>¥n", @@ -1111,10 +1146,12 @@ virStorageVolTargetDefFormat(virConnectPtr conn, virBufferAddLit(buf," <permissions>¥n"); virBufferVSprintf(buf," <mode>0%o</mode>¥n", def->perms.mode); - virBufferVSprintf(buf," <owner>%d</owner>¥n", - def->perms.uid); - virBufferVSprintf(buf," <group>%d</group>¥n", - def->perms.gid); + if (def->perms.owner) + virBufferVSprintf(buf," <owner>%s</owner>¥n", + def->perms.owner); + if (def->perms.group) + virBufferVSprintf(buf," <group>%s</group>¥n", + def->perms.group); if (def->perms.label) diff --git a/src/storage_conf.h b/src/storage_conf.h index 4e35ccb..212e58c 100644 --- a/src/storage_conf.h +++ b/src/storage_conf.h @@ -36,8 +36,8 @@ typedef struct _virStoragePerms virStoragePerms; typedef virStoragePerms *virStoragePermsPtr; struct _virStoragePerms { int mode; - int uid; - int gid; + char *owner; + char *group; char *label; }; -- 1.6.0.6 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list