Add a virGetUserShell wrapper around virGetUserEnt, that
returns the shell field.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/libvirt_private.syms | 1 +
src/util/virutil.c | 51 ++++++++++++++++++++++++++++++++++++++++--------
src/util/virutil.h | 1 +
3 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 22b81ae..f88dd02 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2460,6 +2460,7 @@ virGetUserDirectoryByUID;
virGetUserID;
virGetUserName;
virGetUserRuntimeDirectory;
+virGetUserShell;
virHexToBin;
virIndexToDiskName;
virIsCapableFCHost;
diff --git a/src/util/virutil.c b/src/util/virutil.c
index 8205150..d151c1c 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -750,7 +750,7 @@ virGetUserDirectory(void)
/* Look up fields from the user database for the given user. On
* error, set errno, report the error, and return -1. */
static int
-virGetUserEnt(uid_t uid, char **name, gid_t *group, char **dir)
+virGetUserEnt(uid_t uid, char **name, gid_t *group, char **dir, char **shell)
{
char *strbuf;
struct passwd pwbuf;
@@ -764,6 +764,8 @@ virGetUserEnt(uid_t uid, char **name, gid_t *group, char **dir)
*name = NULL;
if (dir)
*dir = NULL;
+ if (shell)
+ *shell = NULL;
/* sysconf is a hint; if it fails, fall back to a reasonable size */
if (val < 0)
@@ -799,14 +801,21 @@ virGetUserEnt(uid_t uid, char **name, gid_t *group, char **dir)
goto cleanup;
if (group)
*group = pw->pw_gid;
- if (dir && VIR_STRDUP(*dir, pw->pw_dir) < 0) {
- if (name)
- VIR_FREE(*name);
+ if (dir && VIR_STRDUP(*dir, pw->pw_dir) < 0)
+ goto cleanup;
+ if (shell && VIR_STRDUP(*shell, pw->pw_shell) < 0)
goto cleanup;
- }
ret = 0;
cleanup:
+ if (ret < 0) {
+ if (name)
+ VIR_FREE(*name);
+ if (dir)
+ VIR_FREE(*dir);
+ if (shell)
+ VIR_FREE(*shell);
+ }
VIR_FREE(strbuf);
return ret;
}
@@ -866,7 +875,15 @@ char *
virGetUserDirectoryByUID(uid_t uid)
{
char *ret;
- virGetUserEnt(uid, NULL, NULL, &ret);
+ virGetUserEnt(uid, NULL, NULL, &ret, NULL);
+ return ret;
+}
+
+
+char *virGetUserShell(uid_t uid)
+{
+ char *ret;
+ virGetUserEnt(uid, NULL, NULL, NULL, &ret);
return ret;
}
@@ -916,7 +933,7 @@ char *virGetUserRuntimeDirectory(void)
char *virGetUserName(uid_t uid)
{
char *ret;
- virGetUserEnt(uid, &ret, NULL, NULL);
+ virGetUserEnt(uid, &ret, NULL, NULL, NULL);
return ret;
}
@@ -1102,7 +1119,7 @@ virGetGroupList(uid_t uid, gid_t gid, gid_t **list)
if (uid == (uid_t)-1)
return 0;
- if (virGetUserEnt(uid, &user, &primary, NULL) < 0)
+ if (virGetUserEnt(uid, &user, &primary, NULL, NULL) < 0)
return -1;
ret = mgetgroups(user, primary, list);
@@ -1277,6 +1294,15 @@ virGetUserDirectoryByUID(uid_t uid ATTRIBUTE_UNUSED)
}
char *
+virGetUserShell(uid_t uid ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("virGetUserShell is not available"));
+
+ return NULL;
+}
+
+char *
virGetUserConfigDirectory(void)
{
char *ret;
@@ -1323,6 +1349,15 @@ virGetUserDirectoryByUID(uid_t uid ATTRIBUTE_UNUSED)
}
char *
+virGetUserShell(uid_t uid ATTRIBUTE_UNUSED)
+{
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("virGetUserShell is not available"));
+
+ return NULL;
+}
+
+char *
virGetUserConfigDirectory(void)
{
virReportError(VIR_ERR_INTERNAL_ERROR,
diff --git a/src/util/virutil.h b/src/util/virutil.h
index 1e51a25..703ec53 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -139,6 +139,7 @@ char *virGetUserDirectoryByUID(uid_t uid);
char *virGetUserConfigDirectory(void);
char *virGetUserCacheDirectory(void);
char *virGetUserRuntimeDirectory(void);
+char *virGetUserShell(uid_t uid);
char *virGetUserName(uid_t uid);
char *virGetGroupName(gid_t gid);
int virGetGroupList(uid_t uid, gid_t group, gid_t **groups)
--
2.5.5