[libvirt] [PATCH][take2][2/2] storage: allow alphabetical names in owner/group of permissions

Ryota Ozaki ozaki.ryota at gmail.com
Thu Apr 16 14:24:19 UTC 2009


Signed-off-by: Ryota Ozaki <ozaki.ryota at gmail.com>

>From c441d5f29f1ed964e3c17dcac8614c0834eaba49 Mon Sep 17 00:00:00 2001
From: Ryota Ozaki <ozaki.ryota at 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




More information about the libvir-list mailing list