Signed-off-by: Ryota Ozaki <ozaki.ryota(a)gmail.com>
From c441d5f29f1ed964e3c17dcac8614c0834eaba49 Mon Sep 17 00:00:00 2001
From: Ryota Ozaki <ozaki.ryota(a)gmail.com>
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