[libvirt] [PATCH 1/2] util: extend virGetUserID and virGetGroupID to support names and IDs

Marcelo Cerri mhcerri at linux.vnet.ibm.com
Mon Oct 8 13:36:22 UTC 2012


On Mon, Oct 08, 2012 at 02:08:59PM +0200, Peter Krempa wrote:
> On 10/06/12 04:52, Marcelo Cerri wrote:
> >This patch updates virGetUserID and virGetGroupID to be able to parse a
> >user or group name in a similar way to coreutils' chown. This means that
> >a numeric value with a leading plus sign is always parsed as an ID,
> >otherwise the functions try to parse the input first as a user or group
> >name and if this fails they try to parse it as an ID.
> >---
> >  src/util/util.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++---------
> >  1 file changed, 74 insertions(+), 13 deletions(-)
> >
> >diff --git a/src/util/util.c b/src/util/util.c
> >index 43fdaf1..694ed3d 100644
> >--- a/src/util/util.c
> >+++ b/src/util/util.c
> >@@ -2495,9 +2495,11 @@ char *virGetGroupName(gid_t gid)
> >      return virGetGroupEnt(gid);
> >  }
> >
> >-
> >-int virGetUserID(const char *name,
> >-                 uid_t *uid)
> >+/* Search in the password database for a user id that matches the user name
> >+ * `name`. Returns 0 on success, -1 on a critical failure or 1 if name cannot
> >+ * be parsed.
> >+ */
> >+static int virGetUserIDByName(const char *name, uid_t *uid)
> >  {
> >      char *strbuf;
> >      struct passwd pwbuf;
> >@@ -2530,11 +2532,10 @@ int virGetUserID(const char *name,
> >          }
> >      }
> >      if (rc != 0 || pw == NULL) {
> >-        virReportSystemError(rc,
> >-                             _("Failed to find user record for name '%s'"),
> >-                             name);
> >+        VIR_DEBUG("Failed to find user record for user '%s' (error = %d)",
> >+                  name, rc);
> 
> Although this will work most of the times when an error occurs it
> will be masked as if the user wasn't found. Unfortunately getpwuid_r
> and friends have very bad error reporting. The only effective way to
> distinguish errors from non-existent user entries (according to the
> manpage) is to check set errno before the call and check it
> afterwards.

Do you think that I should keep virReportSystemError instead of
VIR_DEBUG here?

> 
> >          VIR_FREE(strbuf);
> >-        return -1;
> >+        return 1;
> >      }
> >
> >      *uid = pw->pw_uid;
> >@@ -2544,9 +2545,41 @@ int virGetUserID(const char *name,
> >      return 0;
> >  }
> >
> >+/* Try to match a user id based on `user`. The default behavior is to parse
> >+ * `user` first as a user name and then as a user id. However if `user`
> >+ * contains a leading '+', the rest of the string is always parsed as a uid.
> >+ *
> >+ * Returns 0 on success and -1 otherwise.
> >+ */
> >+int virGetUserID(const char *user, uid_t *uid)
> >+{
> >+    unsigned int uint_uid;
> >
> >-int virGetGroupID(const char *name,
> >-                  gid_t *gid)
> >+    if (*user == '+') {
> >+        user++;
> >+    } else {
> >+        int rc = virGetUserIDByName(user, uid);
> >+        if (rc <= 0)
> >+            return rc;
> >+    }
> >+
> >+    if (virStrToLong_ui(user, NULL, 10, &uint_uid) < 0 ||
> >+        ((uid_t) uint_uid) != uint_uid) {
> >+        virReportError(VIR_ERR_INVALID_ARG, _("Failed to parse user '%s'"),
> >+                       user);
> >+        return -1;
> >+    }
> >+
> >+    *uid = uint_uid;
> >+
> >+    return 0;
> >+}
> >+
> 
> Otherwise looks ok, so ACK. I'll push this after I get a review on
> the followup patch that fixes the issue with errors being masked
> while getting the user entry.
> 
> Peter
> 




More information about the libvir-list mailing list